Kubernetes 매니페스트에서 컨테이너 이미지 다이제스트 사용

Last reviewed 2023-07-21 UTC

이 튜토리얼에서는 컨테이너를 Kubernetes에 배포하는 개발자와 운영자에게 컨테이너 이미지 다이제스트를 사용하여 컨테이너 이미지를 식별하는 방법을 보여줍니다. 컨테이너 이미지 다이제스트는 컨테이너 이미지를 고유하고 변경 불가능하게 식별합니다.

이미지 다이제스트를 사용하여 컨테이너 이미지를 배포하면 이미지 태그를 사용할 때와 비교해서 몇 가지 장점이 있습니다. 이미지 다이제스트에 대한 자세한 내용은 이 튜토리얼을 계속하기 전 컨테이너 이미지 다이제스트 사용에 관한 포함된 문서를 참조하세요.

Kubernetes pod 사양에서 컨테이너에 대한 image 인수에는 다이제스트 포함 이미지가 사용됩니다. 이 인수는 Deployment, StatefulSet, DaemonSet, ReplicaSet, CronJob, Job 리소스의 template 섹션과 같이 포드 사양을 사용하는 모든 위치에 적용됩니다.

다이제스트를 사용하여 이미지를 배포하려면 이미지 이름과 @sha256: 및 다이제스트 값으로 이어지는 이미지 이름을 사용합니다. 다음은 이미지와 다이제스트를 사용하는 배포 리소스의 예시입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deployment
spec:
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        ports:
        - containerPort: 8080

이미지 다이제스트를 사용할 때의 한 가지 단점은 이미지를 레지스트리에 게시하기 전까지 다이제스트 값을 알 수 없다는 것입니다. 새 이미지를 빌드할 때 다이제스트 값이 변경되고 배포할 때마다 Kubernetes 매니페스트를 업데이트하기 위한 방법이 필요합니다.

이 튜토리얼에서는 Skaffold, kpt, digester, kustomize, gke-deploy, ko와 같은 도구를 사용하여 매니페스트에서 이미지 다이제스트를 사용하는 방법을 보여줍니다.

권장사항

이 문서에서는 Kubernetes 배포에서 이미지 다이제스트를 사용하기 위한 몇 가지 방법을 보여줍니다. 이 문서에 설명된 도구는 보완적으로 사용됩니다. 예를 들어 kustomize와 함께 kpt 함수의 출력을 사용하여 다른 환경에 대한 변이를 만들 수 있습니다. Skaffold는 ko를 사용하여 이미지를 빌드하고 kubectl 또는 kpt를 사용하여 이미지를 Kubernetes 클러스터에 배포할 수 있습니다.

이 도구가 보완적인 이유는 Kubernetes 리소스 모델(KRM)에 따라 구조화된 수정을 수행하기 때문입니다. 이 모델은 도구를 플러그 가능하게 만들고 도구 사용을 발전시켜 앱과 서비스를 배포하는 데 도움이 되는 프로세스와 파이프라인을 만들 수 있습니다.

시작하려면 기존 도구 및 프로세스에 가장 적합한 방법을 사용하는 것이 좋습니다.

  • Skaffold는 다이제스트를 이미지 참조에 추가할 수 있습니다. 작은 구성 변경과 함께 이 함수를 사용 설정합니다. Skaffold를 채택하면 서로 다른 도구로 컨테이너 이미지를 빌드 및 배포하는 방법을 추상화하는 것과 같은 추가적인 이점을 제공합니다.

  • Kubernetes 클러스터에서 digester 도구를 변형 허용 웹훅으로 사용하면, 컨테이너 이미지 빌드 및 배포를 위한 현재 프로세서에 미치는 영향을 최소로 하면서 다이제스트를 모든 배포에 추가할 수 있습니다. 또한 digester 웹훅은 네임스페이스에 라벨을 추가하기만 하면 되므로 Binary Authorization의 채택을 간소화합니다.

  • kpt는 Kubernetes 매니페스트를 조작하는 유연한 도구가 필요한 경우 유용한 옵션입니다. kpt 파이프라인에서 digester 도구를 클라이언트 측 KRM 함수로 사용할 수 있습니다.

  • 환경 간 Kubernetes 매니페스트 관리를 위해 이미 kustomize를 사용하는 경우 다이제스트로 이미지를 배포하기 위해 이미지 변환기를 활용하는 것이 좋습니다.

  • ko는 Go 앱용 이미지를 빌드하고 게시하는 좋은 방법이며 Knative, Tekton, sigstore와 같은 오픈소스 프로젝트에서 사용됩니다.

