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

이미지 구성

원문 보기 위키 갱신

이미지 구성 (ImageConfig)

ImageConfig는 Crossplane 패키지 이미지의 구성을 중앙에서 제어하기 위한 API예요. 다른 객체가 참조할 필요 없이 이미지에 대한 패키지 관리자 동작을 전역적으로 구성할 수 있게 해줘요.

출처: 문서

본문

이미지 참조 매칭

spec.matchImages는 ImageConfig가 적용되는 이미지 참조 목록이에요. 목록의 각 항목은 매칭할 이미지 참조의 유형과 구성을 지정해요. 지원되는 유형은 Prefix뿐이며, 이미지 참조의 접두사를 매칭해요. 와일드카드는 지원되지 않아요. type은 기본값이 Prefix이므로 생략할 수 있어요.

하나의 이미지 참조에 여러 ImageConfig가 매칭되면 가장 긴 매칭 접두사를 가진 것이 선택돼요. 가장 긴 매칭 접두사가 같은 ImageConfig가 여러 개 있으면 그중 하나가 임의로 선택돼요. 이 상황은 서로 다른 ImageConfig 리소스의 matchImages 목록에 겹치는 접두사가 있을 때만 발생하므로, 이런 일은 피해야 해요.

풀 시크릿 구성

ImageConfig를 사용해 Crossplane 패키지 관리자 레지스트리 클라이언트가 레지스트리와 상호작용할 때마다(예: 의존성 해결이나 이미지 풀 시) 풀 시크릿을 주입할 수 있어요.

다음 예에서 acme-packages라는 ImageConfig 리소스는 registry1.com/acme-co/ 접두사의 이미지에 대해 레지스트리와 상호작용할 때마다 acme-registry-credentials라는 풀 시크릿을 주입하도록 구성돼요.

apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: acme-packages
spec:
  matchImages:
    - type: Prefix
      prefix: registry1.com/acme-co/
  registry:
    authentication:
      pullSecretRef:
        name: acme-registry-credentials

spec.registry.authentication.pullSecretRef는 레지스트리 클라이언트에 주입돼야 하는 풀 시크릿에 대한 참조예요. 시크릿은 kubernetes.io/dockerconfigjson 유형이어야 하며 Crossplane 설치 네임스페이스(일반적으로 crossplane-system)에 있어야 해요. 다음 명령으로 시크릿을 만들 수 있어요:

kubectl -n crossplane-system create secret docker-registry acme-registry-credentials --docker-server=registry1.com --docker-username=<사용자> --docker-password=<비밀번호>

서명 검증 구성

중요: 서명 검증은 알파 기능이며 --enable-signature-verification 기능 플래그로 활성화해야 해요.

ImageConfig로 이미지에 대한 서명 검증을 구성할 수 있어요. 서명 검증을 활성화하면 패키지 관리자는 각 이미지를 풀기 전에 서명을 검증해요. 서명이 유효하지 않으면 패키지 관리자는 패키지 배포를 거부해요.

다음 예에서 verify-acme-packages라는 ImageConfig 리소스는 registry1.com/acme-co/configuration-foo와 registry1.com/acme-co/configuration-bar 접두사 이미지의 서명 검증을 구성해요.

아래 예에서 verify-acme-packages라는 ImageConfig 리소스는 registry1.com/acme-co/configuration-foo와 registry1.com/acme-co/configuration-bar 접두사 이미지의 서명을 검증하도록 설정됐어요.

apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: verify-acme-packages
spec:
  matchImages:
    - type: Prefix
      prefix: registry1.com/acme-co/configuration-foo
    - type: Prefix
      prefix: registry1.com/acme-co/configuration-bar
  verification:
    provider: Cosign
    cosign:
      authorities:
        - name: verify acme packages
          keyless:
            identities:
              - issuer: https://token.actions.githubusercontent.com
                subject: https://github.com/acme-co/crossplane-packages/.github/workflows/supplychain.yml@refs/heads/main
          attestations:
            - name: verify attestations
              predicateType: spdxjson

spec.verification.provider는 서명 검증 공급자를 지정해요. 지원되는 공급자는 Cosign뿐이에요. spec.verification.cosign에는 Cosign 공급자 구성이 들어 있어요. authorities 필드에는 이미지에 서명하는 권한(authority) 구성이 들어 있어요. attestations 필드에는 이미지의 증명(attestation) 검증 구성이 들어 있어요.

ImageConfig API는 Sigstore의 Policy Controller와 동일한 API 형태를 따르고 있어요. Crossplane은 처음에 Policy Controller 구성 옵션의 일부만 지원하며, 지원되는 옵션과 설명은 ImageConfig 리소스의 API 참조에서 확인할 수 있어요.

