>  기사  >  운영 및 유지보수  >  Docker를 이용한 계층적 재사용 아이디어를 10분만에 배울 수 있습니다

Docker를 이용한 계층적 재사용 아이디어를 10분만에 배울 수 있습니다

WBOY
WBOY앞으로
2022-01-19 17:37:322528검색

이 기사는 이미지 레이어링, 컨테이너 레이어링 및 Docker에서 컨테이너가 차지하는 디스크 공간과 관련된 몇 가지 문제를 소개합니다.

Docker를 이용한 계층적 재사용 아이디어를 10분만에 배울 수 있습니다

Docker가 스토리지를 구성하는 방법

dokcer는 스토리지 콘텐츠를 구성할 때 계층적 재사용 아이디어를 영리하게 적용합니다. 그래서 우리는 이것을 이 아이디어를 배우기 위한 사례로 사용할 수 있습니다.

1. 이미지 레이어링

Docker 이미지는 생성 과정에서 여러 레이어로 나뉘며, 각 레이어는 읽기 전용입니다. 다음 예를 들어 설명하겠습니다.

# syntax=docker/dockerfile:1
FROM ubuntu:18.04
LABEL org.opencontainers.image.authors="org@example.com"
COPY . /app
RUN make /app
RUN rm -r $HOME/.cache
CMD python /app/app.py

이 Dockerfile에는 파일 시스템을 변경하고 새 레이어를 생성하는 4가지 지침이 있습니다.

  • FROM 명령은 ubuntu:18.04 이미지에서 기본 레이어를 생성합니다.
  • FROM指令从ubuntu:18.04的镜像中创建了基础层。
  • LABEL指令仅仅修改了镜像的元数据,不会创建新层。
  • COPY指令将执行本次构建的当前目录中的内容添加到镜像当中,会创建一个新层记录改变。
  • 第一个RUN指令,构建了程序并将结果输出到镜像中,会创建一个新层记录改变。
  • 第二个RUN指令,删除了缓存目录,会创建一个新层记录改变。
  • CMD指令定义了容器中运行的指令,只是修改了镜像的元数据,并不会创建新层。

这里每层都只记录与其上一层的不同。当我们创建一个容器的时候,这是就会创建一层可写层,也叫容器层。对于正在运行中的容器的内容的变化都会记录在该层中。下图描述了该关系:

2.容器分层

容器和镜像的不同主要是最顶层的可写层的不同,所有对于容器的写操作都会记录在这层中,如果容器被删除,那么这个可写层也会被删除,但是镜像会被保留。

注意:如果想要多个容器共享相同的数据,可以通过Docker Volumes实现。

每个容器都有其自己的可写层,所有的变换都会被存放在其中,所以多个容器可共享同一个镜像。下图描述了该关系:

注意 :此处还有个细节,多个镜像可能共用相同的层,比如两个镜像中有相同的层,那么在构建或是拉取的时候发现本地以存在,则不会再次构建或拉取。所以计算镜像大小的时候,不能仅通过 docker images命令显示出的大小来汇总求和,该值有可能大于实际值。

3.容器在磁盘占用的空间

可以通过 docker ps -s命令,来看正在运行中的容器占用的空间(部分值)。两个列的不同代表的内容:

  • size: 容器的可写层占用的磁盘大小
  • virtual size: 包含了容器可写层和只读镜像的大小。

容器占用磁盘空间的其它途径:

  • 容器产生的日志文件。
  • 使用Volume和bind mounts挂载的内容。
  • 容器的配置文件
  • 内存中的内容(如果开启了swapping)
  • Checkpoints(如果使用了该功能)

4.Copy-on-Write(CoW)策略

Docker中的存储驱动都是采用该策略。

CoW策略能够最大效率的共享和复制文件。如果一个文件在镜像的更低层存在,那么其上层(包括可写层)需要读取该内容则可以直接使用该文件。当需要对其进行修改时,会复制该文件到该层并进行修改。这最大限度的减少了IO和每个后续层的大小。

4.1共享使镜像更小

当我们使用 docker pull拉取镜像或是使用一个本地没有的镜像创建容器的时候,该镜像会被分层的存储到本地Dockers存储区域中。在linux中通常是 /var/lib/docker

我们可以去 /var/lib/docker/<storage-driver></storage-driver>目录下看我们已拉取各层镜像。比如使用 overlay2存储驱动。

这么多层,我们可以通过 docker image inspectLABEL이 명령은 이미지의 메타데이터만 수정하고 새 레이어를 생성하지는 않습니다.

COPY 이 명령은 이 빌드가 실행되는 현재 디렉터리의 내용을 이미지에 추가하고 변경 사항을 기록하기 위한 새 레이어를 생성합니다.

첫 번째 RUN 명령은 프로그램을 빌드하고 결과를 이미지에 출력합니다. 변경 사항을 기록하기 위한 새 레이어가 생성됩니다. Docker를 이용한 계층적 재사용 아이디어를 10분만에 배울 수 있습니다두 번째 RUN 명령은 캐시 디렉터리를 삭제하고 변경 사항을 기록할 새 레이어를 만듭니다.

CMD 명령은 컨테이너에서 실행될 명령을 정의하며 이미지의 메타데이터만 수정하고 새 레이어를 생성하지는 않습니다.

여기서 각 레이어는 이전 레이어와의 차이점만 기록합니다. 컨테이너를 생성하면 쓰기 가능한 레이어(컨테이너 레이어라고도 함)가 생성됩니다. 실행 중인 컨테이너의 내용에 대한 변경 사항이 이 레이어에 기록됩니다. 다음 그림은 관계를 설명합니다.

