티스토리 뷰

728x90
반응형

개요

본 포스팅에서는 Docker 이미지 빌드를 위한 Dockerfile 작성 시 유의할 3가지 종류의 태그에 대해 살펴보도록 하자.

Dockerfile은 Docker Image를 생성하기 위한 Docker Container의 형태를 정의하는 Template이라 할 수 있다.

Admin은 Dockerfile에 정의된 태그를 기반으로 Docker Image를 생성하며, Docker Image는 실제 Container 서비스로 동작하게 된다.

즉 Image를 어떻게 생성하느냐에 따라 서비스 형태가 달라지고 유지보수 효율성을 확보할 수 있는지 결정되기 때문에 이는 컨테이너 서비스를 제공하기 위한 중요한 고려사항이라 할 수 있다.

Dockerfile을 작성하기 위한 요소 중 다음에서 다룰 3가지 사항은 비슷한 개념으로 충돌되는 태그이다.

각 태그가 갖고 있는 특징을 기반으로 어떠한 경우에 해당 TAG를 사용하는 것이 유용한지 판단하는 기준을 삼았으면 한다.

ADD vs COPY

먼저 복사 관련 명령어 이다. ADD와 COPY 모두 호스트 노드의 특정 파일을 컨테이너 이미지로 복사한다.

[ADD]는 원격지의 파일을 다운로드 받거나, tar 등의 알려진 압축파일을 해제하는 역할로 사용된다.
[COPY]는 로컬의 파일을 단순히 복사하는 용도로 사용된다. 

[root@godnr dockertest]# cat Dockerfile_ADD
FROM centos:latest
ADD test.tar /root/
CMD ls -la /root

[root@godnr dockertest]# cat Dockerfile_COPY
FROM centos:latest
COPY test.tar /root/
CMD ls -la /root

[root@godnr dockertest]#

위와 같이 test.tar 파일을 Container 내부로 복사하는 Dockerfile을 생성한 후 테스트를 진행하였다.

[root@godnr dockertest]# docker build -t addtest -f ./Dockerfile_ADD .
Sending build context to Docker daemon  14.85kB
Step 1/3 : FROM centos:latest
latest: Pulling from library/centos
6910e5a164f7: Pull complete
Digest: sha256:4062bbdd1bb0801b0aa38e0f83dece70fb7a5e9bce223423a68de2d8b784b43b
Status: Downloaded newer image for centos:latest
 ---> 831691599b88
Step 2/3 : ADD test.tar /root/
 ---> 3331201a557a
Step 3/3 : CMD ls -la /root
 ---> Running in c96476f99804
Removing intermediate container c96476f99804
 ---> cd192ca2b06c
Successfully built cd192ca2b06c
Successfully tagged addtest:latest
[root@godnr dockertest]# docker build -t copytest -f ./Dockerfile_COPY .
Sending build context to Docker daemon  14.85kB
Step 1/3 : FROM centos:latest
 ---> 831691599b88
Step 2/3 : COPY test.tar /root/
 ---> 6bfd08d4aeda
Step 3/3 : CMD ls -la /root
 ---> Running in e6d609f03d74
Removing intermediate container e6d609f03d74
 ---> 1f0d5e824523
Successfully built 1f0d5e824523
Successfully tagged copytest:latest
[root@godnr dockertest]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
copytest            latest              1f0d5e824523        16 minutes ago      215MB
addtest             latest              cd192ca2b06c        16 minutes ago      215MB
centos              latest              831691599b88        2 weeks ago         215MB
[root@godnr dockertest]#

각각 생성된 Docker Image를 기동해보자.

[root@godnr dockertest]# docker run -it --name add addtest
total 36
dr-xr-x--- 1 root root   21 Jul  3 21:49 .
drwxr-xr-x 1 root root    6 Jul  3 22:09 ..
-rw-r--r-- 1 root root   18 May 11  2019 .bash_logout
-rw-r--r-- 1 root root  176 May 11  2019 .bash_profile
-rw-r--r-- 1 root root  176 May 11  2019 .bashrc
-rw-r--r-- 1 root root  100 May 11  2019 .cshrc
-rw-r--r-- 1 root root  129 May 11  2019 .tcshrc
-rw------- 1 root root 2366 Jun 11 02:35 anaconda-ks.cfg
-rw-r--r-- 1 root root  435 Jun 11 02:35 anaconda-post.log
-rw------- 1 root root 2026 Jun 11 02:35 original-ks.cfg
-rw-r--r-- 1 root root   16 Jul  3 21:35 test.sh
[root@godnr dockertest]# docker run -it --name copy copytest
total 44
dr-xr-x--- 1 root root    22 Jul  3 21:50 .
drwxr-xr-x 1 root root     6 Jul  3 22:12 ..
-rw-r--r-- 1 root root    18 May 11  2019 .bash_logout
-rw-r--r-- 1 root root   176 May 11  2019 .bash_profile
-rw-r--r-- 1 root root   176 May 11  2019 .bashrc
-rw-r--r-- 1 root root   100 May 11  2019 .cshrc
-rw-r--r-- 1 root root   129 May 11  2019 .tcshrc
-rw------- 1 root root  2366 Jun 11 02:35 anaconda-ks.cfg
-rw-r--r-- 1 root root   435 Jun 11 02:35 anaconda-post.log
-rw------- 1 root root  2026 Jun 11 02:35 original-ks.cfg
-rw-r--r-- 1 root root 10240 Jul  3 21:35 test.tar
[root@godnr dockertest]#

