hyperskill - Dockerfile (FROM, LABEL, CMD, ENTRYPOINT) 영어 원문
이 주제의 목적은 도커의 근본 아이디어를 당신에게 소개하는 것 입니다.
이는 Dockerfile 입니다.
이는 도커가 이미지를 생성하는 데 사용하는 지침과 명령어의 집합입니다.
당신은 이 구조에 대한 것을 배울 것이고,
매우 중요한 두 가지 지침을 공부 할 겁니다.
모든 섹션에서, 공식 문서에 대한 하이퍼링크를 보게 될 겁니다.
이를 통해서 확실히 공부하세요.
이 공식문서들은 여기에서 콘텐츠들을 보완 해 줍니다.
Dockerfile overview - 도커파일 개요
도커파일은 이미지를 생성하는 기초입니다.
도커파일의 도움으로, 이미지에 무엇이 포함되어야 하는지 묘사할 수 있으며,
어떤 특별한 지침을 사용해야 하는지 설명할 수 있습니다.
도커는 각각의 지침을 맨 위에서 맨 아래까지 실행합니다.
이러한 지침 혹은 명령은 이러한 구조를 따라야 합니다.
INSTRUCTION argument(s)
이러한 지침은 명령어 실행 직전에 Docker 엔진에서 제거될 적절한 주석으로 이끌 수 있습니다.
키워드들은 대소문자에 민감하게 반응하지는 않으나,
코드 규약은 대문자를 사용하여 전체 명령을 작성해야 합니다.
코드 규약은 개발자들이 읽고, 공유하기 편하도록 만든 일종의 규칙이며,
이를 따르지 않을 경우 협업은 매우 힘들어진다.
주석들과 결합하여, 각각의 명령(지침)은 밑의 코드 조각과 닮았습니다 :
# Comment
INSTRUCTION arguments
이 주제를 시작하면서, 우리는 지침(명령)을 위한 주제의 그룹을 표현 할 겁니다.
이러한 명령들에 대해서 자세히 표현하겠다는 의미
당신은 여러가지 근본들에 대해서 배울 거지만,
각각의 중요한 명령들도 배울 겁니다.
FROM instruction - FROM 지침(명령)
각각의 Dockerfile 에서 FROM 키워드는 시작부분에서 볼 수 있는 지침입니다.
단 한 가지 예외는 바로 ARG 지침(명령) 이지만, 이에 대한 목적은 나중에 배울 겁니다.
FROM 명령은 당신이 사용하고 싶어하는 기본 이미지를 지정합니다.
이 명령FROM 을 사용하는 동안, repository 이름은 반드시 소문자를 사용하여 설정해야 합니다.
FROM 명령으로 작업 할 때 기본 이미지를 지정하는 두 가지 선택지를 가지고 있다는 것을 참고하세요 :
1. version tag 없이 지정하기
FROM ubuntu
LABEL author=HyperDamhyeong
ENTRYPOINT ["/bin/bash"]
이러한 경우, 도커는 latest 태그가 있는 이미지 버전을 찾고, 당겨옵니다.(pull)
이는 ubuntu:latest 입니다.
이는 당신이 최신 기능에 접근할 수 있는 것 처럼 도움이 있을 수도 있습니다.
최신 버전은 보안과 성능 향상을 가져 올 거지만,버그와 취약점 가능성도 있습니다.
하지만 만약 당신이 버그가 없으며, 보안이 튼튼한 것을 원한다면,
당신은 이미 사용되고 테스트 된 stable(안정) 버전을 선택 할 수 있습니다.
2. version tag 를 지정하기
이 선택지는 최신 업데이트를 제공하지는 않지만,
새로운 이미지 버전으로 마주칠 수 있는 다른 유형의 이슈들을 방지합니다.
당신의 컨테이너는 더 오래된 버전과 실행할 수 있지만,
새로운 버전으로 인해 가져온 변화로 인해 에러가 발생할 수 있습니다.
당신이 필요한 버전을 선택하세요.
만약 당신이 최신 기능을 원한다면 새로운 버전을 선택할 수 있습니다.
만약 당신이 버그가 없고 보안이 튼튼한 것을 원한다면,
이미 사용되고 테스트된 안정(stable) 버전을 선택 할 수 있습니다.
FROM 명령(instruction - 지침) 은 AS <NAME> 선택지를 지원합니다.
당신이 멀티스테이지 빌드를 할 때, 이 선택지로 해당 빌드 스테이지의 이름을 지정하는 데 사용할 수 있습니다.
이러한 기능은 미래의 주제들에서 다뤄 볼 겁니다.
LABEL instruction - LABEL 명령(지침)
Dockerfile 에서는 당신이 도커 이미지 내부에 지정할 메타데이터 레이블(LABEL) 을 정의할 수 있습니다.
레이블(라벨 - label) 은,
작성자 정보(author info), 환경 변수(environment), 버전 정보(version info), 등등이 있습니다.
이러한 레이블들은 key=value 형식을 가지고 있는 키-값 쌍이며,
key, value 둘 다 쌍따옴표("") 로 에워싸거나,
이러한 따옴표가 없을 수 있습니다 :
FROM ubuntu:22.04
LABEL author=HyperDamhyeong
LABEL "application_environment"="development"
LABEL "version"=1.0
LABEL multi.first-key="first-value" multi.second-key="second-value"
LABEL first-key=first-value \
second-key=second-value
ENTRYPOINT ["/bin/bash"]
여기서 사용된 "" 에 대한 사용 용도는,
LABEL등록 시 여러 줄을 등록 할 수 있게 하는 것이다.
만약 당신이 이미지 혹은 컨테이너를 검사한다면,
레이블(label) 정보는 Config 섹션에서 볼 수 있습니다.
위의 Dockerfile 에서 생성된 이미지에 대한 label 정보를 확인 해 봅시다.
이를 위해서, 도커파일에서 ubuntu:v1 이미지를 생성하고,
docker inspect ubuntu:v1 --format='{{json .Config}}' 를 실행하세요.
직접 실행하지 않음 : 예시
{
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "sha256:616dd48aceb01a1e3874006bef404aac16abb4c6579d3da63d2448b8e6278271",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/bash"
],
"OnBuild": null,
"Labels": {
"application_environment": "development",
"author": "HyperDamhyeong",
"key_1": "value_1",
"key_2": "value_2",
"multi.label1": "value1",
"multi.label2": "value2",
"version": "1.0"
}
}
CMD instruction - CMD 명령
CMD 명령(지침) 은 이미지 내부 어플리케이션에서 구동되며,
컨테이너가 인스턴스화 된 후 실행됩니다.
이는 목적을 위해서 명령어와 인수를 가집니다.
보통, 선호되는 구조는 CMD ["executable", "param1", "param2"...] 입니다.
하지만, 또다른 접근법 또한 존재합니다.
각각의 도커파일은 하나의 CMD 명령만을 가져야 합니다.
하지만, 이는 도커파일이 여러 CMD 명령을 가지지 못한다는 의미가 아닙니다.
이러한 경우, 각각의 CMD 는 이전의 CMD 를 재정의 합니다.
CMD 를 실전에서 관찰 해 봅시다.
당신이 이러한 도커파일을 가지고 있다고 가정 해 봅시다 :
FROM ubuntu: 22.04
LABEL author=HyperDamhyeong
# Shell form - 쉘 형식
CMD echo Hello Damhyeong.
# Exec form - 실행 형식
CMD ["echo", "Hello Damhyeong."]
당신이 보다시피, 도커파일에서 CMD 명령을 정의하는 두 가지 접근법이 있습니다.
1. CMD echo Hello Damhyeong. :
쉘에서 명령어를 실행합니다.
디폴트 명령어는 원래 /bin/sh -c 입니다.
명령어는 파이프, 하위 명령어, 시그널 구성과 같은 쉘 기능을 가동합니다.
2. CMD ["echo", "Hello Damhyeong."] :
주어진 인자로 된 바이너리를 실행합니다.
이 접근법은 더 공통적으로 사용됩니다.
만약 당신이 이미지를 빌드하고 컨테이너로 실행한다면,
결과는 Hello Damhyeong. 밖에 없을 겁니다.
CMDinstruction 이 두 번 실행되지 않고, 재정의 되었기 때문
게다가 도커파일 내부에 명령어를 지정하고 난 후,
컨테이너를 구동 할 때 명령어를 통과시킬 수 있습니다.
위의 도커파일에서 생성된 이미지 ID 로 이를 실행 해 봅시다 :
$ docker run d559b5d58841 echo Hi
Hi
이 명령어는 두 번째로 작성된 CMD 지침을 재정의하며,
HI 를 대신 출력합니다.
이러한 행동양식을 이해하는 것은 매우 중요한데,
이는 CMD 와 ENTRYPOINT 명령어 간의 중요한 차이점이기 때문입니다.
ENTRYPOINT instruction - ENTRYPOINT 명령
ENTRYPOINT 명령은 컨테이너가 생성되었을 때,
이미지 내부의 어플리케이션을 타겟으로 합니다.
이 명령은 CMD 와는 다른데,
이는 이미 존재하는 ENTRYPOINT 명령을 재정의하지 않기 때문입니다.
실제로, 어떤 경우에는 ENTRYPOINT 와 CMD 명령을 결합합니다.
이는 다음 섹션에서 배워 볼 겁니다.
이 명령을 사용하기 전에, shell 형식을 깊게 탐색 해 봅시다.
당신이 이미 알다시피,
당신이 이 명령을 사용할 때 문자열로 예상되는 /bin/sh -c 명령어를 실행합니다.
따라서 echo Hello Damhyeong. 은 실제로 내부의 실행 문자열을 보았을 때,
/bin/sh -c 'echo Hello Damhyeong.' 명령과 동일합니다.
당신이 이러한 도커파일을 가졌다고 가정 해 봅시다 :
FROM ubuntu:22.04
LABEL author=HyperDamhyeong
# shell form - 쉘 형식
ENTRYPOINT echo Hello Students.
이제, 컨테이너를 나열했을 때 COMMAND 컬럼을 확인 해 봅시다 :
$ docker ps -a --format "table {{.Names}}\\t{{.Command}}" --last 1
NAMES COMMAND ...
hs-ubuntu-2 "/bin/sh -c 'echo He…"
위의 명령어를 외울 필요는 아직 없으며, 속성을 접근하는 것이 도커에서 가장 어려운 부분이다..
이는 당신이 컨테이너를 구동 할 때, echo 명령어와 함께 인자를 하나 더 통과시키는 것을 방지합니다.
이를 피하기 위해서, 도커에게 명령어를 명시적으로 말해주는데, /bin/echo 명령어와, exec 형식으로 작성합니다.
그런데, 당신이 이 예제에서 bin/echo 대신에 echo 를 사용했을 때 비슷한 행동을 보게 될 겁니다.
조그마한 업데이트 후, 도커파일은 이와 같이 생겼습니다.
FROM ubuntu:22.04
LABEL author=HyperDamhyeong
# exec form - 실행 형식
ENTRYPOINT ["/bin/echo", "Hello Damhyeong."]
이제, 이 도커파일을 컨테이너 실행하는 데 사용하면서, 하나의 인자를 통과시켜 봅시다 :
$ docker run --name hs-ubuntu-3 ubuntu:v3 `date`
Hello Students. Thu Nov 10 12:01:19 UTC 2022
볼 수 있다시피, 우리는 도커파일의 ENTRYPOINT 를 재정의하지 않았습니다.
하지만, 하나의 인자가 더 붙었을 뿐입니다.
이제 컨테이너 정보를 확인 해 보면 :
NAMES COMMAND
hs-ubuntu-3 "/bin/echo 'Hello St…"
이 때는 우리가 예상했던 대로 /bin/echo 명령어를 적용했습니다.
이제 우리는 두 가지 명령어를 결합 해 봅시다 :
Combining CMD and ENTRYPOINT
CMD 와 ENTRYPOINT 결합하기
당신이 만약 이미지의 메인 명령어를 정의하고,
당신이 원할 때 이러한 인자들과 플래그를 재정의 할 수 있는 능력을 가지고 싶다면,
CMD 와 ENTRYPOINT 두 명령어를 결합 할 수 있습니다.
실제를 대비하기 위해 이러한 이미지를 사용 해 봅시다 :
FROM ubuntu:22.04
LABEL author=HyperDamhyeong
ENTRYPOINT ["echo"]
CMD ["Hello", "Students."]
만약 당신이 이 도커파일을 기반으로 컨테이너를 구동한다면,
기본적으로 echo 명령어가 기반으로 깔리며, 재정의할 수 없습니다.
ENTRYPOINT지침은 재정의할 수 없다.
다른 한 편으로, 도커파일 내부의 파라미터를 정의하거나,
컨테이너를 실행 할 때 새로운 파라미터들을 통과시킬 수 있습니다.
Conclusion - 결론
이 주제로, 당신은 도커파일 명령(지침)의 세계에 디딤돌을 밣았습니다.
당신은 도커를 사용할 때 도움을 주는 몇 가지 중대한 명령(지침)을 탐색했습니다.
이 주제를 요약 해 봅시다 :
FROM명령은 기본 이미를 지정할 수 있게 해 줍니다LABEL지침을 사용하여 이미지 내부의 metadata 를 지정할 수 있게 해 줍니다.CMD명령은 이미지 내부의 어플리케이션에서 실행할 수 있게 해 줍니다.ENTRYPOINT명령은CMD명령과 다른데, 이는 컨테이너를 시작 할 때, 재정의 할 수 없기 때문입니다.
words to remember
preceded : 선행, 앞서다, ~의 앞에 나서다, 안내자가
dedicated : 헌신적인, 오로지 특정한 목적을 위한
vulnerabilities : 취약점, 상처받기 쉬움, 비난받기 쉬움
enclosed : 에워싸는, 넣는, 동봉하는
inspect : 검사하다, 시찰하다, 검열하다, 검사하다
'Hyperskill - 컴퓨터 CS 및 영어 독해 > Introduction to Docker' 카테고리의 다른 글
| Docker build and docker tag - 도커 이미지 기초 지식 (1) | 2024.08.31 |
|---|---|
| Basic operations with a container - 도커 컨테이너 기초 명령어 (0) | 2024.08.30 |
| Run the "hello-world" docker container - hello-world 이미지로 도커 컨테이너 실행하기 (4) | 2024.08.28 |
| Introduction to docker and installation (1) | 2024.08.27 |
| Containers - 컨테이너 기초 의미 (2) | 2024.08.23 |