여러 권한이 제공되면 패키지 관리자는 유효한 서명을 찾을 때까지 각 권한에 대해 서명을 검증해요. 어느 권한의 서명이라도 유효하면 패키지 관리자는 이미지를 수락해요. 마찬가지로 여러 ID나 증명이 제공되면 패키지 관리자는 유효한 일치 항목을 찾을 때까지 검증하고, 어느 것도 일치하지 않으면 실패해요.

이미지 참조를 ImageConfig에 매칭하는 방식은 앞서 설명한 풀 시크릿 구성과 유사해요.

서명 검증 상태 확인

서명 검증을 활성화하면 해당 컨트롤러가 패키지 리비전 리소스에 Verified 유형의 조건으로 검증 상태를 보고해요. 이 조건은 서명 검증이 성공했는지, 실패했는지, 건너뛰었는지, 아니면 오류로 불완전했는지를 나타내요.

예시 조건

검증 건너뜀: 서명 검증 구성이 있는 매칭 ImageConfig가 없어 패키지 관리자가 패키지 리비전의 서명 검증을 건너뛰었어요.

  - lastTransitionTime: "2024-10-23T16:38:51Z"
    reason: SignatureVerificationSkipped
    status: "True"
    type: Verified

검증 성공: 패키지 관리자가 패키지 리비전의 이미지 서명을 성공적으로 검증했어요.

  - lastTransitionTime: "2024-10-23T16:43:05Z"
    message: Signature verification succeeded with ImageConfig named "verify-acme-packages"
    reason: VerificationSucceeded
    status: "True"
    type: Verified

검증 실패: 패키지 관리자가 패키지 리비전의 이미지 서명 검증에 실패했어요.

  - lastTransitionTime: "2024-10-23T16:42:44Z"
    message: 'Signature verification failed with ImageConfig named "verify-acme-packages":
      [signature keyless validation failed for authority verify acme packages
      for registry1.com/acme-co/configuration-foo:v0.2.0: no signatures found: ]'
    reason: SignatureVerificationFailed
    status: "False"
    type: Verified

검증 불완전: 패키지 관리자가 패키지 리비전의 이미지 서명을 검증하는 동안 오류가 발생했어요.

  - lastTransitionTime: "2024-10-23T16:44:22Z"
    message: 'Error occurred during signature verification cannot get image verification
      config: cannot get cosign verification config: no data found for key "cosign.pub"
      in secret "cosign-public-key"'
    reason: SignatureVerificationIncomplete
    status: "False"
    type: Verified

패키지 리비전 리소스, 즉 ProviderRevision, ConfigurationRevision, FunctionRevision에서 이 조건을 볼 수 없다면 기능을 활성화했는지 확인하세요.

패키지 런타임 구성

ImageConfig로 패턴과 일치하는 패키지(직접 설치됐든 의존성으로 설치됐든 관계없이)에 DeploymentRuntimeConfig를 지정할 수 있어요. 여기에는 직접 설치된 패키지와 의존성으로 설치된 패키지가 모두 포함돼요.

spec.runtime 필드는 이미지 접두사와 일치하는 모든 패키지에 적용되는 DeploymentRuntimeConfig를 지정할 수 있게 해줘요. 특정 레지스트리나 조직의 모든 패키지(의존성 포함)에 일관된 런타임 구성을 적용할 수 있어요.

우선순위 (Precedence)

ImageConfig 런타임과 패키지 수준의 runtimeConfigRef가 모두 지정된 경우 ImageConfig 런타임이 우선해요.

예시

다음 예에서 ImageConfig는 필수 어노테이션과 파드 라벨이 있는 ServiceAccount를 지정해 함수 registry1.com/acme-co/my-function이 Azure Workload Identity를 사용하도록 구성해요:

apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: function-workload-identity
spec:
  matchImages:
    - prefix: registry1.com/acme-co/my-function
  runtime:
    configRef:
      name: azure-workload-identity
---
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
  name: azure-workload-identity
spec:
  serviceAccountTemplate:
    metadata:
      annotations:
        azure.workload.identity/client-id: "12345678-1234-1234-1234-123456789012"
  deploymentTemplate:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    spec:
      selector: {}
      template:
        metadata:
          labels:
            azure.workload.identity/use: "true"
        spec:
          containers:
            - name: package-runtime
              args: []

이 구성으로 함수 registry1.com/acme-co/my-function은 직접 설치됐든 Configuration의 의존성으로 설치됐든 azure-workload-identity 런타임 구성을 사용해요.

디버깅

패키지 관리자가 ImageConfig 런타임 구성을 패키지에 적용하면 ConfigureRuntime 이유로 패키지 status의 appliedImageConfigRefs 필드에 항목을 추가해요:

kubectl get functionrevisions my-function .. -o yaml

...
status:
  appliedImageConfigRefs:
  - name: function-workload-identity
    reason: ConfigureRuntime
