![[인프런 워밍업 클럽 4기 - DevOps] [미션5]컨테이너 이미지 사례 실습](https://cdn.inflearn.com/public/files/blogs/7e82f6d1-c367-4f6d-a364-a0b123f699da/kubernetes_image.png)
[인프런 워밍업 클럽 4기 - DevOps] [미션5]컨테이너 이미지 사례 실습
컨테이너 이미지 사례 실습
▶ 사전 준비사항
# 도커 파일 및 App 소스 다운로드
curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/Dockerfile
curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/hello.js
[root@cicd-server ~]# ls
Dockerfile hello.js
<전체 실습 명령어>
1. docker build -t 1pro/hello:1.0.0 .
2. docker image list
3. docker tag 1pro/hello:1.0.0 1pro/hello:2.0.0
4-1. docker login -u 1pro
4-2. docker push 1pro/hello:1.0.0
5. docker rmi 1pro/hello:1.0.0
6. docker pull 1pro/hello:1.0.0
7. docker save -o file.tar 1pro/hello:1.0.0
8. docker load -i file.tar
1. 빌드
2. 이미지 리스트 조회
3. 태그 변경
4-1. 로그인
4-2. 이미지 업로드
5. 이미지 삭제
6. 이미지 다운로드
7. 이미지 -> 파일로 변환
▶ 이미지 삭제
8. 파일 -> 이미지로 변환
▶ 정리
컨테이너디 (Containerd)
<전체 실습 명령어>
1. ctr ns list
2. ctr -n k8s.io image list
3. ctr images pull docker.io/1pro/hello:1.0.0
4. ctr images tag docker.io/1pro/hello:1.0.0 docker.io/1pro/hello:2.0.0
5. ctr image push docker.io/1pro/hello:2.0.0 --user 1pro
6. ctr -n default image export file.tar docker.io/1pro/hello:1.0.0
7. ctr -n k8s.io image import file.tar
8. ctr -n k8s.io image remove docker.io/1pro/hello:1.0.0
1. 네임스페이스 조회
2. 특정 네임스페이스 내 이미지 조회
3. 다운로드 및 이미지 확인 (이미지는 default라는 네임스페이스에 다운 받아집니다.)
4. 태그 변경
5. 업로드
6. 이미지 (namespace : default) -> 파일로 변환
7. 파일 -> 이미지로 변환 (namespace : k8s.io)
8. 삭제 (namespace : k8s.io)
같은 이미지를 도커에서 받았을 때와 쿠버네티스에서 받았을 때 사이즈가 다른 이유
▶ Docker Hub (248.26 MB)
▶ Docker (520MB)
▶ Containerd (247.8 MiB)
1. Container Image를 만들 때 플랫폼(amd64, arm64)을 고려해야 되는데, Docker에서는 amd64를 받았고, Kuberentes에서 arm64를 받아서 이미지 크기가 달라졌을 것이다.
▶ Docker Hub에 올라간 이미지는 amd64 [win, linux]과 arm64 [mac m series]을 지원
▶ Docker (amd64가 보임)
▶ Containerd (amd64, arm64)가 보임
분석 :
해당 Image는 Mac M 시리즈나 Window 유저가 모두 다운받을 수 있도록 만들었습니다. 그래서 한 Image에 amd64, arm64 버전이 각각 있는 거고요.
현재 저는 Linux (adm64)에서 이미지를 다운로드를 실행 했고, Docker에서는 amd64 이미지를 받았고, Containerd에서는 amd64와 arm64 둘다 있는 걸로 보아 두 버전이 모두 사용가능한 이미지가 다운 받아진 것 처럼 느껴질 수 있습니다.
그럼 두 버전을 모두 받은 Containerd 이미지가 더 커야 할 텐데, 오히려 이미지가 더 작아요.
결론 :
Containerd에서 PLATFORMS는 그냥 해당 이미지가 어떤 플랫폼을 지원하는지 정보를 보여준 것이지, 실제 여러 플랫폼에서 실행 가능한 이미지를 받았다는 의미는 아닙니다.
내가 amd64 환경에서 다운로드 했다면, Containerd는 알아서 amd64의 이미지를 다운 받아와요.
그렇기 때문에 Docker나 Containerd 에서는 같은 amd64 이미지를 다운받았고, 결국 Size도 같아야 합니다.
2. Container 이미지는 각각의 Layer로 구성돼 있는데, Docker에서 다운 받을 때는 전체 Layer를 받았고, Kubernetes에는 기존 이미지에 이미 존재하는 Layer가 있기 때문에 새로 받은 이미지의 Size가 작게 조회 됐을 것이다.
▶ Docker -> Containerd
1. 파일로 변환
2. 복사
3. 이미지로 변환
▶ Containerd -> Docker
1. 파일로 변환
2. 복사
3. 이미지로 변환
분석 :
Docker의 이미지를 파일로 변경 했을 때는 이미지 사이즈가 약간 작아졌지만, 큰 차이가 없었고, 그 파일을 Containerd로 Import 했을 때 사이즈의 변화는 없었습니다.
반면 Containerd의 이미지를 Docker로 넣었더니 이미지가 증가했네요.
Docker로 다운 받나, Containerd로 다운 받나 어차피 같은 동작을 하는 이미지이고, 각각 최초 조회 되는 Size가 달랐어도, 이동되는 파일이나, Import 시에 파일 사이즈가 좀 이상해 보입니다.
결론 :
Container의 이미지는 Layer 방식으로 만들어지며, A 이미지가 1, 2, 3 레이어를 가지고 있고, 각 레이어의 크기가 1MB라고 했을 때, 1, 2, 3, 4 레이어를 가지진 B 이미지를 다운받는 다면, 4 레이어만 다운 받으면 되고
B 이미지는 기존 A 이미지가 가지고 있는 1, 2, 3 레이어를 같이 사용하고, 거기에 4 레이어만 해서 자신의 이미지를 만듭니다.
그래서 A와 B의 이미지를 조회 할 때는, A-3MB, B-4MB로 보이지만, 내부적으로는 4MB만 사용을 해요. 컨테이너 이미지는 조회 권한만 있는 스냅샷이기 때문에 다른 이미지에서도 같이 레이어를 공유해서 사용할 수 있고, 거기에 내 레이어를 추가하는 방식으로 구성 됩니다. 그래서 필요한 레이어만 다운 받으면 되니 컨테이너가 Disk 자원적으로는 매우 유리한 거죠.
이런 관점에서 볼때, 위 그림에서 최초 조회된 사이즈 (Docker-490MB, Containerd-248.3MiB)는 내부적으로는 어떻게 사용되고 있는지 모르겠지만, 해당 이미지를 구성하는 전체 사이즈가 맞습니다.
그래서 결국 Docker에서 Containerd로 이미지를 가져갔을 때 Size가 그대로이고, 반대로 Containerd에서 Docker로 이미지를 가져갔을 때는 Size가 증가하는 원인을 찾아야 합니다.
3. 쿠버네티스에는 다른 Runtime을 사용했을 수 있고, 같은 이미지더라도 사용하는 Runtime에 따라서 이미지의 크기는 달라질 것이다.
분석
쿠버네티스는 Runtime으로 Docker나 Containerd 둘중 하나를 선택할 수가 있는데, 예전에는 주로 도커를 사용했지만 현재는 Contaienrd가 기본으로 사용되고 있다.
이미지 사이즈가 다른 이유는 Docker와 Kubernetes가 아닌 Docker와 Contaienrd의 차이이다.
결론
Docker는 다른 많은 기능들을 지원해 주기 때문에 실제 이미지가 247.8 MiB라고 하더라도 다운 받은 이후 자신의 메타데이터 규격에 맞게 데이터들을 더 추가하고 이미지를 재구성한다. 그래서 520MB가 된 것이다. Containerd에서 이미지를 가져왔을 때도 마찬가지로, 이미지를 재구성 하느라 Size가 커졌다.
반대로 Docker의 이미지를 Contaienrd로 가져가게 됐을 때, Docker에서 재구성을 하느라 커진 불필요한 메타데이터들이 그대로 들어간 것이다.
꼭 알고 넘어가야 하는점
인터넷이 연결되지 않는 환경에서는 이미지들을 다운 받아서 파일 형태로 복사를 해야된다.
이때 쿠버네티스에서 Contaienrd를 사용한다면 Docker로 받은 이미지를 복사해 넣을 경우 불필요하게 이미지 사이즈가 커지게 됩니다.
댓글을 작성해보세요.