반응형

 

1편 (RUN, CMD, ENTRYPOINT) : https://nirsa.tistory.com/66?category=868315

2편 (ONBUILD, STOPSIGNAL, HEALTHCHECK) : https://nirsa.tistory.com/68?category=868315

 

4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315

 

  • 들어가기전에...

간혹 override 라는 단어가 등장 하는데, 일반적으로 override는 물려받은 값(변수 등)을 다르게 만들어 생성하는 개념입니다. 

CMD에 선언한 명령을 ls라고 선언 후 conatiner run을 사용할 때 ps 를 사용 하거나, ENTRYPOINT에서 선언한 명령을 --entrypoint= 옵션을 사용하여 변경하는 경우 등 기존에 상속받은 정해진 값을 변경하여 사용할 때 override를 했다고 합니다.

 

  • 7. COPY, ADD

명령 두개 다 호스트OS의 파일 또는 디렉토리를 컨테이너 안의 경로로 복사 합니다.

COPY의 경우 호스트OS에서 컨테이너 안으로 복사만 가능하지만, ADD의 경우 원격 파일 다운로드 또는 압축 해제 등과 같은 기능을 갖고 있습니다. 즉, 호스트OS에서 컨테이너로 단순히 복사만을 처리할 때 COPY를 사용 합니다.

 

ADD와 COPY 두 명령 모두 사용법은 아래와 같으며 소유자와 소유그룹도 수정이 가능 합니다.

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (이 형식은 공백이 포함 된 경로에 필요합니다)

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (이 형식은 공백이 포함 된 경로에 필요합니다)

 

소유자와 소유그룹 필요 없이 사용할때는 다음과 같이 사용하시면 됩니다.

## COPY <호스트OS 파일 경로> <Docker 컨테이너 안에서의 경로>
COPY test.sh /root/copy/test.sh

## ADD <호스트OS 파일 경로> <Docker 컨테이너 안에서의 경로>
ADD test.sh /root/add/test.sh

 

ADD 명령의 경우 아래와 같이 url을 입력하여 다운로드도 가능 합니다.

## ADD <다운 받을 URL> <Docker 컨테이너 안에서의 경로>
ADD http://~~~~~~/index.php /root/add_url/index.php

 

  • 8. ENV, ARG

ENV와 ARG는 비슷해 보이지만 다른 명령 입니다.

ENV는 Dockerfile 또는 컨테이너 안에서 환경 변수로 사용이 가능하고, ARG는 Dockerfile 에서만 사용이 가능 합니다.

# ENV 사용 법

# ENV [key] [value]
ENV myName nirsa
ENV myAddress nirsa.tistory.com

# ENV [key]=[value]  ## 한번에 여러개의 값을 설정할 때 사용
ENV myName=nirsa \
    myAddress=nirsa.tistory.com
# ARG 사용법

# [key]=[value]
ARG myName=nirsa
ARG myAddress=nirsa.tistory.com

때문에 ARG의 경우 Dockerfile 작성하는데에 필요한 변수를 선언하여 Dockerfile을 좀 더 편하게 작성할 수 있고, ENV는 변수 선언은 물론, 컨테이너 안에서 사용할 환경 변수(작업 디렉토리 지정) 등 선언하여 사용할 수 있습니다. 

 

ENV가 실제로 컨테이너 안에서 환경변수로 작동 하는지 알 기 위해 아래 스크립트를 사용해주세요. (Dockerfile 이 있는 경로에 test.sh 으로 생성)

FROM centos:7

COPY test.sh /root/mkdir/test.sh
ENV DIR=/root/mkdir/

RUN echo ${DIR}
CMD ${DIR}/test.sh

빌드할 때 DIR 변수를 정확히 /root/workdir 으로 인식하고 있고, container run을 할 때도 $DIR/test.sh 즉,  /root/workdir/test.sh를 정확히 실행 하였습니다. (WORKDIR은 리눅스의 cd와 같이 작업 디렉토리로 이동 하지만 ENV는 환경 변수일 뿐이고, pwd 경로를 보시면 아시겠지만 루트 디렉토리에서 작업 합니다.)

 

test.sh 의 코드를 그대로 사용하되 ENV를 ARG로 변경해주세요.

FROM centos:7

COPY test.sh /root/mkdir/test.sh
ARG DIR=/root/mkdir/

RUN echo ${DIR}
CMD ${DIR}/test.sh

빌드할때엔 ARG로 선언한 변수 DIR가 재대로 /root/workdir를 선언 하였고, container run할때는 ARG로 선언한 변수가 사라져서 /root/workdir/test.sh 를 찾지 못하고, 루트 디렉토리 밑에서 test.sh를 찾지 못했다고 나옵니다.

 