이 문서에 설명된 도구를 사용하지 않는 경우 Skaffold 및 digester 웹훅으로 시작하는 것이 좋습니다. Skaffold는 개발자 및 출시 팀 모두에서 사용되는 공통 도구이며, 이 가이드에 설명된 다른 도구들과 통합됩니다. 요구 사항 변화에 따라 이러한 통합 옵션을 활용할 수 있습니다. digester Kubernetes 웹훅은 조직 클러스터에 다이제스트 기반 배포를 사용 설정하여 Skaffold를 보완합니다.

목표

  • Skaffold를 사용하여 이미지를 빌드 및 푸시하고 이미지 이름 및 다이제스트를 Kubernetes 매니페스트에 삽입합니다.
  • digester 클라이언트 측 함수와 허용 웹훅 변형을 사용하여 Kubernetes pod 및 pod 템플릿의 이미지에 다이제스트를 추가합니다.
  • kpt setters를 사용하여 Kubernetes 매니페스트에서 이미지 태그를 이미지 다이제스트로 바꿉니다.
  • kustomize를 사용하여 이미지 다이제스트와 함께 Kubernetes 매니페스트를 생성합니다.
  • gke-deploy를 사용하여 이미지 태그를 Kubernetes 매니페스트의 다이제스트로 분석합니다.
  • ko를 사용하여 이미지를 빌드하고 푸시하고 Kubernetes 매니페스트에 이미지 이름 및 다이제스트를 삽입합니다.

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

  1. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  2. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  3. Artifact Registry API 사용 설정

    API 사용 설정

  4. Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.

    Cloud Shell 활성화

  5. Cloud Shell에서 Google Cloud CLI의 기본 프로젝트를 설정합니다.

    gcloud config set project PROJECT_ID
    

    PROJECT_ID를 [프로젝트 ID]로 바꿉니다.

  6. Artifact Registry에서 컨테이너 이미지 저장소를 만듭니다.

    gcloud artifacts repositories create REPOSITORY \
        --location=LOCATION \
        --repository-format=docker
    

    다음을 바꿉니다.

  7. 이 튜토리얼에 사용된 CLI 도구의 Artifact Registry 위치에 대한 인증을 구성합니다.

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    

Skaffold 사용

Skaffold는 Kubernetes 클러스터에서 애플리케이션을 지속적으로 개발 및 배포하기 위한 명령줄 도구입니다.