ADD : test.tar 파일이 압축이 해제되어 test.sh로 저장되고, test.tar 파일은 삭제된다.COPY : test.tar 파일 자체가 업로드 된다.위와 같이 ADD는 알려진 압축 형태로 업로드 될 경우 압축을 함께 해제한다는 차이점이 있다.그밖에 ADD는 url 형태의 src를 지원한다. (ADD waspro.tistory.com/test.tar /root/)

# URL 형태의 원격지에서 다운로드 받은 파일은 자동으로 압축이 해제되지 않는다. 
[유의사항] ADD를 사용하여 다운로드 받은 파일을 사용하고 삭제하기 위해 추가적으로 RUN layer가 추가되어야 한다.

ADD url dest
RUN tar -xvf test.tar && make ~~ && rm -rf test.tar

다만 ADD 대신 curl을 사용하여 다운로드 받아 처리할 경우 RUN Layer 하나로 처리가 가능하여 불필요한 Layer 증가를 방지할 수 있다.

RUN curl ~~ && tar -xvf test.tar && make ~~ && rm -rf test.tar

즉 로컬의 파일을 업로드하여 압축을 해제하는 용도로 사용되는 경우가 아닐 경우 굳이 ADD를 사용할 필요는 없다.

CMD vs ENTRYPOINT

다음으로 컨테이너를 실행하는 명령어이다.

[CMD]는 기동 시점에 변경가능한 명령어를 정의한다.

[ENTRYPOINT]는 변경되지 않는 명령어를 정의하는데 사용한다.

[root@godnr dockertest]# cat Dockerfile_CMD
FROM centos:latest
CMD ["/bin/df","-h"]
[root@godnr dockertest]# cat Dockerfile_ENTRY
FROM centos:latest
ENTRYPOINT ["/bin/df","-h"]

[root@godnr dockertest]#

각각 df -h 명령어를 실행하도록 Dockerfile에 정의하였다.

[root@godnr dockertest]# docker build -t cmdtest -f Dockerfile_CMD .
Sending build context to Docker daemon   16.9kB
Step 1/2 : FROM centos:latest
 ---> 831691599b88
Step 2/2 : CMD ["/bin/df","-h"]
 ---> Running in 1284f78d35f1
Removing intermediate container 1284f78d35f1
 ---> 65c460fbf8bb
Successfully built 65c460fbf8bb
Successfully tagged cmdtest:latest
[root@godnr dockertest]# docker build -t entrytest -f Dockerfile_ENTRY .
Sending build context to Docker daemon   16.9kB
Step 1/2 : FROM centos:latest
 ---> 831691599b88
Step 2/2 : ENTRYPOINT ["/bin/df","-h"]
 ---> Running in 44520ba1bf9c
Removing intermediate container 44520ba1bf9c
 ---> ecf7f54d45db
Successfully built ecf7f54d45db
Successfully tagged entrytest:latest
[root@godnr dockertest]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
entrytest           latest              ecf7f54d45db        2 minutes ago       215MB
cmdtest             latest              65c460fbf8bb        2 minutes ago       215MB
copytest            latest              1f0d5e824523        About an hour ago   215MB
addtest             latest              cd192ca2b06c        About an hour ago   215MB
centos              latest              831691599b88        2 weeks ago         215MB
[root@godnr dockertest]#

생성된 이미지를 기동해 보도록 하자.