* 이러한 설정들은 docker container inspect [컨테이너명] 을 입력하고 확인할 수 있습니다.

 

  • 9. WORKDIR

WORKDIR은 명령을 실행하기 위한 디렉토리를 지정 합니다.

우선 WORKDIR을 확인하기 위해 Dockerfile이 있는 디렉토리 안에 아래와 같은 코드의 test.sh 생성 및 Dockerfile을 수정해 줍니다. (COPY 명령은 이후 ADD와 같이 업로드 할 것 입니다, 간단히 호스트OS test.sh를 컨테이너 안의 /root/mkdir/test.sh 으로 복사하는 명령 입니다.)

빌드 후 container run을 하시면 WORKDIR로 이동된 경로와 test.sh가 실행되어 Hello, world!가 출력 됩니다. 즉 WORKDIR 명령은 리눅스의 cd와 비슷한 개념이지만, 작업할 디렉토리를 지정 합니다.

#!/bin/bash

pwd
echo "Hello, world!"
FROM centos:7

COPY test.sh /root/mkdir/test.sh
WORKDIR /root/mkdir/

CMD ./test.sh

 

반응형
반응형

 

1편 (RUN, CMD, ENTRYPOINT) : https://nirsa.tistory.com/66?category=868315

 

3편 (COPY, ADD, ENV, ARG, WORKDIR) : https://nirsa.tistory.com/69?category=868315

4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315

 

  • 4. ONBUILD

ONBULD는 조금 특이하게 처음 사용한 Dockerfeil 에서 빌드할 때(이미지 생성) 실행되는 명령이 아닙니다.

ONBUILD 명령을 사용했던 이미지를, 다른 Dockerfile에서 FROM image를 사용하여 빌드 했을 때 동작 합니다.

 

 

 일반적으로 사용하는 명령은 아니지만 웹서버를 구동시키기 위한 이미지를 만들어두고 ONBUILD ADD web.tar /var/www/html 과 같이 미리 정의 해둔 뒤, 개발자들이 해당 경로에 웹서버에 필요한 코드들을 해당 경로에 web.tar을 만들어서 빌드 후 실행시키는 등에 사용한다고 합니다.

 

  • 5. STOPSIGNAL

docker container stop 명령을 입력하면 Docker 데몬이 컨테이너에게 signal을 보내 중지 하는데, 기본적으로 STOPSIGNAL을 명시하지 않을 경우 SIGTERM을 사용 하게 됩니다.

즉 container stop 할 때에 보낼 시그널을 지정할 수 있습니다.

STOPSIGNAL [시그널]   ## 시그널 번호 또는 이름

docker container stop 실행 시 SIGTERM signal을 받은 컨테이너가 프로세스를 정상적으로 종료할 수 있을때 까지 기다리게 되는데, 지정된 시간 (deafult 10sec, 사용자 지정 가능)동안 종료가 되지 않으면 SIGKILL을 전송합니다. 

참고 사이트 : https://stackoverflow.com/questions/50898134/what-does-docker-stopsignal-do

 

일반적으로 많이 사용하지는 않지만, 현재 github 에서는 nginx를 사용해 유닉스 소켓을 사용하면 container stop 시 Docker 데몬이 컨테이너에게 SIGTERM signal을 보내 nginx가 중단되고 모든 연결이 한번에 끊어지는 현상이 발생하여 비정상적인 종료가 된다고 합니다.

때문에 STOPSIGNAL SIGQUIT 을 사용하는게 옳다고 하기도 하며, gibhub에서 꾸준히 사람들이 토론중인걸로 보입니다.

참고 사이트 : https://github.com/Kong/docker-kong/pull/259https://github.com/nginxinc/docker-nginx/issues/377 , https://github.com/nginxinc/docker-nginx/issues/167

 

  • 6. HEALTHCHECK

컨테이너의 HEALTHCHECK를 사용하여 컨테이너의 프로세스 상태를 체크할 수 있고, 두가지 사용 방법이 있습니다.

  • HEALTHCHECK [OPTIONS] CMD command  (컨테이너 내부에서 명령 실행하여 컨테이너 상태 확인, 이 방법을 통해 웹페이지 등을 확인할 수 있습니다)
  • HEALTHCHECK NONE (베이스 이미지에서 상속된 상태 확인을 비활성화)

또한 Dockerfile에서 HEALTHCHECK는 하나의 명령만이 유효하고, 만약 여러개가 있다면 가장 마지막에 선언된 HEALTHCHECK가 적용 됩니다.

옵션 설명 기본값
--interval=DURATION 헬스 체크 간격 30s
--timeout=DURATION 타임 아웃 30s
--retries=N 타임 아웃 횟수 3

 

HEALTHCHECK의 처음 상태는 starting 이고, HEALTHCHECK가 통과될 때 마다 healthy (이전 상태와 상관없이) 됩니다. 그리고 옵션에 정한 일정 횟수가 실패된다면 unhealthy 상태로 됩니다.