Skaffold를 사용하여 이미지를 빌드하고 이미지를 Artifact Registry로 푸시한 후 Kubernetes 매니페스트 템플릿의 image 자리표시자 값을 푸시한 이미지의 이름, 태그, 다이제스트로 바꿉니다.

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/skaffold
    cd ~/container-image-digests-tutorial/skaffold
    
  2. Skaffold Git 저장소를 클론합니다.

    git clone https://github.com/GoogleContainerTools/skaffold.git
    
  3. getting-started 예시의 디렉터리로 이동합니다.

    cd skaffold/examples/getting-started
    
  4. Skaffold 버전과 일치하는 Git 태그를 체크아웃합니다.

    git checkout $(skaffold version)
    
  5. skaffold.yaml 구성 파일을 확인합니다.

    cat skaffold.yaml
    

    파일은 다음과 유사합니다.

    apiVersion: skaffold/v4beta6
    kind: Config
    build:
      artifacts:
      - image: skaffold-example
    manifests:
      rawYaml:
      - k8s-pod.yaml
    

    build.artifacts 섹션에는 자리표시자 이미지 이름이 포함되어 있습니다. Skaffold는 입력 매니페스트 파일에서 이 자리표시자를 검색합니다.

    manifests 섹션은 Skaffold가 현재 디렉터리에서 k8s-pod.yaml이라는 입력 매니페스트를 읽도록 지시합니다.

    사용 가능한 모든 옵션에 대한 개요는 skaffold.yaml 참조 문서를 참조하세요.

  6. Kubernetes 매니페스트 템플릿을 확인합니다.

    cat k8s-pod.yaml
    

    파일은 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - name: getting-started
        image: skaffold-example
    

    image 필드의 skaffold-example 자리표시자 값은 skaffold.yaml 파일의 image 필드 값과 일치합니다. Skaffold는 이 자리표시자 값을 렌더링된 출력의 전체 이미지 이름 및 다이제스트로 바꿉니다.

  7. 이미지를 빌드하고 Artifact Registry에 푸시합니다.

    skaffold build \
        --default-repo=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY \
        --file-output=artifacts.json \
        --interactive=false \
        --push=true \
        --update-check=false
    

    이 명령어는 다음 플래그를 사용합니다.

    • --file-output 플래그는 다이제스트 값을 포함하여 빌드된 이미지에 대한 정보를 Skaffold에 저장하는 파일을 지정합니다.
    • --push 플래그는 Skaffold가 빌드된 이미지를 --default-repo 플래그로 지정된 컨테이너 이미지 레지스트리로 푸시하도록 지시합니다.
    • --interactive--update-check 플래그는 모두 false로 설정됩니다. 빌드 파이프라인과 같은 비대화형 환경에서 이러한 플래그를 false로 설정하지만 로컬 개발의 경우 기본값(두 플래그의 경우 true)을 그대로 둡니다.

    Cloud Deploy를 사용하여 GKE에 배포하는 경우 출시 버전을 만들 때 --file-output 플래그의 파일을 --build-artifacts 플래그 값으로 사용합니다.

  8. 이전 단계에서 가져온 컨테이너 이미지의 이름, 태그, 다이제스트로 확장된 Kubernetes 매니페스트를 렌더링합니다.

    skaffold render \
        --build-artifacts=artifacts.json \
        --digest-source=none \
        --interactive=false \
        --offline=true \
        --output=rendered.yaml \
        --update-check=false
    

    이 명령어는 다음 플래그를 사용합니다.

    • --build-artifacts 플래그는 이전 단계의 skaffold build 명령어에서 출력 파일을 참조합니다.
    • --digest-source=none 플래그는 Skaffold가 컨테이너 이미지 레지스트리에서 다이제스트를 확인하는 대신 --build-artifacts 플래그에 제공된 파일의 다이제스트 값을 사용함을 의미합니다.
    • --offline=true 플래그를 사용하면 Kubernetes 클러스터에 액세스할 필요 없이 명령어를 실행할 수 있습니다.
    • --output 플래그는 렌더링된 매니페스트의 출력 파일을 지정합니다.
  9. 렌더링된 매니페스트를 확인합니다.

    cat rendered.yaml
    

    다음과 유사한 결과가 출력됩니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - image: LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/skaffold-example:TAG@sha256:DIGEST
        name: getting-started
    

    이 출력에서는 다음 값이 표시됩니다.

    • TAG: Skaffold가 이미지에 할당한 태그입니다.
    • DIGEST: 이미지 다이제스트 값입니다.

digester 사용

digester는 Kubernetes pod 및 pod 템플릿 사양에서 컨테이너 및 초기화 컨테이너 이미지에 다이제스트를 추가합니다. digester는 태그를 사용하는 컨테이너 이미지 참조를 바꿉니다.

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10

이미지 다이제스트를 사용하는 참조를 사용합니다.

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

digester는 Kubernetes 클러스터에서 변형 허용 웹훅으로 또는 kpt 또는 kustomize 명령줄 도구를 사용하는 클라이언트 측 KRM 함수로 실행될 수 있습니다.

digester KRM 함수 사용

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/digester-fn
    cd ~/container-image-digests-tutorial/digester-fn
    
  2. digester 바이너리를 다운로드합니다.

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    curl -L "https://github.com/google/k8s-digester/releases/download/${DIGESTER_VERSION}/digester_$(uname -s)_$(uname -m)" --output ${HOME}/bin/digester
    chmod +x ${HOME}/bin/digester
    
  3. 1.10 태그를 사용하여 gcr.io/google-containers/echoserver 이미지를 참조하는 Kubernetes pod 매니페스트를 만듭니다.

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. 현재 디렉터리(.)에서 매니페스트와 함께 kpt를 사용하여 digester KRM 함수를 실행합니다.

    kpt fn eval . --exec digester
    

    이 명령어를 실행하면 kpt가 현재 디렉터리에서 매니페스트의 인플레이스 업데이트를 수행합니다. kpt를 사용해서 Console에서 업데이트된 매니페스트를 표시하고 매니페스트 파일을 변경되지 않은 상태로 두려면 --output unwrap 플래그를 추가합니다.

  5. 업데이트된 매니페스트를 봅니다.

    cat pod.yaml
    

    파일은 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
        - name: echoserver
          image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
          ports:
            - containerPort: 8080
    