[root@godnr dockertest]# docker run -it --name cmd cmdtest
Filesystem      Size  Used Avail Use% Mounted on
overlay          32G  1.8G   31G   6% /
tmpfs            64M     0   64M   0% /dev
tmpfs           492M     0  492M   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/xvda1       32G  1.8G   31G   6% /etc/hosts
tmpfs           492M     0  492M   0% /proc/acpi
tmpfs           492M     0  492M   0% /proc/scsi
tmpfs           492M     0  492M   0% /sys/firmware
[root@godnr dockertest]# docker run -it --name entry entrytest
Filesystem      Size  Used Avail Use% Mounted on
overlay          32G  1.8G   31G   6% /
tmpfs            64M     0   64M   0% /dev
tmpfs           492M     0  492M   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/xvda1       32G  1.8G   31G   6% /etc/hosts
tmpfs           492M     0  492M   0% /proc/acpi
tmpfs           492M     0  492M   0% /proc/scsi
tmpfs           492M     0  492M   0% /sys/firmware
[root@godnr dockertest]#

위와 같이 실행 결과는 동일하게 나타난다.

이제부터 각 동작방식을 확인하기 위해 먼저 docker 이미지의 정보를 살펴보도록 하자.

먼저 CMD 이미지 이다.

[root@godnr dockertest]# docker inspect cmdtest
[
    {
        "Id": "sha256:65c460fbf8bb89f3d9f50b5933d981d6ff5b26a6cdca338fffa81a89514326f0",
        "RepoTags": [
            "cmdtest:latest"
        ],
        "RepoDigests": [],
        "Parent": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
        "Comment": "",
        "Created": "2020-07-03T23:14:47.317513436Z",
        "Container": "1284f78d35f1893cede952ff0e39f3d72a0599c4d3a146863b4aebd9426f90ee",
        "ContainerConfig": {
            "Hostname": "1284f78d35f1",
            "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": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/df\" \"-h\"]"
            ],
            "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "DockerVersion": "19.03.6-ce",
        "Author": "",
        "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": [
                "/bin/df",
                "-h"
            ],
            "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 215320025,
        "VirtualSize": 215320025,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/merged",
                "UpperDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "WorkDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:eb29745b8228e1e97c01b1d5c2554a319c00a94d8dd5746a3904222ad65a13f8"
            ]
        },
        "Metadata": {
            "LastTagTime": "2020-07-03T23:14:47.331203166Z"
        }
    }
]
[root@godnr dockertest]#

위와 같이 이미지 inspect 정보를 확인해 보면,

...
"Cmd": [
	"/bin/df",
	"-h"
],
...
"Entrypoint": null,
...

Cmd에 /bin/df -h가 포함되고, Entrypoint에  null 값이 들어가 있는 것을 확인할 수 있다.

다음은 Entrypoint 이미지이다.

[root@godnr dockertest]# docker inspect entrytest
[
    {
        "Id": "sha256:ecf7f54d45dbe23ce23a091b0bb40fe057175e67971a630a076aa8705b410f05",
        "RepoTags": [
            "entrytest:latest"
        ],
        "RepoDigests": [],
        "Parent": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
        "Comment": "",
        "Created": "2020-07-03T23:15:03.960132719Z",
        "Container": "44520ba1bf9cdb6009d9d56e78b413f065d6169b5882ac82de3e2a03317ba28f",
        "ContainerConfig": {
            "Hostname": "44520ba1bf9c",
            "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": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "ENTRYPOINT [\"/bin/df\" \"-h\"]"
            ],
            "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/df",
                "-h"
            ],
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "DockerVersion": "19.03.6-ce",
        "Author": "",
        "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:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/df",
                "-h"
            ],
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 215320025,
        "VirtualSize": 215320025,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/merged",
                "UpperDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "WorkDir": "/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:eb29745b8228e1e97c01b1d5c2554a319c00a94d8dd5746a3904222ad65a13f8"
            ]
        },
        "Metadata": {
            "LastTagTime": "2020-07-03T23:15:03.971469696Z"
        }
    }
]
[root@godnr dockertest]#

위와 같이 이미지 정보를 확인해보면,

...
"Cmd": null,
...
"Entrypoint": [
	"/bin/df",
	"-h"
],
...

Entrypoint에 /bin/df -h가 실행되도록 구성하며, CMD는 null이 입력되어 있다.

현재를 기반으로 다음과 같이 테스트를 진행해보자.

[root@godnr dockertest]# docker run -it --name cmd2 cmdtest ps -afx
  PID TTY      STAT   TIME COMMAND
    1 pts/0    Rs+    0:00 ps -afx
[root@godnr dockertest]# docker run -it --name entry2 entrytest ps -afx
df: invalid option -- 'f'
Try 'df --help' for more information.
[root@godnr dockertest]#