EXIT CODE 설명
0: success 컨테이너가 정상적이고 사용 가능한 상태
1: unhealthy 컨테이너가 올바르게 작동하지 않는 상태
2: starting 예약된 코드

 

이 상태는 docker container inspect [컨테이너명] 또는 docker container ls 에서 확인할 수 있습니다.

 

 


HEALTHCHECK를 확인해보기 위해 아래 코드를 Dockerfile에 넣은 후 centos7 버전에 nginx를 설치하고 컨테이너를 실행 해주세요.

FROM centos:7

RUN touch /etc/yum.repos.d/nginx.repo && echo -e '[nginx]\nname=nage repo\nbaseurl=http://nginx.org/packages/centos/7/$basearch/\ngpgcheck=0\nenabled=1' > /etc/yum.repos.d/nginx.repo

RUN yum -y install nginx curl

HEALTHCHECK --interval=10s --timeout=3s CMD curl -f http://127.0.0.1/ || exit 1

CMD ["nginx", "-g", "daemon off;"]
  • 옵션 설명 : 10초마다(interval) HEALTHCHECK를 하고, 3초 이상이 소요(timout)되면서 3번의 재시도(retries, 초기값3)가 실패하면 unhealthy 상태로 변경됨

 

HEALTHCHECK는 컨테이너까지 실행 후 docker container inspect [컨테이너명] 으로 아래와 같이 확인이 가능하지만, 이러한 데이터들은 영구적으로 남는게 아니라 4096byte만 현재 상태에 저장된다고 합니다.

 

 

 

반응형
반응형

 

  • 1. 가상머신 우클릭 → Setting

 

  • 2. CD/DVD → Device status 상태 확인 (Connected만 체크 상태) → OK

* Use ISO image file이 지정되어있는 상태에서 Connect at power on 을 선택하면 이미지 파일때문에 VMware tools가 보이지 않고 이미지 파일만 보일 수 있습니다. 반드시 Connected 만 체크해주세요 

 

  • 3. VMware 상단의 VM → Install VMware Tools... 클릭

 

 

  • 4. mkdir /mnt/cdrom →  mount /dev/cdrom /mnt/cdrom

만약 이미 2번에서 VM의 cdrom 설정에서 Connect at power on 을 선택하여 마운트 했을 때 이미지 파일이 보이고 있다면, umount /mnt/cdrom 입력하신 후 3번과 똑같이 따라가면 cencel vmware tools.. 가 보입니다. 클릭하여 캔슬 후 다시 1번부터 천천히 따라와주세요.

 

  • 5. tar zxpf /mnt/cdrom/VMwareTools-x.x.x-yyyyyyyy.tar.gz 

버전 등에따라 위에 x와 y로 적은 부분이 달라질 수 있습니다. 파일명에 맞춰 입력 후 압축 해제 해주세요. 

 

  • 6. yum -y install kernel-headers open-vm-tools

 

  • 7.  cd / → umount /mnt/cdrom → /cd /vmware-tools/distrib/ → ./vmware-install.pl

더이상 불필요하기에 마운트를 해제 하고 설치를 진행 합니다. 엔터 쭉 눌러주시면 설치가 완료 됩니다.

 

 

 

반응형
반응형

2편 (ONBUILD, STOPSIGNAL, HEATHCHECK) : https://nirsa.tistory.com/68?category=868315

3편 (COPY, ADD, ENV, ARG, WORKDIR) https://nirsa.tistory.com/69?category=868315

4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315

 

  • 들어가기전에...

Dockerfile과 같은 디렉터리에 있는 모든 파일들을 컨텍스트(context)라고 합니다. docker build 를 사용하여 이미지를 생성할 때 컨텍스트 모두를 Docker 데몬에 전송하기 때문에 / 디렉토리에 Dockerfile을 생성하던가 하면 시스템 처리 속도가 굉장히 느려질 수 있습니다. 

때문에 Dockerfile은 따로 디렉토리를 새로 생성하는것으로 권장 됩니다.

컨텍스트에서 파일이나 디렉토리를 제외할때 Dockerfile 과 같은 경로에 .dockerignore 파일을 생성하여 제외하고싶은 파일이나 디렉토리를 지정해줄 수 있으며 아래는 예시 입니다.

Hello, world.txt
*.log
.git

 

  • 1. RUN

