2020. 1. 11. 22:37 Docker & Kubernetes

Dockerfile

 

Dockerfile
 
 
  1. 어플리케이션을 컨테이너 화할 때 아래의 과정을 거친다.
  • 마스터 이미지(ubuntu, centos 등) 컨테이너 생성
  • 어플리케이션 환경 구성 및 소스코드 탑재
  • 컨테이너 이미지로 commit
 
위의 과정을 Dockerfile을 만들고 build 명령어를 통해 한번에 할 수 있음.
Dockfike :
  • 최종 이미지 생성을 위한 컨테이너에 설치 할 패키지, 소스 코드, 실행 할 명령어와 셸 스크립트 등을 하나의 파일에 기록 해둔 것
  • 과정 단순화 및 깃과 같은 개발 도구를 통해 어플리케이션 빌드 및 배포를 자동화 가능
  • 이미지를 생성하는 방법을 기록해 놓은 Dockerfile 을 배포 할 수 있음
  • 이미지 설치 자동화 및 배포!!
 
  1. Dockerfile 작성
# mkdir dockerfile
# cd dockerfile
# vi Dockerfile
docker 엔진은 Dockerfile을 읽을 때 현재 디렉토리에서 찾는다
Dockerfile이 있는 디렉토리는 비어 있어야 한다. Dockerfile 만 존재 -> 이미지 빌드 시 컨텍스트(Context) 때문
 
 
Dockerfile 기초 명령어
  • 한 줄에 하나의 명령
  • 명령어 명시한 뒤에 옵션
  • 명령어는 소문자도 상관없으나 일반적으로 대문자로 표기
