클라우드 컴퓨팅/쿠버네티스

Kubernetes Container Images

espossible 2021. 10. 24. 15:08

컨테이너 이미지는 애플리케이션과 모든 소프트웨어 의존성을 캡슐화하는 바이너리 데이터를 나타낸다. 컨테이너 이미지는 독립적으로 실행할 수 있고 런타임 환경에 대해 잘 정의된 가정을 만드는 실행 가능한 소프트웨어 번들이다.

 

일반적으로 파드에서 참조하기 전에 애플리케이션의 컨테이너 이미지를 생성해서 레지스트리로 푸시한다.

 

도커 레지스트리

Docker registry is a storage and distribution system for named Docker images. The same image might have multiple different versions, identified by their tags.

도커 퍼플릿 레지스트리

By default, the Docker engine interacts with DockerHub

 

도커 프라이빗 레지스트리

- 파드에 ImagePullSecrets을 명시하기 위해 시크릿을 생성하자

kubectl create secret docker-registry <name> 
--docker-server=DOCKER_REGISTRY_SERVER 
--docker-username=DOCKER_USER 
--docker-password=DOCKER_PASSWORD 
--docker-email=DOCKER_EMAIL

 

참고: 파드는 이미지 풀 시크릿을 자신의 네임스페이스에서만 참조할 수 있다. 따라서 이 과정은 네임스페이스 당 한 번만 수행될 필요가 있다.

 

- 해당 시크릿을 참조하는 파드 생성 예시

cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: docker-registry
EOF

cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF

 

이미지 이름 부분 다음에 tag 를 추가할 수 있다. 태그를 사용하면 동일한 시리즈 이미지의 다른 버전을 식별할 수 있다.

 

이미지 태그는 소문자와 대문자, 숫자, 밑줄(_), 마침표(.) 및 대시(-)로 구성된다. 이미지 태그 안에서 구분 문자(_, - 그리고 .)를 배치할 수 있는 위치에 대한 추가 규칙이 있다. 태그를 지정하지 않으면, 쿠버네티스는 태그 latest 를 의미한다고 가정한다.

 

프로덕션에서 컨테이너를 배포할 때는 latest 태그를 사용하지 않아야 한다. 실행 중인 이미지 버전을 추적하기가 어렵고 이전에 잘 동작하던 버전으로 롤백하기가 더 어렵다.
대신, v1.42.0 과 같은 의미있는 태그를 지정한다.

 

보다 정확하게 파드가 같은 버전의 이미지를 사용하게 하고 싶다면 digest를 사용할 수 있다.

image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2

 

만약 파드가 사용하고 있는 digest를 알고 싶다면 아래 명령어를 사용하길 바란다.

kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{","}{range .status.containerStatuses[*]}{.image}{", "}{.imageID}{", "}{end}{end}' | sort

 

이미지 업데이트

디플로이먼트, 스테이트풀셋, 파드 또는 파드 템플릿은 포함하는 다른 오브젝트를 처음 만들 때 특별히 명시하지 않은 경우 기본적으로 해당 파드에 있는 모든 컨테이너의 풀(pull) 정책은 IfNotPresent로 설정된다.

 

이미지 Pull Policy

pull policy 설명
IfNotPresent the image is pulled only if it is not already present locally.
Always every time the kubelet launches a container, the kubelet queries the container image registry to resolve the name to an image digest. If the kubelet has a container image with that exact digest cached locally, the kubelet uses its cached image; otherwise, the kubelet pulls the image with the resolved digest, and uses that image to launch the container.
Never the kubelet does not try fetching the image. If the image is somehow already present locally, the kubelet attempts to start the container; otherwise, startup fails.

 

만약 항상 이미지 풀을 강제하고 싶다면, 다음 중 하나를 수행하면 된다.

  • 컨테이너의 imagePullPolicy를 Always로 설정.
  • imagePullPolicy를 생략하고 :latest를 사용할 이미지의 태그로 사용, 쿠버네티스는 정책을 Always로 설정한다.
  • imagePullPolicy와 사용할 이미지의 태그를 생략.
  • AlwaysPullImages 어드미션 컨트롤러를 활성화.
컨테이너의 imagePullPolicy 값은 오브젝트가 처음 created 일 때 항상 설정되고 나중에 이미지 태그가 변경되더라도 업데이트되지 않는다.
예를 들어, 태그가 :latest가 아닌 이미지로 디플로이먼트를 생성하고, 나중에 해당 디플로이먼트의 이미지를 :latest 태그로 업데이트하면 imagePullPolicy 필드가 Always 로 변경되지 않는다. 오브젝트를 처음 생성 한 후 모든 오브젝트의 풀 정책을 수동으로 변경해야 한다.

 

도커 이미지와 이미지 사이즈

이미지명 이미지 사이즈
scratch 최소
alpine 작다
distroless 작다
ubuntu 크다
centos 크다
Universal Base Image 크다

 


출처

- [Docker Registry] : https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/

- [책: 쿠버네티스 완벽 가이드 마사야 아오야마 지음, 박상욱 옮김]

- [컨테이너 이미지]

https://kubernetes.io/ko/docs/tasks/access-application-cluster/list-all-running-container-images/

https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images

https://kubernetes.io/ko/docs/concepts/containers/images/