본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

레지스트리 다이제스트로 이미지 설치하기

원문 보기 위키 갱신

오퍼레이터 설치에서 이미지 태그 대신 변경 불가능한 컨테이너 레지스트리 다이제스트로 Calico 이미지를 배포하는 방법을 안내해요. ImageSet 리소스로 각 이미지를 고정하면 보안 팀이 이미지를 검토하고 검증할 수 있어요.

출처: 문서

본문

큰 그림

오퍼레이터 설치에서 컨테이너 레지스트리 다이제스트로 이미지를 배포해요.

가치

일부 배포 환경은 태그 대신 변경 불가능한 다이제스트로 이미지를 배포하도록 엄격한 보안 요구 사항을 갖고 있어요. 공식 Calico 이미지와 태그는 한번 릴리스되면 수정되지 않지만, 변경 불가능한 다이제스트를 사용하면 보안 팀이 특정 이미지를 검토하고 검증할 수 있어요.

개념

컨테이너 레지스트리

컨테이너 레지스트리는 태그나 다이제스트로 참조되는 컨테이너 이미지에 접근할 수 있게 해줘요.

이미지 태그

버전이 붙은 컨테이너 이미지는 보통 이미지 참조 뒤에 붙는 태그로 참조해요. 예: <repo>/<image>:<tag>. 컨테이너 이미지 태그는 보통 변경되거나 업데이트되지 않을 것으로 기대하지만, 대부분의 이미지 레지스트리는 이를 요구하거나 강제하지 않아요. 즉 같은 이미지 태그에 새 코드를 푸시할 수도 있어요.

이미지 다이제스트

컨테이너 이미지는 컨테이너 레지스트리에 추가될 때 고유한 해시가 만들어져요. 이 해시를 사용하면 변경하거나 업데이트할 수 없는 특정 버전의 이미지를 pull할 수 있어요.

시작하기 전에

필수 요건

  • 오퍼레이터가 관리하는 Calico
  • 이미지가 저장된 컨테이너 레지스트리에서 이미지를 pull하도록 구성된 Docker 클라이언트
  • ImageSet 매니페스트를 클러스터에 적용할 수 있는 Kubernetes 권한

방법

  1. 오퍼레이터 배포를 다이제스트로 업데이트하기
  2. ImageSet 만들기
  3. 올바른 ImageSet이 사용되고 있는지 확인하기

다른 작업

문제 해결

오퍼레이터 배포를 다이제스트로 업데이트하기

tigera-operator.yaml를 적용하기 전에 오퍼레이터 배포가 오퍼레이터 이미지 다이제스트를 사용하도록 수정해요.

다음과 같은 명령으로 이미지 다이제스트를 구해요 (다른 오퍼레이터 이미지를 사용한다면 명령의 이미지를 조정하세요):

docker pull quay.io/tigera/operator:v1.44.0
docker inspect quay.io/tigera/operator:v1.44.0 -f '{{range .RepoDigests}}{{printf "%s\n" .}}{{end}}'

여러 다이제스트가 반환되면 사용 중인 레지스트리와 일치하는 것을 고르세요.

tigera-operator 배포를 업데이트해요:

sed -ie "s|\(image: .*/operator\):.*|?\1@<put-digest-here>|" tigera-operator.yaml

ImageSet 만들기

다음과 같이 imageset.yaml이라는 이름의 ImageSet 매니페스트 파일을 만들어요:

apiVersion: operator.tigera.io/v1
kind: ImageSet
metadata:
  name: calico-v3.33.0
spec:
  images:
    - image: 'calico/apiserver'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/cni'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/kube-controllers'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/node'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/typha'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/pod2daemon-flexvol'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'calico/node-windows'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'tigera/operator'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
    - image: 'tigera/key-cert-provisioner'
      digest: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'

ImageSet 매니페스트는 수동으로 만들 수도 있고 스크립트로 만들 수도 있어요.

Tab: 수동

  1. 위 예시를 imageset.yaml 파일로 복사하고 아래 단계에서 그 파일을 편집해요.

  2. ImageSet 이름을 calico-<version>으로 정해요 (예: calico-v3.33.0). 버전은 다음 명령으로 알 수 있어요:

    docker run quay.io/tigera/operator:v1.44.0 --version
    
  3. 각 이미지에 올바른 다이제스트를 추가해요. 프라이빗 레지스트리를 사용한다면 프라이빗 레지스트리에서 이미지를 pull하고 프라이빗 레지스트리와 연결된 다이제스트를 사용해야 해요.

    1. 기본 이미지를 사용한다면 다음 명령으로 목록을 구해요:

      docker run quay.io/tigera/operator:v1.44.0 --print-images=list
      

      SECONDARY: 기본 이미지 레지스트리나 경로를 사용하지 않는다면 이미지 목록을 직접 만들어야 해요 (위 명령은 적용되지 않아요).

      SECONDARY: 목록에는 Enterprise 배포용 이미지도 포함되지만 ImageSet에 추가할 필요는 없어요.

    2. 위 단계에서 반환된 이미지를 다음 명령에 사용해 필요한 다이제스트를 구해요:

      docker pull <repo/image:tag> && docker inspect <repo/image:tag> -f '{{range .RepoDigests}}{{printf "%s\n" .}}{{end}}'
      
    3. 사용할 repo/image와 일치하는 이미지의 다이제스트를 사용해요. 프라이빗 레지스트리를 사용하거나 imagePath를 지정했더라도 image 필드에는 여전히 "기본" <owner>/<image>를 사용해요. 예를 들어 노드 이미지가 example.com/registry/imagepath/node에서 온다면 ImageSet의 image 필드에는 여전히 calico/node를 사용해요.

      SECONDARY: 이미지 quay.io/tigera/operator@sha256:d111db2f94546415a30eff868cb946d47e183faa804bd2e9a758fd9a8a4eaff1의 경우 @ 뒤의 내용을 모두 복사해 tigera/operator 이미지의 다이제스트로 추가해요.