FROM
기본 이미지 지정, local 에 없을 경우 자동으로 pull(다운)
MAINTAINER
개발자 정보, 이메일 등, docker 1.13.0 버전 이후 사용 안함
LABEL
이미지에 메타데이타 추가, 메타데이타는 "키:값" 형태로 지정
RUN
이미지 생성을 위해 컨테이너 내부에서 실행되는 명령
Dockerfile 빌드 중에는 입력 불가능 -> 옵션도 같이 설정 (apache2 -y)
RUN ["실행가능파일","명령 줄 인자 1", "명령 줄 인자 2, …] 형태로 사용가능, 이는 JSON 배열의 입력 형식을 따르기 때문에 JSON 형식과 일치 해야함.
ADD
파일을 이미지에 추가
추가 파일은 Dockerfile이 위치한 디렉토리인 컨텍스트(Context)에서 가져옴(같은 위치)
["추가할 파일 이름", ….. "컨테이너에 추가될 위치"]
여러 개 파일 추가 가능
WORKDIR
명령어를 실행하는 디렉토리를 나타냄
배시 셸의 cd 명령어와 같음
EXPOSE
Dockerfile의 빌드로 생성된 이미지에서 노출 할 포트 설정
호스트 포트와 바인딩 된 것이 아닌 사용 할 것임을 나타내는 것
컨테이너를 생성하는 run 명령어에서 모든 노출된 컨테이너의 포트를 호스트에 퍼블리시하는 -P 플래그와 함께 사용된다
CMD
컨테이너가 시작될 때 마다 실행 할 명령어 설정(apache web server 자동 실행)
Dockerfile 에서는 한번만 실행 됨
 
 
Dockerfile 빌드
# docker build -t mybuild:0.0 ./
-t : 생성될 이미지 이름 지정, 지정 안하면 16진수형태로
맨뒤 ./ : Dockerfile 이 저장된 경로, 외부 URL 로 부터 가지고 올 수 도 있음.
 
컨텍스트에 대한 정보는 이미지 빌드시 맨 위에 출력되는 내용
 
Dockerfile 로 생성한 이미지로 컨테이너 생성
# docker run -d -P --name myserver mybuild:0.0
-P : 이미지에 설정된 EXPOSE 의 모든 포트를 호스트에 연결하도록 설정, 연결 시 호스트에서 사용가능 한 포트를 차례로 연결하므로 확인이 필요 ( # docker port myserver )
 
정상적으로 생성되고 실행 되는지 확인-> web 접속
 
컨텍스트는 단순 파일 뿐 아니라 하위 디렉토리도 전부 포함하게 되므로 빌드에 불필요한 파일이 포함되지 않도록 컨텍스트 파일만 존재 하는 것이 좋음 => 이것을 방지 하기 위해서 .dockerignore 라는 파일을 작성하여 명시된 파일을 컨텍스트에서 제외(.gitignore 유사)
.dockerignore 파일은 Dockerfile 파일과 같은 위치에
*.html :  html 확장 자를  가지는 모든 파일 제외
*/*.html : 하위 모든 디렉토리 html 확장 자를 가지는 모든 파일 제외
test.html? : ? 자리에 들어 오는 모든 파일 제외
!test.html : ! 파일은 포함
 
  1. Doxckerfile 을 이용한 컨테이너 생성과 커밋
Dockerfile 에서 명령어 한 줄(ADD, RUN 등)이 실행될 때마다 이전 Step에서 생성된 이미지에 의해 새로운 컨테이너가 생성되며, Dockerfile 에 적힌 명령어를 수행하고 다시 새로운 이미지 레이어로 저장된다.
 
 
따라서 이미지의 빌드가 완료되면 Dockerfile의 명령어 줄 수 만큼의 레이어가 존재하게 되며, 중간에 컨테이너도 같은 수만 큼 생성되고 삭제된다.
Removing intermediate containner 10kjhds4834rjf => 임시로 생성된 컨테이너 삭제
삭제되기 전에 출력되는 ID는 커밋된 이미지 레이어를 나타냄
 
캐시를 이용한 이미지 빌드
Dockerfile2 이름으로 아래 내용을 저장
 
Dockerfile -f(또는 --file) 로 지정하여 빌드 할 수 있음.
Dockerfile2 를 지정하여 빌드 한다.
using cache 25b7d4634324 . RUN apt-get update Step 4/4 --> using cache --> 44acB4eaBa0d Successful lg built 44acB4eaBa0d Successful lg tagged mgcache:0.0 -f Dockerf ilea -t mgcache:0.0 . '/>
 
출력 내용 중 Using cache 는 이전에 빌드 했던 Dockerfile에 같은 내용이 있으면 새로 빌드 하지 않고 같은 명령어 줄까지 이전에 사용한 이미지 레이어를 활용하여 생성함
 
이미지 빌드 오류 시 :
마지막으로 생성된 임시 컨테이너가 삭제되지 않고 남는다.
지정 이미지 이름이 아닌 <none>:<none> 으로 생성
삭제는 rmi 명령어 이용 => # docker rmi (이미지 ID)
 
캐시 기능을 사용하지 않고 빌드 할 경우에는 --no-cache 옵션을 추가하여 사용하면 기존 이미지를 사용하지 않고 새롭게 이미지를 빌드한다.
캐시로 사용할 이미지를 직접 지정할 수 있습니다. --cache-from  옵션을 사용
# docker build --cache-from nginx my_nginx:0.0
 
 
  1. 기타 Dcokerfile 명령어
ENV
Dockerfile 에서 사용될 환경 변수 지정
run 명령에서 -e 옵션을 사용해 같은 이름의 환경변수를 사용하면 기존 값을 덮어 슨다.
# vi Dockerfile
 
FROM Ubuntu:14.04
ENV test /home
WORKDIR $test
RUN touch $test/mytochfile
배시 셸 쳐 럼 ${env_name:-value}는 env_name 의 환경 변수의 값이 설정 되어있지 않으면 value 사용하고 ${env_name:+value} 는 env_name 의 환경 변수의 값이 설정 되어있으면 value 사용하고, 설정 되어 있지 않으면 빈 문자열로 적용합니다.
# vi Dockerfile
 
FROM Ubuntu:14.04
ENV my_env my_value
RUN echo ${my_env:-value} / ${my_env:+alue} / ${my_env2:-value} / ${my_env2:+value}
 
VOLUME
빌드된 이미지로 컨테이너를 생성했을 때 호스트와 공유할 컨테이너 내부의 디렉토리를 설정
JSON 배열 형식으로 여러개 사용 가능
# vi Dockerfile
 
FROM Ubuntu:14.04
RUN mkdir /home/volume
RUN echo test >> /home/volume/testfile
VOLUME /home/volume
 
ARG
빌드 명령을 실행 할 때 추가로 입력 받아 Dockerfile 내에서 사용될 변수의 값을 적용
# vi Dockerfile
 
FROM Ubuntu:14.04
ARG my_arg
ARG my_arg_2=value2
RUN touch ${my_arg}/mytouch
 
입력은 --build-arg 옵션을 이용
# docker build --build-arg my_arg=/home -t myarg:0.0
 
USER
컨테이너 내에서 사용될 사용자 계정의 이름이나 UUID를 설정하면 그 아래 명령어는 해당 사용자 권한으로 실행
RUN 으로 사용자의 그룹과 계정을 생성한 뒤에 사용
RUN groupadd -r author && uderadd -r -g quthor demo
USER demo
...
 
ONBUILD
ONDUILD, FROM, MAINTAUNER를 제외한 RUN, ADD 등 이미지가 빌드 될 때 수행되어야 하는 각종 Dockerfile 의 명령어를 나중에 빌드 될 이미지를 위해 미리 저장해 놓는 것.
부모 이미지의 자식 이미지에만 적용되며, 자식 이미지는 ONBUILD  속성을 상속 받지 않음
# vi Dockerfile
 
FROM Ubuntu:14.04
RUN echo "this is onbuild test!"
ONBUILD RUN echo "onbuild!" >> /onbuild_file
이미지 빌드하거나 활용할 소스코드를 ONBUILD ADD 로 추가해 좀 더 깔끔하게 Dockerfile 을 사용 할 수 있슴.
# vi Dockerfile
 
FROM Ubuntu:14.04
RUN mkrid -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD ADD . /usr/src/app
ONBUILD RUN mvn install
 
STOPSIGNAL
컨테이너가 정지될 때 사용될 시스템 콜의 종류 지정. 기본 값은 SIGTERM
# vi Dockerfile
 
FROM Ubuntu:14.04
STOPSIGNAL SIGKILL
 
 
HEALTHCHECK
이미지로부터 생성된 컨테이너에서 동작하는 어플리케이션의 상태를 체크하도록 설정
예시 :
1분마다 curl -f 옵션 값 실행해 nginx 어플리케이션의 상태를 체크하며, 3초 이사이 소요되면 이를 한 번의 실패로 간주하고, 3번이상 타임아웃이 발생하면 컨테이너는 unhealthy 상태로 설정
# vi Dockerfile
 
FROM nginx
RUN apt-get update -y && apt-get install curl -y
HEALTHCHECK --interval=1m --timeout=3s --retries=3 CMD curl -f http://localhost || exit 1
--interval : 컨테이너 상태를 체크하는 주기
CMD curl -f … : 상태를 체크하는 명령
--timeout  : 설정 시간을 초과하면 상태 초과 실패
--retries : 지정 횟수 만큼 명령 반복
 
설정 후에 이미지를 생성 하면 "docker ps" 를 실행 하면 해당 컨테이너의 STATUS 정보가 추가된 것을 확인 할 수 있음.
상태 체크에 대한 로그는 컨테이너의 정보에 저장
 
SHELL
사용하고자 하는 셸을 설정
# vi Dockerfile
 
FROM node
RUN echo "hello, world"
SHELL ["/usr/local/bin/node"] => 사용 할 셸 지정
RUN -v                             => 빌드 시 셸 버전 출력
리눅스 셀 : /bin/sh -c echo hello, world
윈도우 셸 : cmd /S /C echo hello, world
 
ADD, COPY
로컬 디랙토리에서 읽어 들인 컨텍스트로부터 이미지에 파일을 복사하는 역할.
ADD : 로컬 파일 뿐 아니라 외부 URL 및 tar 파일에서도 파일을 추가할 수 있음. (비 권장: 빌드 시 추가 파일이 명확하지 않음)
COPY : 로컬 파일 만 추가 가능.(권장 :  빌드 시 추가될 파일이 명확 함)
# vi Dockerfile
 
FROM ubuntu:14.04
copy test.html /home/
copy ["test.html", "/home"]
 
ADD test.tar /home => 자동으로 풀어 준다.
 
ENTRYPOINT, CMD
CMD : 컨테이너가 시작 될 때 실행 할 명령어 설정
ENTRYPOINT :
  • CMD 와 유사하게 컨테이너 시작 될 때 실행 할 명령어 설정
  • 커맨드를 인자로 받아 사용 할 수 있는 스크립트의 역할 가능
entrypoint 설정 예시
# docker run -it --entrypoint="echo" --name demo ubuntu:14.04 /bin/bash
 
출력으로 /bin/bash 출력된다.
entrypoint 가 설정되지 않으면 cmd에 설정된 명령어 그대로 사용되지만, entrypoint 가 설정 된 경우에는 층 는 단지 entrypoint 에 대한 인자의 기능을 함.
컨테이너는 CMD 와 entrypoint 중 하나는 설정되어야 한다. 안 그럼 에러
 
스크립트 파일을 entrypoint의 인자로 사용해 컨테이너가 시작될 때마다 해당 스크립트 파일을 실행 하도록 설정 가능
이미지 내에 스크립트 파일이 존재해야 함.
절차 :
  • 설정 및 실행에 대한 스크립트 파일 생성
  • ADD 또는 COPY 로 스크립트를 이미지 내에 포함
  • ENTRYPOINT를 작성한 스크립트로 지정
  • 이미지 빌드
  • 스크립트에서 필요한 인자는 Docker run  명령어에서 cmd 로 entrypoint의 스크립트에 전달
 
예시 :
# vi Dockerfile
 
FROM ubuntu:14.04
RUN apt-get update -y && apt-get install apache2 -y
ADD entrypoint.sh /entrypoint.sh
RUN chmod+x /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
이미지 빌드 후 컨테이너가 시작되면서 entrypoint.sh 파일을 실행.
 
CMD, ENTRYPOINT 형식  : 실제 컨테이너에서 /bin/sh -c /entrypoint.sh /bin/sh -c echo test 실행
CMD echo test
# -> /bin/sh -c echo test
 
ENTRYPOINT /entrypoint.sh
# -> /bin/sh -c /entrypoint.sh
 
JOSN 형식 : 실제 컨테이너에서 /bin/bash /entrypoint.sh echo test 실행
CMD ["echo",  "test"]
# -> echo test
 
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
# -> /bin/bash /entrypoint.sh
 
 
  1. 도커 허브에서 Dockerfile 빌드
도커 허브에서 이미지를 자동으로 빌드(Automated Build)하도록 설정 할 때에도 사용 할 수 있음.
단, 자동으로 빌드된 도커 허브의 저장소는 기존 저장소와 별개로 생성해야 함.
 
연동 방법 :
  • Public and private : push 되면 도커 허브가 해당 브랜치로부터 소스코드를 받아와 이미지를 빌드
웹 훅과 디프로이 키를 설정 필요, 깃 허브 저장소 읽기/쓰기 권한 필요
  • Limited Access :  일기 권한 만
push 후 자동으로 빌드 안됨 로그인 후 직접 빌드 해야 함
 
Dockerfile은 깃허브에 push 하는 소스 코드에 포함되어야 함.
도커 허브 저장소를 최초로 생성했을 때 자동으로 이미지를 빌드하지 않으므로 한 번 이상 깃 허브의 저장소에 push 해야 이미지가 생성됨.
 
깃하브 저장소 사용방법 : https://guides.github.com/activities/hello-world
 
  1. Dockerfile로 빌드 시 주의 점
여러 개의 RUN 명령어를 하나로 줄 일 수 있다면 이미지 레이어의 개수도 또 한 하나로 줄어든다.
왜 명령마다 하나의 레이어가 생성되므로 하나로 줄이면 레이어도 하나로 된다.
# vi Dockerfile
 
FROM ubuntu:14.04
RUN mkdir /test
RUN fallocaye -l 100m /test/dumy
RUN rm /test/dumy
 아래 처럼 한 줄로 변경
# vi Dockerfile
 
FROM ubuntu:14.04
RUN mkdir /test && fallocaye -l 100m /test/dumy && rm /test/dumy
 
docker export, import 명령어를 사용해 컨테이너를 이미지를 만듦으로써 이미지의 크기를 줄일 수 도 있음.
 
Posted by jgpaper

블로그 이미지
jgpaper

최근에 올라온 글

최근에 받은 트랙백

Yesterday
Today
Total

달력

 « |  » 2025.5
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31