[cmd2] container를 실행하는 인자 값으로 ps -afx를 입력할 경우 기존 df -h가 대체되어 실행된다.

[entry2] container를 실행하는 인자 값으로 ps -afx를 입력할 경우 기존 df -h + ps -afx가 하나의 명령어로 실행된다.

실행된 컨테이너의 inspect 정보를 기반으로 다시 확인해 보도록 하자.먼저 cmd2 컨테이너이다.

[root@godnr dockertest]# docker inspect cmd2
[
    {
        "Id": "1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46",
        "Created": "2020-07-03T23:31:16.747289932Z",
        "Path": "ps",
        "Args": [
            "-afx"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-07-03T23:31:17.21377781Z",
            "FinishedAt": "2020-07-03T23:31:17.220454216Z"
        },
        "Image": "sha256:65c460fbf8bb89f3d9f50b5933d981d6ff5b26a6cdca338fffa81a89514326f0",
        "ResolvConfPath": "/var/lib/docker/containers/1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46/hostname",
        "HostsPath": "/var/lib/docker/containers/1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46/hosts",
        "LogPath": "/var/lib/docker/containers/1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46/1412663eb5997f7ea50bdb8aa31b6ea82209090f8306e9a20f85cd0da1dc4a46-json.log",
        "Name": "/cmd2",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [
                {
                    "Name": "nofile",
                    "Hard": 4096,
                    "Soft": 1024
                }
            ],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/c529accd317ed2914f68cfecd10b312e9d41bc55137cf91647be3083cd553faf-init/diff:/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "MergedDir": "/var/lib/docker/overlay2/c529accd317ed2914f68cfecd10b312e9d41bc55137cf91647be3083cd553faf/merged",
                "UpperDir": "/var/lib/docker/overlay2/c529accd317ed2914f68cfecd10b312e9d41bc55137cf91647be3083cd553faf/diff",
                "WorkDir": "/var/lib/docker/overlay2/c529accd317ed2914f68cfecd10b312e9d41bc55137cf91647be3083cd553faf/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "1412663eb599",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "ps",
                "-afx"
            ],
            "Image": "cmdtest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "ac9a1b60fee2f556584cbfd7007cac46fdff46636763fa325f22f7d7f3b4255a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/ac9a1b60fee2",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "708a1380fb31505561224f16611dacc5ad6d86db4ec8afdae78b5258cd26d4c6",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@godnr dockertest]#

이를 확인해보면 다음과 같이 cmd가 변경되는 것을 확인할 수 있다.

"Cmd": [
	"ps",
	"-afx"
],

다음으로 entry2이다.

[root@godnr dockertest]# docker inspect entry2
[
    {
        "Id": "3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61",
        "Created": "2020-07-03T23:31:30.217981923Z",
        "Path": "/bin/df",
        "Args": [
            "-h",
            "ps",
            "-afx"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 1,
            "Error": "",
            "StartedAt": "2020-07-03T23:31:30.693548782Z",
            "FinishedAt": "2020-07-03T23:31:30.693005909Z"
        },
        "Image": "sha256:ecf7f54d45dbe23ce23a091b0bb40fe057175e67971a630a076aa8705b410f05",
        "ResolvConfPath": "/var/lib/docker/containers/3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61/hostname",
        "HostsPath": "/var/lib/docker/containers/3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61/hosts",
        "LogPath": "/var/lib/docker/containers/3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61/3762fc78c674881aa98c570722ed3240dc72565a4962450f8fa765235f5bfb61-json.log",
        "Name": "/entry2",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [
                {
                    "Name": "nofile",
                    "Hard": 4096,
                    "Soft": 1024
                }
            ],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e9c5d8832b16061023dc465c505847bafc8eb33abd7f54a5f0bb1548c31620eb-init/diff:/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "MergedDir": "/var/lib/docker/overlay2/e9c5d8832b16061023dc465c505847bafc8eb33abd7f54a5f0bb1548c31620eb/merged",
                "UpperDir": "/var/lib/docker/overlay2/e9c5d8832b16061023dc465c505847bafc8eb33abd7f54a5f0bb1548c31620eb/diff",
                "WorkDir": "/var/lib/docker/overlay2/e9c5d8832b16061023dc465c505847bafc8eb33abd7f54a5f0bb1548c31620eb/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "3762fc78c674",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "ps",
                "-afx"
            ],
            "Image": "entrytest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/df",
                "-h"
            ],
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "5f3aadb0c2a5ac5578d1f21acb3d6c654b217cb496e864578126f9ace95670bf",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/5f3aadb0c2a5",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "708a1380fb31505561224f16611dacc5ad6d86db4ec8afdae78b5258cd26d4c6",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@godnr dockertest]#

역시 cmd와 entry point를 확인해 보면, 다음과 같다.

...
	    "Cmd": [
                "ps",
                "-afx"
            ],
...
            "Entrypoint": [
                "/bin/df",
                "-h"
            ],
...

위와 같이 entrypoint는 그대로 유지되고 cmd null 값이 ps -afx로 변경된 것을 알 수 있다.

대체로 위와 같이 동작하며, CMD의 경우 파라미터로 인해 CMD가 대체되지만, ENTRYPOINT는 유지되고 CMD PARAMETER로 붙은 값이 뒤 인자로 처리되는 것을 확인할 수 있다.즉 ENTRYPOINT는 항상 유지되어야 하는 값이 있을 경우 ENTRYPOINT로 정의하고 CMD는 변경되는 값에 대한 파라미터로 활용하는 것이 좋다.

이는 다음과 같은 조합으로도 사용될 수 있다.

[root@godnr dockertest]# cat Dockerfile_CMDENTRY
FROM centos:latest
ENTRYPOINT ["/bin/df"]
CMD ["-h"]
[root@godnr dockertest]#

위와 같이 ENTRYPOINT와 CMD를 함께 정의할 경우 다음과 같이 Docker Container의 Init Process가 실행된다.

[ENTRYPOINT] [CMD]

위와 같이 Dockerfile을 정의하면 기본 df를 실행하는 컨테이너 프로세스가 생성되고 default 옵션으로 -h를 사용할 수 있다. Container 기동 시점에 뒤에 옵션을 넣어주면 CMD에 대체되는 옵션이 추가된다.

먼저 도커 이미지 생성 및 기동해보도록 하자.

[root@godnr dockertest]# docker build -t cmdentrytest -f Dockerfile_CMDENTRY .
Sending build context to Docker daemon  17.92kB
Step 1/3 : FROM centos:latest
 ---> 831691599b88
Step 2/3 : ENTRYPOINT ["/bin/df"]
 ---> Running in a15f2e40f773
Removing intermediate container a15f2e40f773
 ---> 1000e90a0920
Step 3/3 : CMD ["-h"]
 ---> Running in df32b1fbfee0
Removing intermediate container df32b1fbfee0
 ---> 44b528aeb55d
Successfully built 44b528aeb55d
Successfully tagged cmdentrytest:latest
[root@godnr dockertest]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
cmdentrytest        latest              44b528aeb55d        2 minutes ago       215MB
entrytest           latest              ecf7f54d45db        4 hours ago         215MB
cmdtest             latest              65c460fbf8bb        4 hours ago         215MB
copytest            latest              1f0d5e824523        5 hours ago         215MB
addtest             latest              cd192ca2b06c        5 hours ago         215MB
centos              latest              831691599b88        2 weeks ago         215MB
[root@godnr dockertest]# docker run -it --name cmdentry cmdentrytest
Filesystem      Size  Used Avail Use% Mounted on
overlay          32G  1.8G   31G   6% /
tmpfs            64M     0   64M   0% /dev
tmpfs           492M     0  492M   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/xvda1       32G  1.8G   31G   6% /etc/hosts
tmpfs           492M     0  492M   0% /proc/acpi
tmpfs           492M     0  492M   0% /proc/scsi
tmpfs           492M     0  492M   0% /sys/firmware
[root@godnr dockertest]#

위와같이 df -h 명령어로 실행된다.

[root@godnr dockertest]# docker inspect cmdentry
[
    {
        "Id": "42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515",
        "Created": "2020-07-04T02:59:38.711632806Z",
        "Path": "/bin/df",
        "Args": [
            "-h"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-07-04T02:59:39.185955077Z",
            "FinishedAt": "2020-07-04T02:59:39.185412247Z"
        },
        "Image": "sha256:44b528aeb55d18ed1e96192960b5218704f28b7d9c6b5c2f7d0986f7f22619ac",
        "ResolvConfPath": "/var/lib/docker/containers/42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515/hostname",
        "HostsPath": "/var/lib/docker/containers/42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515/hosts",
        "LogPath": "/var/lib/docker/containers/42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515/42b3d76e34a447adbedbb0a2dcdcf5d0c5acdcf34d604d1ceedfdad6a7c92515-json.log",
        "Name": "/cmdentry",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [
                {
                    "Name": "nofile",
                    "Hard": 4096,
                    "Soft": 1024
                }
            ],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/c1fb31e2bd11d940aa593adb54c4863d3b7b66ec769ade250d1542d59ad8e593-init/diff:/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "MergedDir": "/var/lib/docker/overlay2/c1fb31e2bd11d940aa593adb54c4863d3b7b66ec769ade250d1542d59ad8e593/merged",
                "UpperDir": "/var/lib/docker/overlay2/c1fb31e2bd11d940aa593adb54c4863d3b7b66ec769ade250d1542d59ad8e593/diff",
                "WorkDir": "/var/lib/docker/overlay2/c1fb31e2bd11d940aa593adb54c4863d3b7b66ec769ade250d1542d59ad8e593/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "42b3d76e34a4",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "-h"
            ],
            "Image": "cmdentrytest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/df"
            ],
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "43c189573ddd8bab376610e53b84f78b10f8c474f2c0d931f10a0a01fb24071f",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/43c189573ddd",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "708a1380fb31505561224f16611dacc5ad6d86db4ec8afdae78b5258cd26d4c6",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@godnr dockertest]#

docker inspect 정보를 확인해 보면 다음과 같이

...
"Cmd": [
	"-h"
],
"Entrypoint": [
	"/bin/df"
],
...

다음과 같이 조합되는 것을 알 수 있다.

이제 다음과 같이 CMD를 변경하여 실행해 보도록 하자.

[root@godnr dockertest]# docker run -it --name cmdentry2 cmdentrytest -a
Filesystem     1K-blocks    Used Available Use% Mounted on
overlay         33542124 1864396  31677728   6% /
proc                   0       0         0    - /proc
tmpfs              65536       0     65536   0% /dev
devpts                 0       0         0    - /dev/pts
sysfs                  0       0         0    - /sys
tmpfs             503472       0    503472   0% /sys/fs/cgroup
cgroup                 0       0         0    - /sys/fs/cgroup/systemd
cgroup                 0       0         0    - /sys/fs/cgroup/cpu,cpuacct
cgroup                 0       0         0    - /sys/fs/cgroup/blkio
cgroup                 0       0         0    - /sys/fs/cgroup/freezer
cgroup                 0       0         0    - /sys/fs/cgroup/cpuset
cgroup                 0       0         0    - /sys/fs/cgroup/net_cls,net_prio
cgroup                 0       0         0    - /sys/fs/cgroup/memory
cgroup                 0       0         0    - /sys/fs/cgroup/hugetlb
cgroup                 0       0         0    - /sys/fs/cgroup/pids
cgroup                 0       0         0    - /sys/fs/cgroup/perf_event
cgroup                 0       0         0    - /sys/fs/cgroup/devices
mqueue                 0       0         0    - /dev/mqueue
shm                65536       0     65536   0% /dev/shm
/dev/xvda1      33542124 1864396  31677728   6% /etc/resolv.conf
/dev/xvda1      33542124 1864396  31677728   6% /etc/hostname
/dev/xvda1      33542124 1864396  31677728   6% /etc/hosts
devpts                 0       0         0    - /dev/console
proc                   0       0         0    - /proc/bus
proc                   0       0         0    - /proc/fs
proc                   0       0         0    - /proc/irq
proc                   0       0         0    - /proc/sys
proc                   0       0         0    - /proc/sysrq-trigger
tmpfs             503472       0    503472   0% /proc/acpi
tmpfs              65536       0     65536   0% /proc/kcore
tmpfs              65536       0     65536   0% /proc/keys
tmpfs              65536       0     65536   0% /proc/latency_stats
tmpfs              65536       0     65536   0% /proc/timer_list
tmpfs              65536       0     65536   0% /proc/sched_debug
tmpfs             503472       0    503472   0% /proc/scsi
tmpfs             503472       0    503472   0% /sys/firmware
[root@godnr dockertest]#

다음과 같이 df -a 명령어의 조합으로 실행되어 기존과 다른 결과를 확인할 수 있다.

다음과 같이 inspect 정보를 다시확인해 보자.

[root@godnr dockertest]# docker inspect cmdentry2
[
    {
        "Id": "e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da",
        "Created": "2020-07-04T04:15:38.403004525Z",
        "Path": "/bin/df",
        "Args": [
            "-a"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-07-04T04:15:38.881820166Z",
            "FinishedAt": "2020-07-04T04:15:38.881304483Z"
        },
        "Image": "sha256:44b528aeb55d18ed1e96192960b5218704f28b7d9c6b5c2f7d0986f7f22619ac",
        "ResolvConfPath": "/var/lib/docker/containers/e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da/hostname",
        "HostsPath": "/var/lib/docker/containers/e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da/hosts",
        "LogPath": "/var/lib/docker/containers/e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da/e12f124ad107bee68d1156fca3aec2a7dd8c5807606d055262f0b336010643da-json.log",
        "Name": "/cmdentry2",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [
                {
                    "Name": "nofile",
                    "Hard": 4096,
                    "Soft": 1024
                }
            ],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/6187852364c07affa63fbe1b9fbe8f1b922866dd38bf5d5ba15e51e573824fc0-init/diff:/var/lib/docker/overlay2/83f0f7da21017064734ecd3505187344a7b17090f11e8c8dca87125c1a7254e1/diff",
                "MergedDir": "/var/lib/docker/overlay2/6187852364c07affa63fbe1b9fbe8f1b922866dd38bf5d5ba15e51e573824fc0/merged",
                "UpperDir": "/var/lib/docker/overlay2/6187852364c07affa63fbe1b9fbe8f1b922866dd38bf5d5ba15e51e573824fc0/diff",
                "WorkDir": "/var/lib/docker/overlay2/6187852364c07affa63fbe1b9fbe8f1b922866dd38bf5d5ba15e51e573824fc0/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "e12f124ad107",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "-a"
            ],
            "Image": "cmdentrytest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/df"
            ],
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "e076f04a01cb88cd1b53a4ade34fd2f2ab8fc05b348668db15a63c3b559ab49f",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/e076f04a01cb",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "708a1380fb31505561224f16611dacc5ad6d86db4ec8afdae78b5258cd26d4c6",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@godnr dockertest]#

다음과 같이 -h를 대체하는 -a로 실행되는 것을 알 수 있다.

...
"Cmd": [
	"-a"
],
"Entrypoint": [
	"/bin/df"
],
...

위와 같이 CMD에 정의한 파라미터를 Optional하게 가져가야 할 경우 CMD와 ENTRYPOINT의 조합으로 활용할 수 있다.

즉 컨테이너가 실행되는 가운데 INIT Process로 기동되는 명령어는 다음과 같은 조합으로 실행된다.

1) ENTRYPOINT CMD