Tab: 스크립트

다음 스크립트를 파일로 복사하고 실행 권한을 준 다음 실행해요. 스크립트는 실행된 디렉터리에 imageset.yaml 파일을 만들어요.

SECONDARY: 이 스크립트는 기본 레지스트리와 이미지 경로를 사용할 때만 동작해요.

#!/bin/bash -e

images=(calico/apiserver calico/cni calico/kube-controllers calico/node calico/typha calico/pod2daemon-flexvol calico/node-windows tigera/key-cert-provisioner tigera/operator)

OPERATOR_IMAGE=quay.io/tigera/operator:v1.44.0
echo "Pulling $OPERATOR_IMAGE"
echo
docker pull $OPERATOR_IMAGE -q >/dev/null
versions=$(docker run $OPERATOR_IMAGE --version)
ver=$(echo -e "$versions" | grep 'Calico:')

imagelist=($(docker run $OPERATOR_IMAGE --print-images=list))

cat > ./imageset.yaml <<EOF
apiVersion: operator.tigera.io/v1
kind: ImageSet
metadata:
  name: calico-$(echo $ver | sed -e 's|^.*: *||')
spec:
  images:
EOF

for x in "${imagelist[@]}"; do
  for y in ${images[*]}; do
    if [[ $x =~ $y: ]]; then
      digest=$(docker run --rm gcr.io/go-containerregistry/crane:v0.7.0 digest ${x})
      echo "Adding digest for $x"
      echo
      echo "  - image: \"$(echo $x | sed -e 's|^.*/\([^/]*/[^/]*\):.*$|\1|')\"" >> ./imageset.yaml
      echo "    digest: \"$digest\"" >> ./imageset.yaml
    fi
  done
done

만든 imageset.yaml을 클러스터에 적용해요.

올바른 ImageSet이 사용되고 있는지 확인하기

  1. kubectl get tigerastatus로 Degraded 상태인 컴포넌트가 있는지 확인해요.

  2. 모든 컴포넌트의 tigerastatus가 Available True를 보이면 ImageSet이 적용된 거예요.

    NAME     AVAILABLE   PROGRESSING   DEGRADED   SINCE
    calico   True        False         False      54s
    
  3. 올바른 ImageSet이 사용되고 있는지 확인해요. Installation 상태에서 imageset 필드가 여러분이 만든 ImageSet으로 설정됐는지 확인해요. 다음 명령으로 필드를 확인할 수 있어요:

    kubectl get installation default -o yaml | grep imageSet
    

    다음과 비슷한 출력이 보여야 해요:

    imageSet: calico-v3.33.0
    

다른 작업

업그레이드 또는 다운그레이드할 때 새 ImageSet 만들기

새 릴리스로 업그레이드하거나 다운그레이드하기 전에, 새 릴리스에 맞는 이미지 참조와 이름으로 새 ImageSet을 만들어야 해요. 클러스터를 업그레이드하기 전에 이 작업을 해야 새 매니페스트를 적용할 때 적절한 ImageSet이 준비돼 있어요.

문제 해결

Installation 리소스 상태에 내 ImageSet이 없는 이유는?

Installation 리소스의 status.imageset 필드는 calico 컴포넌트가 완전히 배포되기 전까지는 업데이트되지 않아요. kubectl get tigerastatus calico가 Progressing과 Degraded가 False인 상태에서 Available True를 보고하면 calico가 완전히 배포된 거예요.

ImageSet에 문제가 있는지 어떻게 알 수 있나요?

ImageSet에 문제가 의심되면 kubectl get tigerastatus로 확인해요. Degraded 상태인 컴포넌트가 있다면 kubectl get tigerastatus <component-name> -o yaml로 추가 정보를 얻을 수 있어요. 이미지에 제공한 다이제스트가 잘못됐거나 pull할 수 없는 경우 tigerastatus가 그 정보를 직접 보고하지는 않지만, Deployment나 Daemonset, Job을 롤아웃하는 데 문제가 있다는 정보는 보게 돼요. 이미지 문제로 리소스 롤아웃에 문제가 의심되면 특정 파드를 get이나 describe해서 문제의 세부 사항을 확인해야 해요.

더 알아보기 (Learn more)

이미지 태그는 언제든 바뀔 수 있지만 다이제스트는 변경 불가능하다는 점이 핵심이에요. ImageSet을 활용하면 보안 요구 사항이 엄격한 환경에서도 검증된 이미지 버전을 고정해 배포할 수 있어요.