본문 바로가기

클라우드/Docker

[docker] 기본개념 및 동작

 

 

 

[레이어정보]

 

 

docker history ubuntu:20.04
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
56c3ecf33e76   2 weeks ago     /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      2 weeks ago     /bin/sh -c apt-get update && apt-get install -y… 114MB    
<missing>      2 weeks ago     /bin/sh -c #(nop)  LABEL org.opencontainers.i… 0B        
<missing>      2 weeks ago     /bin/sh -c #(nop)  MAINTAINER Ubuntu Develop… 0B        
<missing>      2 weeks ago     /bin/sh -c #(nop)  FROM debian:stretch          0B

 

 

docker history 출력 설명

  • IMAGE: 레이어 ID나 이미지 ID입니다. 이미지 ID는 docker images 명령어로 확인할 수 있습니다.
  • CREATED: 레이어가 생성된 시간입니다.
  • CREATED BY: 해당 레이어를 생성하기 위해 실행된 명령입니다. 예를 들어, apt-get install이나 RUN 명령 등이 포함될 수 있습니다.
  • SIZE: 해당 레이어의 크기입니다. 이 값은 이 레이어가 차지하는 용량을 나타냅니다.
  • COMMENT: 해당 레이어에 대한 추가 설명이 있으면 표시됩니다.

출력 항목 설명

  1. IMAGE: 각 레이어의 ID 또는 이미지 ID를 표시합니다. 첫 번째 행에는 최상위 레이어가 표시되며, 가장 마지막 레이어(이미지의 시작)는 <missing>으로 표시될 수 있습니다. 이는 레이어의 정보가 이미지에서 삭제되었거나 확인할 수 없을 때 나타납니다.
  2. CREATED: 각 레이어가 언제 생성되었는지 시간 단위로 표시됩니다. ago 뒤에 나타나는 시간은 상대적인 시간(예: "2 weeks ago", "3 days ago")입니다.
  3. CREATED BY: 해당 레이어를 생성한 명령어를 나타냅니다. 예를 들어, RUN apt-get update 같은 명령어가 표시됩니다. 이는 Dockerfile에 정의된 각 단계의 명령을 보여줍니다.
  4. SIZE: 해당 레이어의 크기를 나타냅니다. 이 값은 레이어가 차지하는 디스크 공간을 기준으로 합니다.
  5. COMMENT: 이 항목은 보통 비어 있지만, 이미지에 추가된 설명이 있는 경우 여기에 표시됩니다. 주로 레이어가 생성된 이유나 주석이 포함될 수 있습니다.

docker history의 예시 분석

출력 예시:

  • 첫 번째 레이어 56c3ecf33e76는 CMD ["bash"] 명령을 실행하는 레이어로, 최상위 레이어입니다.
  • 두 번째 레이어는 apt-get update와 apt-get install 명령을 실행하여 114MB의 크기를 차지하는 패키지 설치 레이어입니다.
  • 세 번째, 네 번째, 다섯 번째 레이어는 각기 LABEL, MAINTAINER, FROM 명령으로, 각각 메타 데이터와 기반 이미지를 설정하는 단계입니다. 이들은 모두 크기가 0B입니다.

 

도커 레이어(Docker Layer) 개념 설명

도커에서 레이어(Layer)  이미지를 구성하는 각각의 수정된 상태를 의미합니다. 도커 이미지가 생성될 때, 여러 명령을 실행하면서 하나씩 쌓여가는 파일 시스템 덧셈 구조로 생각할 수 있습니다. 도커는 이러한 레이어들을 효율적으로 관리하고, 이미지의 중복된 부분을 최소화하여 디스크 공간을 절약할 수 있도록 설계되어 있습니다.

각 레이어는 불변(immutable) 하며, 한 번 생성된 레이어는 변경되지 않습니다. 대신, 새로운 명령어가 실행될 때마다 새로운 레이어가 생성됩니다. 레이어는 이전 레이어의 상태를 기반으로 하고, 새로운 변경 사항을 추가합니다.

도커 이미지와 레이어

  1. 이미지(Image): 도커 이미지는 여러 개의 레이어들이 결합된 결과물입니다. 도커 이미지는 읽기 전용이며, 여러 컨테이너들이 동일한 이미지를 기반으로 실행될 수 있습니다.
    • 예를 들어, ubuntu:20.04 이미지는 여러 레이어로 구성되어 있습니다. 베이스 이미지는 debian:stretch로 시작되고, 그 위에 다양한 명령어로 레이어가 추가됩니다.
  2. 레이어(Layer): 각 레이어는 도커 이미지 생성 시 RUN, COPY, ADD, ENV 등과 같은 명령어를 실행한 결과입니다. 각 레이어는 읽기 전용이며, 새로 생성된 레이어는 그 위에 변경된 내용을 추가합니다.
    • 첫 번째 레이어: 보통 기본 이미지(예: FROM ubuntu)에 해당하며, 이는 시스템의 기본적인 파일 시스템을 구성합니다.
    • 이후 레이어들: 사용자가 RUN apt-get install 등의 명령을 통해 소프트웨어를 설치하거나 파일을 복사하면 그에 따라 새로운 레이어가 추가됩니다.

