Study/Docker

[Docker]Docker Image Layer

seomj 2023. 11. 17. 15:30

전에 프로젝트를 진행하며 docker image version으로 고생한 기억이 있어 다시 공부하고 확인해보고자 했다.


Docker Image Layer

 

왼쪽에 Dockerfile을 기준으로 오른쪽 image에서 layer로 변환되는 과정을 그림을 통해 확인할 수 있다.

각 명령어들이 builder를 통해 각 layer로 바뀌어 저장된다.

 

이미지 레이어가 변경되지 않은 경우 빌더는 빌드 캐시에서 해당 레이어를 선택하여 재사용한다.

마지막 빌드 후 레이어가 변경된 경우에는 해당 레이어와 이후의 모든 레이어를 재빌드 해야 한다.


실습 TEST

version을 동일 시 하고 이미지가 바뀌는지를 체크한다.

 

1. local image - dockerfile 수정

Dockerfile에서 "hello docker" image에서 "hello world"를 출력하는 이미지 테스트

 

dockerfile

# 사용할 베이스 이미지를 선택
FROM ubuntu:latest

# 이미지 내에서 명령어 실행
RUN apt-get update
RUN apt-get install -y python3

# 컨테이너가 시작될 때 실행할 명령어
CMD ["python3", "-c", "print('Hello, Docker!')"]

 

결과

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t test:1.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
test         1.0       0068618db378   9 seconds ago   154MB
ubuntu       20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run test:1.0
Hello, Docker!

 

변경

# 사용할 베이스 이미지를 선택
FROM ubuntu:latest

# 이미지 내에서 명령어 실행
RUN apt-get update
RUN apt-get install -y python3

# 컨테이너가 시작될 때 실행할 명령어
CMD ["python3", "-c", "print('Hello, World!')"]

 

결과

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t test:1.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
<none>       <none>    0068618db378   About a minute ago   154MB
test         1.0       260d7de0191a   About a minute ago   154MB
ubuntu       20.04     6df894023726   3 months ago         72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run test:1.0
Hello, World!

 

→ image id를 보면 기존 버전의 image가 none으로 밀려난 것을 확인

 

 

2.  local image - shell file 수정

shell에서 "hello docker"에서 "hello world"를 출력하는 이미지 테스트

 

Dockerfile

# 사용할 베이스 이미지를 선택
FROM ubuntu:latest

# 이미지 내에서 명령어 실행
RUN apt-get update
RUN apt-get install -y bash

# 스크립트 파일 복사
COPY my_script.sh /usr/local/bin/

# 스크립트 실행 권한 부여
RUN chmod +x /usr/local/bin/my_script.sh

# 컨테이너가 시작될 때 실행할 명령어 (스크립트 실행)
CMD ["/usr/local/bin/my_script.sh"]

 

shell

#!/bin/bash

echo "This is a simple Shell script executed in a Docker container."
echo "Hello, Docker!"

 

결과

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t shell:1.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run shell:1.0
This is a simple Shell script executed in a Docker container.
Hello, Docker!
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
shell        1.0       11e571954691   50 seconds ago   123MB
ubuntu       20.04     6df894023726   3 months ago     72.8MB

 

shell 변경

#!/bin/bash

echo "This is a simple Shell script executed in a Docker container."
echo "Hello, World!"

 

결과

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t shell:1.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
shell        1.0       f1438383492e   6 seconds ago        123MB
<none>       <none>    11e571954691   About a minute ago   123MB
ubuntu       20.04     6df894023726   3 months ago         72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run shell:1.0
This is a simple Shell script executed in a Docker container.
Hello, World!

이 또한 제대로 잘 된다. 대체 뭐가 문제였지.

 

그때 당시 ecr로 업로드를 했었는데 이에 대한 영향도 있을까?

docker hub나 ecr처럼 어느 레포에 올려야 한다? 업로드해야하나? 싶어서 혹시 몰라 docker hub로 테스트했다.

 

 

3. Docker hub - shell 수정

shell에서 "hello docker"에서 "hello world"를 출력하는 이미지 테스트

 

shell

#!/bin/bash

echo "This is a simple Shell script executed in a Docker container."
echo "Hello, Docker!"

 

결과

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:1.1 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
smj100394/tag-test   1.1       11e571954691   5 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:1.1
The push refers to repository [docker.io/smj100394/tag-test]

 