2) ENTRYPOINT run_command_parameter(cmd)

3) CMD

1번의 경우 Dockerfile에 정의한 ENTRYPOINT + CMD(Default)로 동작하며, run_command에 cmd parameter가 포함될 경우 default CMD에 대체되어 실행된다. 마지막 ENTRYPOINT 없이 CMD만으로 실행된다.

이를 적절히 조합하여 컨테이너를 구성하는 것은 실행/유지보수 관점에서 중요한 포인트가 될 것이다.

ARG vs ENV

마지막으로 살펴볼 ARG와 ENV는 파라미터를 설정하는 옵션이다.

[ARG] 이미지 빌드 타임에 사용되는 환경 변수이며 docker build 시 --build-arg 옵션을 사용하여 덮어쓸 수 있다.

[ENV] 이미지가 실행되는 Runtime 즉 OS의 export 환경 변수로써 동작한다. docker run 시 --e 옵션을 사용하여 변수를 전달 할 수 있다.

[root@godnr dockertest]# cat Dockerfile_ARG
FROM centos:latest
ARG cmdtest=test
RUN echo $cmdtest
CMD env | grep cmdtest
[root@godnr dockertest]# cat Dockerfile_ENV
FROM centos:latest
ENV cmdtest=test
RUN echo $cmdtest
CMD env | grep cmdtest
[root@godnr dockertest]#

