요 며칠 간 docker-compose 로 redis 나 mysql container 생성하는 방법을 공유했습니다.
https://kimdubi.github.io/categories/docker/
이 과정에서 Docker Image 의 중요성에 대해 새삼 다시 느끼게 되어 정리하는 시간을 가지고자…
이번 글에서는 docker의 image 에 대해 소개하겠습니다.
Docker Image
Docker 에서 가장 중요한 두 축은 Container 와 Image 라고 생각합니다.
Docker Image는 container를 띄우는데 필요한 모든 파일이나 설정값들을 포함하고 있습니다.
잘하시는 분들께 “Docker가 왜 좋아요?” 라고 물으면 종종 “dependency 꼬일 일 없이 서비스 띄울 수 있으니까”
라는 굉장히 전문가 느낌의 이해하기 어려운 답변이 돌아올 때가 있는데
Container의 독립성 + Container를 띄우는데 필요한 모든 정보를 갖고 있는 Image
두가지가 합쳐지면 위의 답변과 같은 장점이 발휘되는 것이죠
이미 Docker Image에 모든 필요한 정보가 다 있으니 추가로 설치하고 컴파일할 것이 없고
추가로 한다쳐도 Container는 독립적이니 다른 Container에 영향을 끼칠 게 없다
=> “dependency 꼬일 일 없이 서비스를 띄울 수 있다”
kimdubi:~ kimdubi$ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5763 [OK]
ansible/centos7-ansible Ansible on Centos7 126 [OK]
jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 114 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 107 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 67
imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 57 [OK]
tutum/centos Simple CentOS docker image with SSH access 44
docker image는 docker hub 라는 곳에서 받아옵니다 (pull)
centos, mysql, nginx 등등 정말 다양한 image 가 있으니 필요한 것을 골라 쓰면 됩니다.
그런데 의문이 하나 생깁니다.
- 이렇게 image 가 많다면.. docker hub 는 그 수천만개의 image 를 어떻게 갖고 있는 것일까?
- DB 하나 띄울 때마다 Image를 새로 받아온다면 그 용량은 어떻게 감당하지?
여기에서 Docker 의 장점인 “레이어 저장방식” 이 등장합니다.
어떻게 저장 되는가
위 그림에서 각각의 이미지들은 아래와 같이 정리할 수 있습니다.
- ubuntu image = A + B + C
- nginx image = ubuntu image + nginx
- web_app image = nginx image + web app source
하나의 이미지 (ubuntu)는 여러개의 레이어로 구성 되고 (A+B+C)
무언가 파일이 추가되거나 수정되면 새로운 레이어(nginx) 가 생성되어 새로운 이미지 (nginx image)가 됩니다.
만약 기존에 web app image 를 사용하던 사람이 app source 부분만 수정된 wep_app 을 올려야한다면
A+B+C+ nginx + web app source_v2 모든 레이어를 다시 받아오는 게 아니라 web app source_v2 라는 새로운 레이어만 받아오면 되기 때문에 굉장히 효율적입니다.
Docker image layer 확인
기본 centos image로 centos, centos2, centos3 image 를 만들어 정말 layer 구성으로 되는지 확인해보겠습니다.
* centos image
* centos2 image = centos + a
* centos3 image = centos2 + b
- centos image 준비
kimdubi:~ kimdubi$ docker images | grep centos
centos latest 67fa590cfc1c 4 months ago 202MB
- centos container 생성
kimdubi:~ kimdubi$ docker run -d -it --name centos centos:latest
908a06abf004551684c784bf83579d93293cfc4f94e1c9978554621afd362b3d
kimdubi:~ kimdubi$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
908a06abf004 centos:latest "/bin/bash" 14 seconds ago Up 14 seconds centos
- 파일 추가 ( 새로운 layer 추가 )
kimdubi:~ kimdubi$ de 908 /bin/bash
[root@908a06abf004 /]# fallocate -l 2G layertest
[root@908a06abf004 /]# ls -ltr layertest
-rw-r--r-- 1 root root 2147483648 Jan 10 16:17 layertest
- 변경된 내용 commit 하여 새로운 centos2 image 생성
kimdubi:~ kimdubi$ docker commit centos centos2
sha256:505f52d32377641f5eccdce9ce28db8c00cbd623065420b250b4d418d4a1597c
kimdubi:~ kimdubi$ docker run -d -it --name centos2 centos2
f6895c211f404735b7ba5b1e2e32f44fc18e96d8ae6babe98e0f21785aa5461a
kimdubi:~ kimdubi$ de f689 /bin/bash
[root@f6895c211f40 /]# fallocate -l 2G layertest2
[root@f6895c211f40 /]# ls -ltr layertest2
-rw-r--r-- 1 root root 2147483648 Jan 10 16:19 layertest2
- centos3 Image 도 동일하게 생성
kimdubi:~ kimdubi$ docker commit centos2 centos3
sha256:9d82b922d5e7053aee3bed1628feb87dfaa020e552932bf11ca68de9d76b518c
kimdubi:~ kimdubi$ docker run -d -it --name centos3 centos3
10fd843d74e87444503e39d53fa6eb03585e0d83eee44a095c628dfffa4072f0
- 생성된 image 확인
kimdubi:~ kimdubi$ docker images | grep centos
centos3 latest 9d82b922d5e7 8 minutes ago 4.5GB
centos2 latest 505f52d32377 11 minutes ago 2.35GB
centos latest 67fa590cfc1c 4 months ago 202MB
- layer 확인
kimdubi:~ kimdubi$ docker inspect 9d82b922d5e7 | grep Parent
"Parent": "sha256:505f52d32377641f5eccdce9ce28db8c00cbd623065420b250b4d418d4a1597c",
kimdubi:~ kimdubi$ docker inspect 505f52d32377 | grep Parent
"Parent": "sha256:67fa590cfc1c207c30b837528373f819f6262c884b7e69118d060a0c04d70ab8",
=> centos3 의 parent 는 centos2, centos2의 parent는 centos 확인
kimdubi:~ kimdubi$ docker ps -s | grep centos
10fd843d74e8 centos3 "/bin/bash" 13 seconds ago Up 10 seconds centos3 0B (virtual 4.5GB)
f6895c211f40 centos2 "/bin/bash" 3 minutes ago Up 3 minutes centos2 2.15GB (virtual 4.5GB)
908a06abf004 centos:latest "/bin/bash" 5 minutes ago Up 5 minutes centos 2.15GB (virtual 2.35GB)
- centos 컨테이너의 경우 image 크기는 200MB + 생성한 파일 2.15GB
- centos2 컨테이너의 경우 centos container + 생성한 파일 2.15GB
- centos3 컨테이너의 경우 centos2 container + 생성한 파일 0 => size : 해당 컨테이너가 실제로 사용중인 크기
virtual size : size + 상위 부모 이미지의 크기 => 컨테이너를 띄울 때 부모 이미지의 사이즈는 가상으로만 잡히고 실제 디스크를 차지하는 사이즈는 해당 컨테이너의 사용분 만큼임 => 용량도 image layer와 같은 개념으로 사용됨