Docker
배경
서버 운영
애플리케이션이 동작하는 상태를 유지하는 작업
-
프로비저닝
애플리케이션이 동작하는 상태를 만드는 작업
-
배포
프로비저닝된 서버에 애플리케이션을 실행
-
Application을 Server에서 실행시킴
-
여러 단계를 거쳐야 하는데, 서버의 상태가 계속 바뀜
-
배포 과정
하나의 서버에 여러 개의 Applictaion
[D] 라는 새로운 Application 추가
-
-
서버 운영
배포된 애플리케이션이 동작 가능한 상태 유지
- 서버 운영이 어려운 이유
- 고유한 네트워크 환경, 하드웨어 파편화
- 하나의 서버에 다수의 애플리케이션 배포
- 명령어: 절차적, 휘발적, 재현불가능
- 서버 운영이 어려운 이유
Infrastructure
IaaS(Infrastructure as a Service)
-
클라우드, 하드웨어 가상화
-
같은 환경을 가짐(Instance 단위)
-
원하는 만큼만 사용 가능
-
이미지화 & 스케일 인/아웃
하나의 앱을 여러개의 Instance로
App을 복제해서 3개로 늘림
-
오토 스케일링
원하는 만큼만 인스턴스 사용
:star:이미지 수의 증가
이미지의 수에 비례에해서 관리가 어려워 짐
이미지: 어떤 특정 시점의 상태를 저장한 것일 뿐
어떻게 만들었는지 아무도 모름 (복원 불가)
결론
리눅스로 명령어를 운영해야 하는 것은 여전함
Configuration Management
제현 가능한 서버 상태 관리를 위한 솔루션
ex) chef, puppet, ansible
-
멱등: 같은 과정을 거치면 서버는 똑같은 상태가 됨
Cookbook을 통한 상태 변화(chef)
같은 명령어
Infrastructure의 코드화: Git
- 기존 CMD와 다르게 Chef Cookbook을 통해 상태 관리
-
서버 운영 추상화
명령어를 통한 서버 관리X
상태 관리 코드 작성 -> 서버 적용
선언적 서버 상태 정의
서버 상태 재현 가능
서버 운영 협업
PaaS(Platform as a Service)
ex) Heroku: Dyno 단위에 App을 올리면 배포 가능
- :star:App과 배포 단위의 1:1 매치
-
Scale In/Out 지원
-
App 코드 수정 시 Push & Build가 새로 일어남
롤백이 쉬움
-
배포 단순화
-
결론
-
장점
소스 코드만으로 배포
일반화된 프로비저닝 방법 제공 (단, 과정에 개입X)
서버 운영 없이 App 가능
-
단점
생각보다 어려움
App을 Pass 방식에 맞게 작성
서버에 대한 원격 접속 시스템 제공X
서버에 파일 시스템을 사용X
Site 패키지 설치X
로그 수집 제한적 방식 허용(STDOUT)
명령어를 치면 표준 출력으로 Dyno에 명령어를 보여주는 식으로만 보여줌
-
LXC(LinuX Container)
파일 시스템을 분리함
-
정의
컨테이너 기반 가상화 도구
-
컨테이너: 격리된 환경에서 작동하는 프로세스
리눅스 커널 기술
하드웨어 가상화 기술보다 가벼움
이미지 단위로 프로세스 실행 환경 구성
-
busybox: 다른 환경에서 돌아감
실행 환경이 바뀜
-
가상 머신과의 차이
- Docker: Kernel을 공유
-
프로세스 실행 환경 분리
-
계층화된 저장장치(AUFS)
-
이미지(App이 돌아가는 환경) 공유
배포 환경 설정
-
빌드된 이미지
호스트의 환경과 무관하게 실행 가능
Ruby, Rails, Node 없어도 실행 가능
-
-
배포 단위 = Docker Images
App 실행 환경
Immutable Infrastructure
-
프로비저닝: 이미지 생성 시점에 완료
-
배포: 프로비저닝과 별도로 원하는 지점에
-
서버: 컨테이너를 실행시키기 위한 환경
컨테이너 실행을 위한 최소한 환경
서버 상태를 적극적으로 관리X
- 서버 없이 컨테이너 실행 서비스 등장 -> 서버 운영X
실습
http://52.78.185.183:4200/
ID: ubuntu
PW: apple-kiwi-apple
실제 외부 서버에 접속하는 것은 아님
redis: 저장소
php 사용
-
docker run -it -v $(pwd)/content:/tmp php:7 /bin/bash
php가 깔려있지 않아도 연결하여서 실행
-v 옵션을 통해 host와 image의 폴더 연결
Image
-
Docker
레이어드 파일 시스템 기반 ex) AUFS, BTRFS, Overlayfs, …
-
Image
프로세스가 실행되는 파일들의 집합(환경)
프로세스: 환경(파일)을 변경할 수 있음 (휘발됨)
–> 환경을 저장해 새로운 이미지 생성
- git이 설치된 image 구성
바뀐게 없으면 계속 사용 가능
Dockerfile
docker 이미지 생성을 위한 dsl
ROM nacyot/ruby-ruby:latest
RUN apt-get update
RUN apt-get install -qq -y libsqlite3-dev nodejs
RUN gem install foreman compass
WORKDIR /app
RUN git clone https://github.com/nacyot/docker-sample-project.git /app
RUN git checkout v0.1
RUN bundle install --without development test
ENV SECRET_KEY_BASE hellodocker
ENV RAILS_ENV production
EXPOSE 3000
CMD foreman start -f Procfile
-
#: 주석
-
FROM: 베이스 이미지 지정
-
ADD <추가할 파일=""> <파일 경로="">파일>추가할>
–> COPY를 더 많이 사용
-
RUN <명령어>명령어>
run apt-get install -y git
–> -y: 모두 y를 선택
-
WORKDIR <디렉터리>: 작업 디렉터리 변경디렉터리>
Docker build
docker build -t 이름공간/이미지이름:태그 .
docker build -t nacyot/ubuntu:git .
-
.dockerignore
.gitignore과 비슷한 역할
지정된 패턴의 파일 무시
FROM ruby:2.6
COPY Gemfile* /usr/src/app/
#Gemfile을 먼저 복사함
WORKDIR /usr/src/app
RUN bundle install
COPY . /usr/src/app
EXPOSE 4567
CMD bundle exec ruby app.rb -o 0.0.0.0
Gemfile이 바뀌지 않는 한 build가 깨지지 않음 (캐쉬최적화)
멀티 스테이지 빌드
-
기존 Dockerfile
FROM이 하나만 존재
-
멀티 스테이지 빌드
FROM maven:3-jdk-8-slim as build #작업한 내용은 build에 저장 COPY . /app WORKDIR /app RUN mvn package #만들어진 jar 파일 저장 FROM adoptopenjdk/openjdk8:alpine COPY --from=build /app/target/demo-0.0.1-SNAPSHOT.jar /app.jar #build에서 파일을 가져옴 #가져온 jar 파일 실행 CMD ["java","-Djava.security.egd=file:/dev/./urandom", "-jar","/app.jar "]
FROM이 두 개 이상 존재
빌드를 효과적으로 구현
시간, 용량 단축
환경 변수
-
기본 사이즈 설정
#!/bin/sh POST_MAX_SIZE=${POST_MAX_SIZE:-"32M"} #default = 32M sed -e "s/post_max_size = 8M/post_max_size = ${POST_MAX_SIZE}/" \ -i /usr/local/etc/php/php.ini php /tmp/hello.php
Docker Hub
https://hub.docker.com/
서버에서 생성한 이미지를 다른 서버에서 사용하기 위해 중앙 저장소에 이미지 저장
검색을 통해 미리 생성된 이미지 사용 가능