확실하게 하기 위해 로컬의 이미지는 지우고 다시 push

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
smj100394/tag-test   1.1       11e571954691   7 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker rmi 11e571954691
Untagged: smj100394/tag-test:1.1
Untagged: smj100394/tag-test@sha256:585e437fdaa2719a070f989c02560adb5aab48f252851e7b1ff9904c0209e21a
Deleted: sha256:11e571954691a07e2bd0cc2cac8cd139e6c0c15d9aaa448fa9e8120e2a46abce
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       20.04     6df894023726   3 months ago   72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker pull smj100394/tag-test:1.1
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
smj100394/tag-test   1.1       11e571954691   8 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run smj100394/tag-test:1.1
This is a simple Shell script executed in a Docker container.
Hello, Docker!

하지만 id가 같은 것을 보아 의미가 없는 거 같긴 하다 ㅎㅎ

 

변경

#!/bin/bash

echo "This is a simple Shell script executed in a Docker container."
echo "Hello, World!"

 

결과

...
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker run smj100394/tag-test:1.1
This is a simple Shell script executed in a Docker container.
Hello, World!

예상한 결과였다.

왜냐면 docker build를 하면 기존의 이미지가 none으로 밀리고 새로 id가 생성되며 바뀌기 때문이다.


문제점

그렇다면 왜 전에 ECR에서는 변경이 안되었던거지?

shell 파일을 수정하고 동일 태그로 이미지를 빌드하면 새로운 shell이 적용되지 않았다.

코드를 변경해도 바뀌는 게 없어 해당 이미지를 run하고 접속해서 shell을 까보니 처음 원본 그대로의 shell만 떠있었다.

그래서 결국 test를 할 때마다 버전을 올리면서 진행했었다.

 

물론 문제는 없지만 그때 해결하지 못 한 궁금증이 다시 수면위로 올라왔다.

 

현재 다시 테스트를 해보니 제대로 된다. 그리고 그때 당시 나 또한 이게 될 거라고 생각하고 진행했는데 안돼서 뭐지 싶었는데... 그때 당시 휴먼 에러였던건가..


Layer 변화 TEST

layer의 변화도 한번 살펴보자.

"hello docker"를 출력하는 shell을 docker hub에 push했다가 "hello world"를 출력하는 shell로 변경하여 push하면 layer가 어떻게 변화되는지를 보자.

 

실습 전 GPT에게 물어본 결과

 

 

1. shell 수정

동일 버전으로 shell만 변경하여 push

 

"hello world" image push

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ vi my_script.sh
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ cat my_script.sh
#!/bin/bash

echo "Hello world!"

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
smj100394/tag-test   2.0       98d0a7c9ef6a   5 seconds ago   123MB
ubuntu               20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.0

 

"hello docker" image push

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ vi my_script.sh
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ cat my_script.sh
#!/bin/bash

echo "Hello docker!"
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.0 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
smj100394/tag-test   2.0       98df0b1a7777   3 seconds ago   123MB
smj100394/tag-test   <none>    98d0a7c9ef6a   2 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago    72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.0

우선 기존의 2.0이 아닌 새로 push한 2.0으로 변경되었으며 파일 용량이나 id 등이 바뀐 것을 보면 아예 바뀐 듯..?

 

 

2. Shell 추가

이번에는 "welcome!"을 추가로 출력하도록 shell을 수정한 후 확인해보자.

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ vi my_script.sh
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ cat my_script.sh
#!/bin/bash

echo "Hello docker!"

echo "welcome!"
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.1
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
smj100394/tag-test   2.1       80f8e7a43188   4 seconds ago    123MB
smj100394/tag-test   2.0       98df0b1a7777   7 minutes ago    123MB
smj100394/tag-test   <none>    98d0a7c9ef6a   10 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago     72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.1

오... 놀랍게도 모르겠군....

아무래도 내부에 넣은 shell에서의 변화기에 차이가 없는거 같다?

 

 

3. Dockerfile 수정

이번에는 Dockerfile 자체에서의 수정을 해보자.

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ vi Dockerfile
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ cat Dockerfile
# 사용할 베이스 이미지를 선택
FROM ubuntu:latest