해당 Dockerfile을 기반으로 Docker image를 생성하고 기동하면 다음과 같이 동작한다.

[root@godnr dockertest]# docker build -t argtest -f Dockerfile_ARG .
Sending build context to Docker daemon  19.97kB
Step 1/4 : FROM centos:latest
 ---> 831691599b88
Step 2/4 : ARG cmdtest=test
 ---> Running in 5503e772da14
Removing intermediate container 5503e772da14
 ---> 537ed144efd8
Step 3/4 : RUN echo $cmdtest
 ---> Running in cc8d462225b6
test
Removing intermediate container cc8d462225b6
 ---> 98877637475b
Step 4/4 : CMD env | grep cmdtest
 ---> Running in 5c2b691aaa72
Removing intermediate container 5c2b691aaa72
 ---> 40c19d3f338a
Successfully built 40c19d3f338a
Successfully tagged argtest:latest
[root@godnr dockertest]# docker build -t envtest -f Dockerfile_ENV .
Sending build context to Docker daemon  19.97kB
Step 1/4 : FROM centos:latest
 ---> 831691599b88
Step 2/4 : ENV cmdtest=test
 ---> Running in c1a6bdadae9f
Removing intermediate container c1a6bdadae9f
 ---> 8d5a13b305be
Step 3/4 : RUN echo $cmdtest
 ---> Running in 9dcd3cc1ea93