RUN 명령은 아래 예시처럼 패키지 설치 등에 사용 되는건데, 좀 더 특정지어 말한다면 RUN 명령은 image layer를 만들어냅니다. (image layer는 https://nirsa.tistory.com/63?category=868315 참고)

 

/bin/sh 또는 exec 형식으로 작성할 수 있는데 exec 형식은 JSON배열로 지정 됩니다.

FROM centos:7

# nignx 설치 (/bin/sh 예시)
# RUN yum -y install nginx

# nignx 설치 (exec 형식 예시)
# RUN ["/bin/bash", "-c", "yum -y install nginx"]

 

기본적으로 /bin/sh -c 를 통해 실행되기 때문에 yum -y install nginx만 써도 정상적으로 실행 되었습니다.

이미지에 /bin/sh가 없을 경우 exec 형식을 사용하면 되고, 쉘을 경유하지 않고 직접 실행되기 때문에 환경 변수 등 지정할 수 없습니다.

 

* RUN 명령은 되도록 한줄로 작성하는것이 좋습니다. 위에서 말햇듯이 RUN 명령은 image layer를 생성해나가는 과정이기 때문에 같은 결과를 가져오더라도 RUN을 여러줄로 작성하면 image layer가 여러개 생성되고, RUN을 한줄로 작성하면 image layer가 1개로 생성 됩니다. 

FROM centos:7

RUN yum -y install httpd
RUN yum -y install php
RUN yum -y install mysql

 

FROM centos:7

RUN yum -y install httpd php mysqld

 

  • 2. CMD, ENTRYPOINT

CMD와 ENTRYPOINT 명령은 두 개를 비교 해가며 보는게 좀 더 이해하기 편합니다.

일단 두가지의 명령 모두 이미지를 바탕으로 생성된 컨테이너에서 사용 됩니다. (docker run로 생성/실행 또는 docker start으로 실행 시)

 

centos 7버전을 베이스로 하고 nginx를 설치 하였습니다. 그럼 nginx를 실행 시켜줘야겠죠? 그럴때 쓰는것이 CMD 또는 ENTRYPOINT 입니다.

실서버에 centos 7을 깔고, nginx를 설치 한 후 systemctl start nginx 를 입력해주는것과 같습니다.

FROM centos:7

RUN touch /etc/yum.repos.d/nginx.repo && echo -e '[nginx]\nname=nage repo\nbaseurl=http://nginx.org/packages/centos/7/$basearch/\ngpgcheck=0\nenabled=1' > /etc/yum.repos.d/nginx.repo

RUN yum -y install nginx

# nginx foreground 실행
CMD ["nginx", "-g", "daemon off;"]

 

CMD와 ENTRYPOINT의 차이는 docker run 을 사용하며 새로운 명령을 지정한 경우 이 명령이 실행 되는지, 안되는지의 차이 입니다.

CMD : 컨테이너가 실행될 때 명령어 및 인자값 전달하여 실행, 단 docker run 명령에 쉘 명령어 및 인자값 전달할 경우 CMD에 작성된 명령어와 인자값은 무시 됩니다. (다른 명령어와 인자값을 사용한 예는 아래 이미지 확인)

즉, 우선 순위는 docker run > CMD

FROM centos:7

CMD ["/bin/ls", "-lh", "/root"]

 

ENTRYPOINT : 컨테이너가 실행될 때 명령어 및 인자값 전달하여 실행, 단 docker run 명령에 쉘 명령어 및 인자값 전달할 경우 쉘 명령어는 영향을 받지 않으며, 인자값만 영향을 받습니다.

즉, 우선 순위는 ENTRYPOINT (인자값) < docker run < ENTRYPOINT (명령어)

 

1. docker container run -it ent_hw 를 입력했을 땐 그대로 ls -lh /root 의 결과값이 나옵니다.

2. docker container run -it ent_hw ls -la 를 입력했을 땐 그대로 ls -la /root 의 결과값이 나옵니다. (인자값만 수정한 경우)

3. docker container run -it ent_hw ps -ef 를 입력했을 땐 에러가 발생 합니다. (명령어까지 수정한 경우)

FROM centos:7

ENTRYPOINT ["/bin/ls", "-lh", "/root"]

 

ENTRYPOINT는 conatiner run의 --entrypoint="실행명령" 옵션을 사용하여 Dockerfile에 정의한 ENTRYPOINT를 무시할 수 있습니다.

아래는 --entrypoint 옵션을 사용하여 ent_hw 이미지를 생성 및 실행하며 cat /etc/hosts 를 수행 합니다.

FROM centos:7

ENTRYPOINT ["/bin/ls", "-lh", "/root"]

 

  • 3. CMD, ENTRYPOINT 정리

CMD는 명령과 인자값이 변경될 수 있고, 컨테이너에서 명령 설정하지 않을 시 CMD에 기재된 명령을 기본값으로 실행됩니다. ENTRYPOINT는 명령 수정이 불가능하여 사용자에 의해 변경되지 않고 고정적으로 실행될 명령은 ENTRYPOINT를 사용하는것이 좋습니다.

 

 

 

반응형

+ Recent posts