레이어 구조의 예시

  1. 도커파일 예시 (Dockerfile):위의 도커파일을 기준으로 도커 이미지를 빌드하면, 다음과 같은 레이어가 생성됩니다:
    • 레이어 1: ubuntu:20.04 이미지를 기반으로 시작 (베이스 이미지)
    • 레이어 2: RUN apt-get update 명령어 실행으로 추가된 변경 사항
    • 레이어 3: RUN apt-get install -y vim 명령어 실행으로 vim 설치
    • 레이어 4: COPY myapp /usr/local/bin 명령어 실행으로 애플리케이션 파일 복사
  2. Dockerfile
    코드 복사
    FROM ubuntu:20.04 # 레이어 1: 베이스 이미지 (Ubuntu) RUN apt-get update # 레이어 2: apt-get update 실행 RUN apt-get install -y vim # 레이어 3: vim 패키지 설치 COPY myapp /usr/local/bin # 레이어 4: 애플리케이션 파일 복사

레이어의 특성

  1. 불변성 (Immutability):
    • 도커 레이어는 불변입니다. 즉, 한 번 생성된 레이어는 수정할 수 없습니다. 만약 RUN 명령어로 설치한 패키지를 삭제하거나 수정해야 한다면, 새로운 레이어를 만들어야 합니다.
    • 예를 들어, RUN apt-get install -y vim을 실행한 후 RUN apt-get remove -y vim을 실행해도, 실제로 vim을 삭제한 레이어는 새로운 레이어로 추가됩니다. 이전 레이어는 그대로 남아있고, 그 위에 새로운 레이어가 쌓입니다.
  2. 읽기 전용 (Read-Only):
    • 도커에서 각 레이어는 읽기 전용으로, 이미 생성된 레이어는 변경할 수 없습니다. 새로 생성된 레이어는 변경 사항만 포함되며, 이전 레이어를 변경하지 않습니다. 예를 들어, COPY 명령어로 파일을 복사하면 새로운 레이어가 생성되며, 이 레이어에는 복사된 파일만 포함됩니다.
  3. 효율적인 스토리지 관리:
    • 도커는 레이어를 효율적으로 관리하여 디스크 공간을 절약합니다. 동일한 이미지에서 여러 컨테이너가 생성될 때, 각 컨테이너는 해당 이미지의 레이어들을 공유합니다.
    • 예를 들어, 여러 개의 컨테이너가 같은 ubuntu 이미지를 사용하면, ubuntu 이미지는 한 번만 다운로드되고, 각 컨테이너는 이 레이어들을 공유하여 디스크 공간을 절약합니다.
  4. 레벨별 재사용:
    • 동일한 레이어가 여러 이미지에서 재사용될 수 있습니다. 만약 여러 이미지가 동일한 패키지를 설치하는 RUN apt-get install 명령을 포함하고 있다면, 해당 레이어는 여러 이미지에서 공유될 수 있습니다.

레이어의 장점과 단점

장점:

  1. 디스크 공간 절약:
    • 여러 이미지와 컨테이너들이 동일한 레이어를 공유함으로써 디스크 공간을 절약합니다.
  2. 빠른 빌드 시간:
    • 이미지가 변경된 레이어만 다시 빌드하므로, 전체 이미지를 다시 빌드하는 것보다 빠릅니다. 예를 들어, RUN 명령어가 포함된 레이어가 변경되면 그 레이어만 다시 빌드되고, 이전에 빌드된 레이어는 재사용됩니다.
  3. 캐싱을 통한 효율적인 이미지 빌드:
    • 도커는 이미지 빌드 시 각 레이어를 캐시하여, 이전에 빌드한 레이어를 재사용합니다. 예를 들어, RUN apt-get update와 같은 명령이 변경되지 않으면 해당 레이어는 캐시에서 가져와 재빌드하지 않습니다.

단점:

  1. 레이어가 많아지면 이미지 크기가 커질 수 있음:
    • 너무 많은 레이어가 추가되면 이미지의 크기가 불필요하게 커질 수 있습니다. 이 경우 이미지를 최적화하여 레이어 수를 줄여야 할 수 있습니다.
  2. 불필요한 파일이 포함될 수 있음:
    • 각 레이어는 이전 레이어의 상태를 기반으로 하므로, 불필요한 파일이나 캐시가 포함될 수 있습니다. 이럴 경우 이미지를 최적화하려면 불필요한 파일을 삭제하거나 캐시를 정리하는 작업이 필요합니다.