test
Removing intermediate container 9dcd3cc1ea93
 ---> 71b6bc0d2e05
Step 4/4 : CMD env | grep cmdtest
 ---> Running in 5d87a52fe74e
Removing intermediate container 5d87a52fe74e
 ---> dbb3d31057e9
Successfully built dbb3d31057e9
Successfully tagged envtest:latest
[root@godnr dockertest]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
envtest             latest              dbb3d31057e9        3 seconds ago       215MB
argtest             latest              40c19d3f338a        2 minutes ago       215MB
cmdentrytest        latest              44b528aeb55d        4 hours ago         215MB
entrytest           latest              ecf7f54d45db        8 hours ago         215MB
cmdtest             latest              65c460fbf8bb        8 hours ago         215MB
copytest            latest              1f0d5e824523        9 hours ago         215MB
addtest             latest              cd192ca2b06c        9 hours ago         215MB
centos              latest              831691599b88        2 weeks ago         215MB
[root@godnr dockertest]# docker run -it --name arg argtest
[root@godnr dockertest]# docker run -it --name env envtest
cmdtest=test
[root@godnr dockertest]#

env | grep cmdtest를 통해 컨테이너 내부 local 환경 변수로 지정되었는지 여부를 확인한다.

위 결과와 같이 ARG는 컨테이너 내부에 지정되지 않았으며, ENV는 환경변수로 지정되어 있다.