digester 허용 웹훅 사용

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/digester-webhook
    cd ~/container-image-digests-tutorial/digester-webhook
    
  2. kind를 사용하여 로컬 Kubernetes 클러스터를 만듭니다.

    kind create cluster
    

    kind는 Docker를 사용하여 로컬 Kubernetes 클러스터를 실행하는 명령줄 도구입니다.

  3. digester 웹훅을 배포합니다.

    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    kustomize build "https://github.com/google/k8s-digester.git/manifests?ref=${DIGESTER_VERSION}" | kubectl apply -f -
    
  4. kind 클러스터에 digester-demo라는 Kubernetes 네임스페이스를 만듭니다.

    kubectl create namespace digester-demo
    
  5. digest-resolution: enabled 라벨을 digester-demo 네임스페이스에 추가합니다.

    kubectl label namespace digester-demo digest-resolution=enabled
    

    digester 웹훅은 이 라벨이 있는 네임스페이스의 pod에 다이제스트를 추가합니다.

  6. 1.10 태그를 사용하여 gcr.io/google-containers/echoserver 이미지를 참조하는 Kubernetes 배포 매니페스트를 만듭니다.

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  7. digester-demo 네임스페이스에 매니페스트를 적용합니다.

    kubectl apply --filename deployment.yaml --namespace digester-demo \
        --output jsonpath='{.spec.template.spec.containers[].image}{"\n"}'
    

    --output 플래그는 이미지 이름을 콘솔에 출력하고 줄바꿈 문자를 출력하도록 kubectl에 지시합니다. 출력은 다음과 같습니다.

    gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    

    이 출력은 digester 웹훅이 배포 리소스의 pod 템플릿 사양에 이미지 다이제스트를 추가했음을 보여줍니다.

  8. kind 클러스터를 삭제하여 Cloud Shell 세션의 리소스를 확보합니다.

    kind delete cluster
    

kpt setters 사용

kpt는 Kubernetes 리소스 매니페스트를 관리, 조작, 맞춤설정, 적용하기 위한 명령줄 도구입니다.

새 이미지를 빌드할 때 kpt 함수 카탈로그create-settersapply-setters KRM 함수를 사용하여 Kubernetes 매니페스트의 이미지 다이제스트를 업데이트할 수 있습니다.

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/kpt
    cd ~/container-image-digests-tutorial/kpt
    
  2. 현재 디렉터리에 kpt 패키지를 만듭니다.

    kpt pkg init --description "Container image digest tutorial"
    
  3. 1.10 태그를 사용하여 gcr.io/google-containers/echoserver 이미지를 참조하는 Kubernetes pod 매니페스트를 만듭니다.

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. kpt를 사용하여 기존 필드에 gcr.io/google-containers/echoserver:1.10인 매니페스트 필드에 대해 echoimage이라는 setter를 만듭니다.

    kpt fn eval . \
        --image gcr.io/kpt-fn/create-setters@sha256:0220cc87f29ff9abfa3a3b5643aa50f18d355d5e9dc9e1f518119633ddc4895c \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10"
    
  5. 매니페스트를 확인합니다.

    cat pod.yaml
    

    파일은 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    
  6. 컨테이너 이미지의 다이제스트 값을 가져옵니다.

    DIGEST=$(gcloud container images describe \
        gcr.io/google-containers/echoserver:1.10 \
        --format='value(image_summary.digest)')
    
  7. 새 필드 값을 설정합니다.

    kpt fn eval . \
        --image gcr.io/kpt-fn/apply-setters@sha256:4d4295727183396f0c3c6a75d2560254c2f9041a39e95dc1e5beffeb49cc1a12 \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10@$DIGEST"
    

    이 명령어를 실행하면 image가 매니페스트에서 필드 값의 제자리 교체를 수행합니다.

  8. 업데이트된 매니페스트를 봅니다.

    cat pod.yaml
    

    파일은 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    

kustomize 이미지 변환기 사용

kustomize는 오버레이, 패치, 변환기를 사용하여 Kubernetes 매니페스트를 맞춤설정할 수 있게 해주는 명령줄 도구입니다.

이미지 변환기를 사용하여 기존 매니페스트에서 이미지, 이름 태그, 다이제스트를 업데이트할 수 있습니다.

다음 kustomization.yaml 스니펫은 pod 사양 image 값이 변환기 name 값과 일치하는 이미지에 변환기 digest 값을 사용하도록 이미지 변환기를 구성하는 방법을 보여줍니다.

images:
- name: gcr.io/google-containers/echoserver
  digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