🎜2 .컨테이너 레이어링🎜🎜🎜컨테이너와 이미지의 주요 차이점은 쓰기 가능한 최상위 레이어입니다. 컨테이너에 대한 모든 쓰기 작업은 이 레이어에 기록되지만, 쓰기 가능한 레이어도 삭제됩니다. 이미지가 유지됩니다. 🎜🎜🎜Note🎜: 여러 컨테이너가 동일한 데이터를 공유하도록 하려면 Docker 볼륨을 통해 이를 수행할 수 있습니다. 🎜🎜각 컨테이너에는 모든 변환이 저장되는 쓰기 가능한 자체 레이어가 있으므로 여러 컨테이너가 동일한 이미지를 공유할 수 있습니다. 다음 그림은 관계를 설명합니다. 🎜🎜🎜🎜🎜참고 🎜: 여기에 또 다른 세부 사항이 있습니다. 여러 이미지가 동일한 레이어를 공유할 수 있습니다. 예를 들어 두 이미지가 동일한 레이어를 가지고 있는 경우 빌드하거나 끌어올 때 로컬로 존재하는 것으로 확인되면 다시 빌드되거나 당겨지지 않습니다. 따라서 이미지 크기를 계산할 때 docker Images 명령으로 표시되는 크기를 단순히 합산할 수는 없으며, 실제 값보다 더 클 수 있습니다. 🎜🎜🎜3. 디스크에서 컨테이너가 차지하는 공간🎜🎜🎜 docker ps -s 명령을 사용하면 실행 중인 컨테이너가 차지하는 공간을 확인할 수 있습니다(부분 값). 두 열로 표시되는 다양한 콘텐츠: 🎜🎜🎜size: 컨테이너의 쓰기 가능한 레이어가 차지하는 디스크 크기 🎜virtual size: 컨테이너의 쓰기 가능한 레이어와 읽기 전용 이미지의 크기를 포함합니다. 🎜컨테이너가 디스크 공간을 차지하는 다른 방법: 🎜🎜🎜컨테이너에 의해 생성된 로그 파일. 🎜볼륨 및 바인드 마운트를 사용하여 콘텐츠를 마운트했습니다. 🎜컨테이너 구성 파일🎜메모리의 콘텐츠(스와핑이 활성화된 경우)🎜체크포인트(이 기능이 사용되는 경우)🎜🎜4.Copy -on -쓰기(CoW) 전략 🎜🎜🎜Docker의 스토리지 드라이버는 모두 이 전략을 채택합니다. 🎜🎜CoW 전략은 최대의 효율성으로 파일을 공유하고 복사할 수 있습니다. 이미지의 하위 레이어에 파일이 있는 경우 상위 레이어(쓰기 가능한 레이어 포함)는 콘텐츠를 읽어야 하며 파일을 직접 사용할 수 있습니다. 수정이 필요한 경우 파일이 이 레이어에 복사되어 수정됩니다. 이렇게 하면 IO와 각 후속 레이어의 크기가 최소화됩니다. 🎜

🎜4.1 공유로 인해 이미지가 작아집니다🎜

🎜 docker pull을 사용하여 이미지를 가져오거나 로컬에서 사용할 수 없는 이미지를 사용하여 컨테이너를 생성하면 이미지는 분할 레이어는 로컬 Dockers 저장 영역에 저장됩니다. Linux에서는 일반적으로 /var/lib/docker입니다. 🎜🎜 /var/lib/docker/<storage-driver></storage-driver> 디렉토리로 이동하여 각 레이어의 이미지를 가져온 것을 확인할 수 있습니다. 예를 들어 overlay2 저장소 드라이버를 사용하세요. 🎜🎜🎜🎜레이어가 너무 많아서 통과할 수 있습니다docker image Inspection을 통해 특정 이미지에 어떤 레이어가 포함되어 있는지 확인하세요🎜
docker image inspect --format "{{json .RootFS.Layers}}" redis

docker image inspect --format "{{json .RootFS.Layers}}" mysql:5.7
🎜🎜🎜🎜🎜🎜🎜위 보기를 통해 redis와 mysql5.7이 동일한 레이어를 사용하므로 동일한 레이어를 공유하면 비용이 절약되는 것을 알 수 있습니다. 이미지를 저장하는 공간이 많아지면 이미지를 가져오는 속도도 빨라집니다. 🎜

我们可以通过 docker image history命令来查看镜像分层情况,以redis为例

docker history redis

注意 :

  • 有些步骤的大小为0,是因为他们只改变了元数据,并不会产生新层,也不会占用额外的空间(除元数据本身)。所以上述redis镜像中包含了5层。

  • <missing></missing>步骤,这些步骤可能是以下情况中的一种

    • 在另一个系统上构建的
    • 从Docker Hub中提取的
    • 使用BuildKit作为构建器构建的。

4.2复制让容器更有效率

当我们启动一个容器的时候,会添加一个可写层在镜像之上,用于存储所有的变化。当对已有文件进行修改的时候采用CoW策略。首先会到各层寻找到该文件,然后复制该文件到可写层,然后进行修改并存储。

这么做能够让我们最大限度地减少I/O操作。

但是,很明显的是当一个容器中的应用需要进行频繁的写操作,那么会造成可写层越来越庞大,此时我们可以通过Volume来帮助我们分担压力。

容器的元数据和日志是单独存放的,一般是存放在 /var/lib/docker/containers中,我们可以使用 du -sh /var/lib/docker/containers/*来查看各个容器占用多少。(容器ID其实就是文件夹名称的前12位)。

推荐学习:《docker视频教程

위 내용은 Docker를 이용한 계층적 재사용 아이디어를 10분만에 배울 수 있습니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제