이와 같이 ARG는 일반적으로 빌드 시점에 사용하고 ENV는 기동 후 컨테이너 내부 환경 변수로 사용된다.

두 환경변수는 함께 사용할 수 있으며, 일반적으로 다음과 같이 사용된다.

[root@godnr dockertest]# cat Dockerfile_ARGENV
FROM centos:latest
ARG SPRING_PROFILES
ENV SPRING_PROFILE=$SPRING_PROFILE
RUN echo $SPRING_PROFILE
CMD env | grep SPRING_PROFILE
[root@godnr dockertest]#

위 Dockerfile은 ARG를 통해 빌드 시점에 Spring Profiles를 지정하고, 실행 시점에 ENV를 통해 환경변수로 정의하여 실제 런타임에 사용하는 방식이다.

[root@godnr dockertest]# docker run -it --name argenv argenvtest
SPRING_PROFILES=
[root@godnr dockertest]#
[root@godnr dockertest]# docker build --build-arg SPRING_PROFILES=dev -t argenvtest_dev -f Dockerfile_ARGENV .
Sending build context to Docker daemon  20.99kB
Step 1/5 : FROM centos:latest
 ---> 831691599b88
Step 2/5 : ARG SPRING_PROFILES
 ---> Using cache
 ---> fe39b00bf80d
Step 3/5 : ENV SPRING_PROFILES=$SPRING_PROFILES
 ---> Running in 05b43b45556e
Removing intermediate container 05b43b45556e
 ---> 68061fa8bea1
Step 4/5 : RUN echo $SPRING_PROFILES
 ---> Running in ff68b59d6f0a
dev
Removing intermediate container ff68b59d6f0a
 ---> fbd7ae44c8a4
Step 5/5 : CMD env | grep SPRING_PROFILE
 ---> Running in 9b75f4f14abd
Removing intermediate container 9b75f4f14abd
 ---> f5b200a1f887
Successfully built f5b200a1f887
Successfully tagged argenvtest_dev:latest
[root@godnr dockertest]# docker run -it --name argenv_dev argenvtest_dev
SPRING_PROFILES=dev
[root@godnr dockertest]#

위와 같이 docker run을 실행해 보면 SPRING_PROFILES 환경 변수가 RUNTIME 환경에 구성되어 있지만, ARG Default 값이 없어 빈 값으로 구성되어 있다. 해당 환경 변수를 빌드 시점에 구성하기 위해 --build-arg 옵션을 기반으로 SPRING_PROFILES=dev을 설정하고 다시 docker run을 실행하면 환경 변수에 SPRING_PROFILES=dev가 구성되는 것을 확인할 수 있다.

이와 같이 도커 이미지는 동일하게 구성하고, 개별 환경 변수만 다르게 구성하여 각 환경에 맞게 활용 할 수 있다.

728x90
반응형