이미지 다이제스트와 함께 이미지 변환기를 사용하려면 다음을 수행합니다.

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/kustomize
    cd ~/container-image-digests-tutorial/kustomize
    
  2. kustomization.yaml 파일을 만듭니다.

    kustomize init
    
  3. 1.10 태그를 사용하여 gcr.io/google-containers/echoserver 이미지를 참조하는 pod 사양으로 Kubernetes 매니페스트를 만듭니다.

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. kustomization.yaml 파일에서 리소스로 매니페스트를 추가합니다.

    kustomize edit add resource pod.yaml
    
  5. 이미지 변환기를 사용하여 이미지의 다이제스트를 업데이트합니다.

    kustomize edit set image \
        gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    
  6. kustomization.yaml 파일에서 이미지 변환기를 확인합니다.

    cat kustomization.yaml
    

    파일은 다음과 같습니다.

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - pod.yaml
    images:
    - digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
      name: gcr.io/google-containers/echoserver
    
  7. 결과 매니페스트를 확인합니다.

    kustomize build .
    

    출력은 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        name: echoserver
        ports:
        - containerPort: 8080
    
  8. kustomize 변환기를 실행하고 결과 매니페스트를 한 번에 Kubernetes 클러스터에 적용하려면 --kustomize 플래그와 함께 kubectl apply 명령어를 사용하면 됩니다.

    kubectl apply --kustomize .
    

    출력을 나중에 적용하려면 kustomize build 명령어의 출력을 파일로 리디렉션할 수 있습니다.

gke-deploy 사용

gke-deployGoogle Kubernetes Engine(GKE)에서 사용하는 명령줄 도구입니다. gke-deploykubectl 명령줄 도구를 래핑하며 Google의 권장사항에 따라 만든 리소스를 수정할 수 있습니다.

gke-deploy 하위 명령어 prepare 또는 run을 사용하면 gke-deploy는 이미지 태그를 다이제스트로 확인하고 기본적으로 output/expanded/aggregated-resources.yaml 파일에 이미지 다이제스트와 함께 확장된 매니페스트를 저장합니다.

gke-deploy run을 사용하여 다이제스트에 대해 이미지 태그를 대체하고 확장된 매니페스트를 GKE 클러스터에 적용할 수 있습니다. 이 명령어가 편리하지만 배포 시에 이미지 태그가 대체되는 단점이 있습니다. 배포를 결정한 시간과 배포한 시간 사이에 태그와 연관된 이미지가 변경될 수 있으므로, 예기치 않은 이미지가 배포될 수 있습니다. 프로덕션 배포의 경우 매니페스트 생성 및 적용 단계를 개별적으로 수행하는 것이 좋습니다.

Kubernetes 배포 매니페스트에서 이미지 태그를 이미지 다이제스트로 바꾸려면 다음을 수행합니다.

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/gke-deploy
    cd ~/container-image-digests-tutorial/gke-deploy
    
  2. gke-deploy을 설치합니다.

    go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
    
  3. 1.10 태그를 사용하여 gcr.io/google-containers/echoserver 이미지를 참조하는 Kubernetes 배포 매니페스트를 만듭니다.

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  4. deployment.yaml 매니페스트를 기반으로 확장된 매니페스트를 생성합니다.

    gke-deploy prepare \
        --filename deployment.yaml \
        --image gcr.io/google-containers/echoserver:1.10 \
        --version 1.10
    
  5. 확장된 매니페스트를 확인합니다.

    cat output/expanded/aggregated-resources.yaml
    

    출력은 다음과 같습니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/managed-by: gcp-cloud-build-deploy
        app.kubernetes.io/version: "1.10"
      name: echo-deployment
      namespace: default
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
            app.kubernetes.io/managed-by: gcp-cloud-build-deploy
            app.kubernetes.io/version: "1.10"
        spec:
          containers:
          - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
            name: echoserver
            ports:
            - containerPort: 8080
    

    확장된 매니페스트에서 이미지 태그는 다이제스트로 바뀝니다.

    gke-deploy 명령어와 함께 사용한 --version 인수는 배포의 app.kubernetes.io/version 라벨 값과 확장된 매니페스트의 포드 템플릿 메타데이터를 설정합니다.

    Cloud Build에서 gke-deploy를 사용하는 방법은 gke-deploy용 Cloud Build 문서를 참조하세요.

ko 사용

koGo 컨테이너 이미지를 빌드하고 Kubernetes 클러스터에 배포하기 위한 명령줄 도구 및 라이브러리입니다. ko는 Docker 데몬을 사용하지 않고 이미지를 빌드하므로, Docker를 설치할 수 없는 환경에서 사용할 수 있습니다.

