1. 개요
Dockerfile에서 우리는 종종 run , cmd 또는 entrypoint 와 같은 명령을 접하게 됩니다. 언뜻보기에는 모두 명령을 지정하고 실행하는 데 사용됩니다. 그러나 그들 사이의 차이점은 무엇입니까? 그리고 그들은 어떻게 서로 상호 작용합니까?
이 사용방법(예제)에서는 이러한 질문에 답합니다. 이러한 각 지침이 수행하는 작업과 작동 방식을 제시합니다. 또한 이미지를 빌드하고 Docker 컨테이너를 실행하는 데 어떤 역할을 하는지 살펴보겠습니다 .
2. 설정
시작하려면 log-event.sh 스크립트를 생성해 보겠습니다. 단순히 파일에 한 줄을 추가한 다음 인쇄합니다.
#!/bin/sh
echo `date` $@ >> log.txt;
cat log.txt;
이제 간단한 Dockerfile을 만들어 보겠습니다.
FROM alpine
ADD log-event.sh /
다양한 시나리오에서 log.txt 에 행을 추가하여 스크립트를 사용 합니다.
3. 실행 명령
실행 우리가 이미지를 빌드 할 때 명령이 실행됩니다. 이는 run 에 전달된 명령 이 새 레이어의 현재 이미지 위에서 실행 됨을 의미합니다 . 그런 다음 결과가 이미지에 커밋됩니다. 이것이 실제로 어떻게 보이는지 봅시다.
먼저 Dockerfile에 실행 명령을 추가합니다 .
FROM alpine
ADD log-event.sh /
RUN ["/log-event.sh", "image created"]
두 번째로 다음을 사용하여 이미지를 빌드해 보겠습니다.
docker build -t myimage .
이제 내부에 한 줄의 이미지가 생성 된 log.txt 파일이 포함된 Docker 이미지가 있을 것으로 예상합니다 . 이미지를 기반으로 컨테이너를 실행하여 이를 확인합시다.
docker run myimage cat log.txt
파일 내용을 나열하면 다음과 같은 출력이 표시됩니다.
Fri Sep 18 20:31:12 UTC 2020 image created
컨테이너를 여러 번 실행하면 로그 파일의 날짜가 변경되지 않는 것을 볼 수 있습니다. 이는 실행 단계 가 컨테이너 런타임이 아닌 이미지 빌드 시간에 실행 되기 때문에 의미가 있습니다 .
이제 이미지를 다시 빌드해 보겠습니다. 로그의 생성 시간이 변경되지 않았음을 알 수 있습니다. 이것은 Dockerfile이 변경되지 않은 경우 Docker가 실행 명령에 대한 결과 를 캐시 하기 때문에 발생합니다 . 캐시를 무효화 하려면 빌드 명령에 –no-cache 옵션을 전달해야 합니다 .
4. cmd 명령
으로 cmd를 명령, 우리는 컨테이너를 시작하는 실행하는 기본 명령을 지정할 수 있습니다. Dockerfile에 cmd 항목을 추가하고 작동 방식을 살펴보겠습니다.
...
RUN ["/log-event.sh", "image created"]
CMD ["/log-event.sh", "container started"]
이미지를 빌드한 후 이제 실행하고 출력을 확인합니다.
$ docker run myimage
Fri Sep 18 18:27:49 UTC 2020 image created
Fri Sep 18 18:34:06 UTC 2020 container started
이것을 여러 번 실행하면 이미지 생성 항목이 동일하게 유지되는 것을 볼 수 있습니다. 그러나 컨테이너는 실행할 때마다 항목 업데이트를 시작했습니다 . 이것은 컨테이너가 시작될 때마다 cmd가 실제로 어떻게 실행 되는지 보여줍니다 .
이번에는 컨테이너를 시작 하기 위해 약간 다른 docker run 명령을 사용했습니다 . 이전과 동일한 명령을 실행하면 어떻게 되는지 봅시다.
$ docker run myimage cat log.txt
Fri Sep 18 18:27:49 UTC 2020 image created
이번에 는 Dockerfile에 지정된 cmd 가 무시됩니다. docker run 명령에 인수를 지정했기 때문 입니다.
이제 계속 해서 Dockerfile에 cmd 항목 이 두 개 이상 있으면 어떻게 되는지 살펴 보겠습니다. 다른 메시지를 표시할 새 항목을 추가해 보겠습니다.
...
RUN ["/log-event.sh", "image created"]
CMD ["/log-event.sh", "container started"]
CMD ["/log-event.sh", "container running"]
이미지를 빌드하고 컨테이너를 다시 실행하면 다음 출력을 찾을 수 있습니다.
$ docker run myimage
Fri Sep 18 18:49:44 UTC 2020 image created
Fri Sep 18 18:49:58 UTC 2020 container running
우리가 볼 수 있듯이, 컨테이너가 시작 항목이없는 만 컨테이너 실행이 있습니다 . 둘 이상 지정되면 마지막 cmd만 호출 되기 때문 입니다.
5. 진입점 명령
위에서 보았듯이 컨테이너를 시작할 때 인수를 전달하면 cmd 가 무시됩니다. 더 많은 유연성을 원하면 어떻게 합니까? 추가된 텍스트를 사용자 지정하고 docker run 명령에 인수로 전달한다고 가정해 보겠습니다 . 이를 위해 진입점을 사용합시다 . 컨테이너가 시작될 때 실행할 기본 명령을 지정합니다. 또한 이제 추가 인수를 제공할 수 있습니다.
Dockerfile 의 cmd 항목을 진입점으로 교체해 보겠습니다 .
...
RUN ["/log-event.sh", "image created"]
ENTRYPOINT ["/log-event.sh"]
이제 사용자 정의 텍스트 항목을 제공하여 컨테이너를 실행해 보겠습니다.
$ docker run myimage container running now
Fri Sep 18 20:57:20 UTC 2020 image created
Fri Sep 18 20:59:51 UTC 2020 container running now
진입점이 cmd 와 유사하게 작동하는 방식을 볼 수 있습니다 . 또한 시작 시 실행되는 명령을 사용자 지정할 수 있습니다.
cmd 와 마찬가지로 진입점 항목 이 여러 개인 경우 마지막 항목만 고려됩니다.
6. cmd 와 진입점 간의 상호 작용
컨테이너를 실행할 때 실행되는 명령을 정의하기 위해 cmd 와 entrypoint 를 모두 사용했습니다 . 이제 cmd 와 진입점 을 조합 하여 사용하는 방법을 살펴보겠습니다 .
이러한 사용 사례 중 하나는 진입점에 대한 기본 인수를 정의하는 것 입니다. Dockerfile의 진입점 뒤에 cmd 항목을 추가해 보겠습니다 .
...
RUN ["/log-event.sh", "image created"]
ENTRYPOINT ["/log-event.sh"]
CMD ["container started"]
이제 인수를 제공하지 않고 cmd에 지정된 기본값으로 컨테이너를 실행해 보겠습니다 .
$ docker run myimage
Fri Sep 18 21:26:12 UTC 2020 image created
Fri Sep 18 21:26:18 UTC 2020 container started
다음과 같이 선택하면 재정의할 수도 있습니다.
$ docker run myimage custom event
Fri Sep 18 21:26:12 UTC 2020 image created
Fri Sep 18 21:27:25 UTC 2020 custom event
주의해야 할 점은 셸 형식으로 사용될 때 진입 점의 다른 동작입니다 . Dockerfile 에서 진입점 을 업데이트 해 보겠습니다.
...
RUN ["/log-event.sh", "image created"]
ENTRYPOINT /log-event.sh
CMD ["container started"]
이 상황에서 컨테이너를 실행할 때 Docker가 docker run 또는 cmd에 전달된 모든 인수를 무시하는 방법을 볼 수 있습니다 .
7. 결론
이 기사에서 우리는 Docker 명령어인 run , cmd 및 entrypoint 간의 차이점과 유사점을 보았습니다 . 우리는 그들이 호출되는 시점을 관찰했습니다. 또한 사용 방법과 함께 작동하는 방법을 살펴보았습니다.