# 이미지 내에서 명령어 실행
RUN apt-get update
RUN apt-get install -y bash

# 스크립트 파일 복사
COPY my_script.sh /usr/local/bin/

# 스크립트 실행 권한 부여
RUN chmod +x /usr/local/bin/my_script.sh

# 컨테이너가 시작될 때 실행할 명령어 (스크립트 실행)
CMD ["/usr/local/bin/my_script.sh"]

RUN echo "====== Dockerfile ======"
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.2 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
smj100394/tag-test   2.2       17b5a1f76bee   4 seconds ago    123MB
smj100394/tag-test   2.1       80f8e7a43188   3 minutes ago    123MB
smj100394/tag-test   2.0       98df0b1a7777   11 minutes ago   123MB
smj100394/tag-test   <none>    98d0a7c9ef6a   13 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago     72.8MB
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.2

12번째 Layer가 새로 생겼다.

 

그렇다면 2.1 version에 해당 이미지를 넣으면?

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.1 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.1
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
smj100394/tag-test   2.1       17b5a1f76bee   2 minutes ago    123MB
smj100394/tag-test   2.2       17b5a1f76bee   2 minutes ago    123MB
smj100394/tag-test   <none>    80f8e7a43188   6 minutes ago    123MB
smj100394/tag-test   2.0       98df0b1a7777   13 minutes ago   123MB
smj100394/tag-test   <none>    98d0a7c9ef6a   16 minutes ago   123MB
ubuntu               20.04     6df894023726   3 months ago     72.8MB

12번째 layer가 생겼다.

 

 

4. Dockerfile 삭제

그렇다면 Layer를 삭제하면 증가하나? 아니면 줄어드나?

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ vi Dockerfile
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ cat Dockerfile
# 사용할 베이스 이미지를 선택
FROM ubuntu:latest

# 이미지 내에서 명령어 실행
RUN apt-get update
RUN apt-get install -y bash

# 스크립트 파일 복사
COPY my_script.sh /usr/local/bin/

# 스크립트 실행 권한 부여
RUN chmod +x /usr/local/bin/my_script.sh

# 컨테이너가 시작될 때 실행할 명령어 (스크립트 실행)
CMD ["/usr/local/bin/my_script.sh"]

seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker build -t smj100394/tag-test:2.2 .
seo@LAPTOP-RBH2DA89:~/nba/docker_test$ docker push smj100394/tag-test:2.2

줄어든다!


결국 위의 실습으로는 의문점이 풀리지 않았고 직접 팀장님께 질문했다.

결국 쿠버...

 

팀장님의 설명으로 내가 이해한 바로는

job이나 pod 등을 apply할 때 이미지를 적용하면 이는 설정된 이미지 풀 정책을 따르게 된다.

여기서 이미지 풀 정책을 기본으로 사용하면 이미지 명과 태그만 확인하여 바뀌지 않는다.

 

그러고 생각해보니 imagePullPolicy라는 항목이 있다는 것이 기억남...!!!

 

기본 값이 IfNotPresent로 설정되어 있다. 이로 인해 worker node에 이미 저장된 이미지만 적용되어 계속 실행되었던 것 같다. 더 자세한 내용은 공홈에서 확인해 보시길! https://kubernetes.io/docs/concepts/containers/images/

 

사실 내 기억엔 worker node에 접속해서 이미지도 다 지워보고 다시 해보고 별 짓을 다 했던거 같긴 한데... 이는 확실하지 않으니 패스. 내가 빼먹은 부분이 있을 수도 있공... 모르겠다

 

쨋든, 정리하자면 docker 등 이미지 만들 때의 문제가 아니였다는 것.

쿠버네티스에서 job을 생성할 때 이미지 풀 정책으로 인한 문제였었다.

그래도 이미지 layer에 대해 공부도 다시 하고, 쿠버네티스 이미지 풀 정책에 대해서도 다시 상기할 수 있었으니 이걸로 되었다~

 

 

 

참고

https://docs.docker.com/build/guide/layers/

'Study > Docker' 카테고리의 다른 글

[Docker]Docker 사용하기 2 (공유)  (0) 2023.02.11
[Docker]Docker 사용하기  (0) 2023.02.11
[Docker]명령어  (0) 2022.10.18
[Docker]Docker 입문 및 간단 명령어  (0) 2021.08.18