ko 하위 명령어 build는 이미지를 빌드하고 컨테이너 이미지 레지스트리에 게시하거나 로컬 Docker 데몬에 로드합니다.

ko 하위 명령어 resolve는 다음을 수행합니다.

  • --filename 인수를 사용하여 제공하는 Kubernetes 매니페스트의 image 필드에서 자리표시자를 찾아 빌드할 이미지를 식별합니다.
  • 이미지를 빌드하고 게시합니다.
  • image 값 자리표시자를 빌드된 이미지의 이름 및 다이제스트로 바꿉니다.
  • 확장된 매니페스트를 출력합니다.

ko 하위 명령어 apply, create, runresolve와 동일한 단계를 수행한 다음 확장된 매니페스트로 kubectl apply, create 또는 run을 실행합니다.

Go 소스 코드에서 이미지를 빌드하고 이미지의 다이제스트를 Kubernetes 배포 매니페스트에 추가하려면 다음을 수행합니다.

  1. Cloud Shell에서 이 섹션에서 만드는 파일을 저장할 디렉터리를 만들고 이동합니다.

    mkdir -p ~/container-image-digests-tutorial/ko
    cd ~/container-image-digests-tutorial/ko
    
  2. ko를 다운로드하고 이를 PATH에 추가합니다.

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    KO_VERSION=$(curl -sL https://api.github.com/repos/ko-build/ko/releases/latest | jq -r .tag_name | cut -c2-)
    curl -L "https://github.com/ko-build/ko/releases/download/v${KO_VERSION}/ko_${KO_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar -zxC ${HOME}/bin ko
    
  3. app라는 새 디렉터리에 모듈 이름 example.com/hello-world를 사용하여 Go 앱을 만듭니다.

    mkdir -p app/cmd/ko-example
    
    cd app
    
    go mod init example.com/hello-world
    
    cat << EOF > cmd/ko-example/main.go
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world")
    }
    EOF
    
  4. ko가 이미지 게시를 위해 사용하는 이미지 저장소를 정의합니다.

    export KO_DOCKER_REPO=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY
    

    이 예시에서는 Artifact Registry를 사용하지만 다른 컨테이너 이미지 레지스트리와 함께 ko를 사용할 수 있습니다.

  5. 앱에 대해 이미지를 빌드하고 게시하려면 다음 단계 중 하나를 수행합니다.

    • Go 기본 패키지에 대한 경로를 제공하여 앱에 대해 이미지를 빌드하고 게시합니다.

      ko build --base-import-paths ./cmd/ko-example
      

      선택적 인수 --base-import-pathsko가 기본 패키지 디렉터리의 짧은 이름을 이미지 이름으로 사용한다는 의미입니다.

      ko는 다음 형식으로 stdout에 이미지 이름 및 다이제스트를 출력합니다.

      LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
      

      이 출력에서 DIGEST는 이미지 다이제스트 값입니다.

    • ko를 사용하여 매니페스트 자리표시자를 빌드 및 게시하는 이미지의 다이제스트로 바꿉니다.

      1. Kubernetes pod 매니페스트를 만듭니다. 매니페스트는 image 필드의 값으로 ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE 자리표시자를 사용합니다.

        cat << EOF > ko-pod.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: ko://example.com/hello-world/cmd/ko-example
        EOF
        
      2. 앱의 이미지를 빌드 및 게시하고 매니페스트 자리표시자를 이미지 이름과 다이제스트로 바꿉니다.

        ko resolve --base-import-paths --filename ko-pod.yaml
        

        ko는 이미지 이름 및 다이제스트를 사용하여 매니페스트를 stdout에 출력합니다.

        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
        

        이 출력에서 DIGEST는 이미지 다이제스트 값입니다.

삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 튜토리얼에서 만든 Google Cloud 프로젝트를 삭제하는 것입니다. 또는 개별 리소스를 삭제할 수 있습니다.

프로젝트 삭제

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

리소스 삭제

이 튜토리얼에서 사용된 Google Cloud 프로젝트를 유지하려면 개별 리소스를 삭제합니다.

  1. Cloud Shell에서 이 튜토리얼에서 만든 파일을 삭제합니다.

    cd
    rm -rf ~/container-image-digests-tutorial
    
  2. Artifact Registry에서 컨테이너 이미지 저장소를 삭제합니다.

    gcloud artifacts repositories delete REPOSITORY \
        --location=LOCATION --async --quiet
    

다음 단계