레이어 최적화 방법

  1. 명령어 결합:
    • 여러 개의 RUN 명령어를 하나로 결합하여 레이어 수를 줄입니다. 예를 들어, RUN apt-get update와 RUN apt-get install을 두 개의 명령어로 분리하는 대신, 하나의 RUN 명령어로 합쳐서 실행할 수 있습니다.
    Dockerfile
    코드 복사
    RUN apt-get update && apt-get install -y vim curl
  2. 불필요한 파일 제거:
    • 빌드 중에 생성된 불필요한 파일이나 캐시를 제거하여 이미지 크기를 줄일 수 있습니다. 예를 들어, 패키지 설치 후에 캐시를 삭제하는 명령어를 추가합니다.
    Dockerfile
    코드 복사
    RUN apt-get update && apt-get install -y vim && apt-get clean && rm -rf /var/lib/apt/lists/*
    • 다단계 빌드를 사용하여 불필요한 빌드 도구나 파일을 최종 이미지에서 제거할 수 있습니다. 첫 번째 단계에서 빌드에 필요한 모든 파일을 생성하고, 두 번째 단계에서 필요한 파일만을 복사해 최종 이미지를 생성하는 방법입니다.다단계 빌드 (Multi-stage build):
    코드 복사
# 빌드 단계
FROM node:14 AS builder
WORKDIR /app
COPY . .
RUN npm install

# 최종 이미지
FROM node:14
WORKDIR /app
COPY --from=builder /app .
CMD ["node", "index.js"]

결론

도커에서 이미지는 여러 개의 레이어가 쌓여서 만들어집니다. 각 레이어는 읽기 전용이고, 불변이며, 변경 사항만 추가되기 때문에 효율적으로 저장되고 공유됩니다. 레이어를 최적화하는 것은 이미지 크기를 줄이고 빌드 시간을 단축하는 데 중요한 역할을 합니다.

 

 

[mysql]의 히스토리를 보여줌

PS C:\docker> docker history mysql
IMAGE          CREATED       CREATED BY                                       SIZE      COMMENT
10db11fef9ce   4 weeks ago   CMD ["mysqld"]                                   0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   EXPOSE map[3306/tcp:{} 33060/tcp:{}]             0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   ENTRYPOINT ["docker-entrypoint.sh"]              0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   COPY docker-entrypoint.sh /usr/local/bin/ # …   13.8kB    buildkit.dockerfile.v0
<missing>      4 weeks ago   VOLUME [/var/lib/mysql]                          0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  microdnf install -…   328MB     buildkit.dockerfile.v0
<missing>      4 weeks ago   ENV MYSQL_SHELL_VERSION=9.1.0-1.el9              0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eu;  {   echo '[mysql-to…   226B      buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  microdnf install -…   142MB     buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eu;  {   echo '[mysqlinn…   246B      buildkit.dockerfile.v0
<missing>      4 weeks ago   ENV MYSQL_VERSION=9.1.0-1.el9                    0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   ENV MYSQL_MAJOR=innovation                       0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  key='BCA4 3417 C3B…   3.17kB    buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  microdnf install -…   16.5MB    buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  arch="$(uname -m)"…   2.36MB    buildkit.dockerfile.v0
<missing>      4 weeks ago   ENV GOSU_VERSION=1.17                            0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   RUN /bin/sh -c set -eux;  groupadd --system …   2.77kB    buildkit.dockerfile.v0
<missing>      4 weeks ago   CMD ["/bin/bash"]                                0B        buildkit.dockerfile.v0
<missing>      4 weeks ago   ADD oraclelinux-9-slim-amd64-rootfs.tar.xz /…   113MB     buildkit.dockerfile.v0

 

 

[nginx] pull

PS C:\docker> docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
2d429b9e73a6: Pull complete
9b1039c85176: Pull complete
9ad567d3b8a2: Pull complete
773c63cd62e4: Pull complete
1d2712910bdf: Pull complete
4b0adc47c460: Pull complete
171eebbdf235: Pull complete
Digest: sha256:bc5eac5eafc581aeda3008b4b1f07ebba230de2f27d47767129a6a905c84f470
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

tag 지정하지않으면 latest적용됨

 

PS C:\docker> docker history nginx
IMAGE          CREATED       CREATED BY                                       SIZE      COMMENT
60c8a892f36f   6 weeks ago   CMD ["nginx" "-g" "daemon off;"]                 0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   STOPSIGNAL SIGQUIT                               0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   EXPOSE map[80/tcp:{}]                            0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ENTRYPOINT ["/docker-entrypoint.sh"]             0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   COPY 30-tune-worker-processes.sh /docker-ent…   4.62kB    buildkit.dockerfile.v0
<missing>      6 weeks ago   COPY 20-envsubst-on-templates.sh /docker-ent…   3.02kB    buildkit.dockerfile.v0
<missing>      6 weeks ago   COPY 15-local-resolvers.envsh /docker-entryp…   389B      buildkit.dockerfile.v0
<missing>      6 weeks ago   COPY 10-listen-on-ipv6-by-default.sh /docker…   2.12kB    buildkit.dockerfile.v0
<missing>      6 weeks ago   COPY docker-entrypoint.sh / # buildkit           1.62kB    buildkit.dockerfile.v0
<missing>      6 weeks ago   RUN /bin/sh -c set -x     && groupadd --syst…   117MB     buildkit.dockerfile.v0
<missing>      6 weeks ago   ENV DYNPKG_RELEASE=1~bookworm                    0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ENV PKG_RELEASE=1~bookworm                       0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ENV NJS_RELEASE=1~bookworm                       0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ENV NJS_VERSION=0.8.6                            0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ENV NGINX_VERSION=1.27.2                         0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   LABEL maintainer=NGINX Docker Maintainers <d…   0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   CMD ["bash"]                                     0B        buildkit.dockerfile.v0
<missing>      6 weeks ago   ADD rootfs.tar.xz / # buildkit                   74.8MB    buildkit.dockerfile.v0

 

 

[nginx 레이어확인법]

> docker inspect nginx
[
    {
        "Id": "sha256:60c8a892f36faf6c9215464005ee6fb8cf0585f70b113c0b030f6cb497a41876",
        "RepoTags": [
            "nginx:latest"
        ],
        "RepoDigests": [
            "nginx@sha256:bc5eac5eafc581aeda3008b4b1f07ebba230de2f27d47767129a6a905c84f470"
        ],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
        "Created": "2024-10-02T17:55:35Z",
        "DockerVersion": "",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.27.2",
                "NJS_VERSION=0.8.6",
                "NJS_RELEASE=1~bookworm",
                "PKG_RELEASE=1~bookworm",
                "DYNPKG_RELEASE=1~bookworm"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "ArgsEscaped": true,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "/",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 191670156,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/21bd0c593a660f55ffb4ecd40700f8f50d3293e3b2fc50d388c82cb4bcd52457/diff:/var/lib/docker/overlay2/9c67d619aeab234d61dc189b19a5f533c653142a32ebf85d2521f4a66c1febe8/diff:/var/lib/docker/overlay2/2a70c46ce4fe8589f6e893130cbe8d7ce6e91c28ec6a6522e830a63cd5360404/diff:/var/lib/docker/overlay2/46ab166c56c2b897da7ec3335289439186568970e7366d85f0bef96e80ad7d52/diff:/var/lib/docker/overlay2/ccfab899d0521ed0f89b8000947ffdb179a5ad63f72534909846209e0faca488/diff:/var/lib/docker/overlay2/2230947cdc3d7a9e237e79faa1c80f54a32a79b2f48008930670c1b4255ea2b3/diff",
                "MergedDir": "/var/lib/docker/overlay2/ea3fe32c887f9e36d54d7d842ed39acc540bb212c3e69bee681304e165abf149/merged",
                "UpperDir": "/var/lib/docker/overlay2/ea3fe32c887f9e36d54d7d842ed39acc540bb212c3e69bee681304e165abf149/diff",
                "WorkDir": "/var/lib/docker/overlay2/ea3fe32c887f9e36d54d7d842ed39acc540bb212c3e69bee681304e165abf149/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:c3548211b8264f8bfa47a6727043a64f1791b82ac965a284a7ea187e971a95e2",
                "sha256:7dca41ff148690a71f3a18230b037c224699bddca66451edfc3e0875c38266a5",
                "sha256:ffe4285e29068b1a6112d99b633535058b91344bb1eac41cbec3c319c908cc43",
                "sha256:19b722697f76432e2991f3ddbfe83ff062c58cbc81ae86a209cc1a907281ed33",
                "sha256:a1fe8b721bb198a7416c45774b913499e3d32da7e49c36a173ab9eab1f16f651",
                "sha256:a0c145a29c8d0bd6496ca844601ea021aaeef71ab28a060cc9b4e3f0031d2eb6",
                "sha256:61ef4e878aac3937fc88785022b0a2b9b7791455b3a34b72eb5a77fd1bdbc7fd"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

 

반응형