...

이미지 경로 재작성

ImageConfig로 패키지 이미지를 사설 레지스트리 같은 대체 위치에서 풀 수 있어요. spec.rewriteImages는 매칭된 이미지의 경로를 어떻게 재작성할지 지정해요.

접두사 교체만 지원돼요. spec.rewriteImage.prefix에 지정된 접두사가 matchImages에서 매칭된 접두사를 대체해요. 예를 들어 다음 ImageConfig는 xpkg.crossplane.io 접두사를 가진 모든 이미지의 xpkg.crossplane.io를 registry1.com으로 교체해요.

apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: private-registry-rewrite
spec:
  matchImages:
    - prefix: xpkg.crossplane.io
  rewriteImage:
    prefix: registry1.com

이 예에서 프로바이더 패키지 xpkg.crossplane.io/crossplane-contrib/provider-nop:v0.4.0를 설치하면 패키지 관리자는 registry1.com/crossplane-contrib/provider-nop:v0.4.0에서 프로바이더를 풀게 돼요.

ImageConfig로 이미지 경로를 재작성하는 것은 패키지를 사설 레지스트리로 미러링할 때 유용해요. 패키지와 그 모든 의존성을 같은 레지스트리에서 풀 수 있기 때문이에요. 예를 들어 프로바이더 xpkg.crossplane.io/crossplane-contrib/provider-aws-s3는 xpkg.crossplane.io/crossplane-contrib/provider-family-aws에 의존해요. 패키지를 registry1.com의 자신의 레지스트리로 미러링하고 ImageConfig 없이 설치하면 패키지 관리자는 여전히 xpkg.crossplane.io에서 의존성을 풀려고 시도해요. 앞선 ImageConfig를 사용하면 의존성은 registry1.com에서 풀려요.

ImageConfig로 이미지 경로를 재작성해도 패키지 리소스의 spec.package 필드는 바뀌지 않아요. 재작성된 경로는 status.resolvedPackage 필드에 기록돼요. 앞선 예는 다음 결과를 낳아요:

kubectl describe provider crossplane-contrib-provider-family-aws
...
Spec:
  ...
  Package:                        xpkg.crossplane.io/crossplane-contrib/provider-family-aws:v1.22.0
Status:
  ...
  Resolved Package:        registry1.com/crossplane-contrib/provider-family-aws:v1.22.0

다른 작업과의 상호작용

팁: 이미지 재작성은 항상 다른 ImageConfig 작업보다 먼저 수행돼요. 재작성과 함께 풀 시크릿이나 서명 검증도 구성하려면 해당 ImageConfig 리소스가 재작성된 이미지 경로와 일치해야 해요.

예를 들어 xpkg.crossplane.io에서 registry1.com으로 패키지를 미러링하고 registry1.com에 대한 풀 시크릿을 구성해야 한다면 ImageConfig 리소스 두 개가 필요해요:

# Rewrite xpkg.crossplane.io -> registry1.com
---
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: private-registry-rewrite
spec:
  matchImages:
    - prefix: xpkg.crossplane.io
  rewriteImage:
    prefix: registry1.com

# Configure pull secrets for registry1.com
---
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: private-registry-auth
spec:
  matchImages:
    - type: Prefix
      prefix: registry1.com
  registry:
    authentication:
      pullSecretRef:
        name: private-registry-credentials

디버깅

패키지 관리자가 패키지의 ImageConfig를 선택하면 ImageConfigSelection 이유와 선택된 ImageConfig 이름 및 주입된 풀 시크릿이 포함된 이벤트를 내보내요. 이 이벤트는 패키지 및 패키지 리비전 리소스 모두에서 찾을 수 있어요. 패키지 관리자는 패키지 status의 appliedImageConfigRefs 필드도 업데이트해 각 ImageConfig가 선택된 목적을 보여줘요.

예를 들어 다음 이벤트와 status는 acme-packages라는 ImageConfig가 acme-configuration-foo라는 구성에 풀 시크릿을 제공하는 데 사용됐음을 보여줘요:

kubectl describe configuration acme-configuration-foo
...
Status:
  Applied Image Config Refs:
    Name:    acme-packages
    Reason:  SetImagePullSecret
...
Events:
  Type     Reason                Age                From                                              Message
  ----     ------                ----               ----                                              -------
  Normal   ImageConfigSelection  45s                packages/configuration.pkg.crossplane.io          Selected pullSecret "acme-registry-credentials" from ImageConfig "acme-packages" for registry authentication

예상한 이벤트와 appliedImageConfigRefs 항목을 찾을 수 없다면, 이미지 참조의 접두사가 클러스터의 어떤 ImageConfig 리소스의 matchImages 목록과 일치하는지 확인하세요.

더 알아보기 (Learn more)