Kustomize

Kustomize

Argo CD에서 Kustomize 애플리케이션을 정의하고 구성하는 방법을 다룹니다. 선언적 구문, 패치, 컴포넌트, 프라이빗 원격 base, 빌드 옵션, 커스텀 Kustomize 버전, Helm 차트 커스터마이징, 네임스페이스 설정을 설명합니다.

출처: 문서

본문

Kustomize

선언적(Declarative)

Kustomize 애플리케이션 매니페스트를 선언적 GitOps 방식으로 정의할 수 있습니다. 예시:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: kustomize-example
spec:
  project: default
  source:
    path: examples/helloWorld
    repoURL: 'https://github.com/kubernetes-sigs/kustomize'
    targetRevision: HEAD
  destination:
    namespace: default
    server: 'https://kubernetes.default.svc'

repoURLpath가 가리키는 위치에 kustomization.yaml 파일이 있으면 Argo CD는 Kustomize로 매니페스트를 렌더링합니다.

Kustomize에 대해 다음 구성 옵션이 제공됩니다:

  • namePrefix는 Kustomize 앱의 kustomization.yaml에서 namePrefix를 재정의합니다.
  • nameSuffix는 Kustomize 앱의 kustomization.yaml에서 nameSuffix를 재정의합니다.
  • images는 Kustomize 이미지 재정의 목록입니다.
  • replicas는 Kustomize replica 재정의 목록입니다.
  • commonLabels는 추가 라벨의 문자열 맵입니다.
  • labelWithoutSelector는 공통 라벨을 리소스 셀렉터에 적용해야 하는지 정의하는 불리언 값입니다. 또한 labelIncludeTemplates가 true로 설정되지 않으면 템플릿에서 공통 라벨을 제외합니다.
  • labelIncludeTemplates는 공통 라벨을 리소스 템플릿에 적용해야 하는지 정의하는 불리언 값입니다.
  • commonAnnotations는 추가 어노테이션의 문자열 맵입니다.
  • namespace는 Kubernetes 리소스 네임스페이스입니다.
  • commonAnnotationsEnvsubst는 어노테이션 값에서 환경 변수 대체를 활성화하는 불리언 값입니다.
  • patches는 인라인 업데이트를 지원하는 Kustomize 패치 목록입니다.
  • components는 Kustomize 컴포넌트 목록입니다.
  • ignoreMissingComponents는 존재하지 않는 컴포넌트를 kustomization 파일에 추가하지 않음으로써 컴포넌트가 로컬에 없을 때 kustomize가 실패하는 것을 방지합니다.
  • forceCommonLabels는 불리언 값입니다. true일 때 Argo CD는 --force를 kustomize edit add label에 전달하여 kustomization.yaml의 기존 commonLabels/labels 항목을 교체할 수 있게 합니다. false일 때 라벨 키가 이미 존재하면 생성이 실패합니다.
  • forceCommonAnnotations는 불리언 값입니다. true일 때 Argo CD는 --force를 kustomize edit add annotation에 전달하여 kustomization.yaml의 기존 commonAnnotations 항목을 교체할 수 있게 합니다. false일 때 어노테이션 키가 이미 존재하면 생성이 실패합니다.

Kustomize를 overlay와 함께 사용하려면 path를 overlay로 지정하세요.

: 리소스를 생성하고 있다면 IgnoreExtraneous compare option으로 생성된 리소스를 무시하는 방법을 읽어보세요.

패치(Patches)

패치는 Argo CD 애플리케이션에서 인라인 구성을 사용해 리소스를 kustomize하는 방법입니다. patches는 해당 Kustomization과 동일한 로직을 따릅니다. 기존 Kustomization 파일을 대상으로 하는 모든 패치는 병합됩니다.

이 Kustomize 예시는 argoproj/argocd-example-apps 저장소의 /kustomize-guestbook 폴더에서 매니페스트를 가져오고, Deployment를 패치해 컨테이너에 포트 443을 사용하게 합니다.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
  name: kustomize-inline-example
namespace: test1
resources:
  - https://github.com/argoproj/argocd-example-apps//kustomize-guestbook/
patches:
  - target:
      kind: Deployment
      name: guestbook-ui
    patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/ports/0/containerPort
        value: 443

Application은 인라인 kustomize.patches 구성을 사용해 동일한 작업을 수행합니다.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: kustomize-inline-guestbook
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: test1
    server: https://kubernetes.default.svc
  project: default
  source:
    path: kustomize-guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: master
    kustomize:
      patches:
        - target:
            kind: Deployment
            name: guestbook-ui
          patch: |-
            - op: replace
              path: /spec/template/spec/containers/0/ports/0/containerPort
              value: 443

인라인 kustomize 패치는 ApplicationSets와도 잘 작동합니다. 각 클러스터에 대한 패치나 overlay를 유지하는 대신, 이제 Application 템플릿에서 패치를 수행하고 생성기의 속성을 활용할 수 있습니다. 예를 들어 external-dns에서 txt-owner-id를 클러스터 이름으로 설정하는 경우입니다.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: external-dns
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - clusters: {}
  template:
    metadata:
      name: 'external-dns'
    spec:
      project: default
      source:
        repoURL: https://github.com/kubernetes-sigs/external-dns/
        targetRevision: v0.14.0
        path: kustomize
        kustomize:
          patches:
          - target:
              kind: Deployment
              name: external-dns
            patch: |-
              - op: add
                path: /spec/template/spec/containers/0/args/3
                value: --txt-owner-id={{.name}}   # patch using attribute from generator
      destination:
        name: 'in-cluster'
        namespace: default

컴포넌트(Components)

Kustomize 컴포넌트는 리소스와 패치를 함께 캡슐화합니다. 이는 Kubernetes 애플리케이션에서 구성을 모듈화하고 재사용하는 강력한 방법을 제공합니다. Kustomize에 존재하지 않는 컴포넌트 디렉터리가 전달되면 오류가 발생합니다. 누락된 컴포넌트 디렉터리는 ignoreMissingComponents로 무시(즉, Kustomize에 전달하지 않음)할 수 있습니다. 이는 [default/override pattern]을 구현할 때 특히 유용합니다.

Argo CD 밖에서 컴포넌트를 활용하려면 Application이 참조하는 kustomization.yaml에 다음을 추가해야 합니다. 예:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
...
components:
- ../component

v2.10.0에서 컴포넌트에 대한 지원이 추가되어, 이제 Application에서 직접 컴포넌트를 참조할 수 있습니다:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: application-kustomize-components
spec:
  ...
  source:
    path: examples/application-kustomize-components/base
    repoURL: https://github.com/my-user/my-repo
    targetRevision: main

    # This!
    kustomize:
      components:
        - ../component  # relative to the kustomization.yaml (`source.path`).
      ignoreMissingComponents: true

프라이빗 원격 base (Private Remote Bases)

(a) HTTPS이고 사용자 이름/비밀번호가 필요하거나 (b) SSH이고 SSH 개인 키가 필요한 원격 base가 있다면, 그것들은 앱의 저장소에서 해당 값을 상속받습니다.

이것은 원격 base가 동일한 자격 증명/개인 키를 사용할 때 작동합니다. 다른 것을 사용하면 작동하지 않습니다. 보안상의 이유로 앱은 자신의 저장소(다른 팀이나 사용자의 저장소가 아닌)에 대해서만 알며, Argo CD가 다른 프라이빗 저장소를 알고 있어도 그에 접근할 수 없습니다.

프라이빗 저장소에 대해 더 읽어보세요.

kustomize build 옵션/파라미터

기본 Kustomize 버전의 kustomize build에 빌드 옵션을 제공하려면 argocd-cm ConfigMap의 kustomize.buildOptions 필드를 사용하세요. 버전별 빌드 옵션을 등록하려면 kustomize.buildOptions.<version>을 사용하세요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
    kustomize.buildOptions: --load-restrictor LoadRestrictionsNone
    kustomize.buildOptions.v4.4.0: --output /tmp

kustomize.buildOptions를 수정한 후 변경 사항이 적용되도록 ArgoCD를 재시작해야 할 수 있습니다.

커스텀 Kustomize 버전

Argo CD는 여러 Kustomize 버전을 동시에 사용하는 것을 지원하며 애플리케이션별로 필요한 버전을 지정합니다. 추가 버전을 추가하려면 필요한 버전을 번들한 다음 argocd-cm ConfigMap의 kustomize.path.<version> 필드를 사용해 번들된 추가 버전을 등록하세요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
    kustomize.path.v3.5.1: /custom-tools/kustomize_3_5_1
    kustomize.path.v3.5.4: /custom-tools/kustomize_3_5_4

새 버전이 구성되면 Application 스펙에서 다음과 같이 참조할 수 있습니다:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
spec:
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: kustomize-guestbook

    kustomize:
      version: v3.5.4

추가로 애플리케이션 kustomize 버전은 Application 세부 정보 페이지의 Parameters 탭이나 다음 CLI 명령으로 구성할 수 있습니다:

argocd app set <appName> --kustomize-version v3.5.4

빌드 환경

Kustomize 앱은 렌더링된 매니페스트를 변경하기 위해 구성 관리 플러그인과 함께 사용할 수 있는 표준 빌드 환경에 접근합니다.

Argo CD Application 매니페스트에서 이러한 빌드 환경 변수를 사용할 수 있습니다. Application 매니페스트에서 .spec.source.kustomize.commonAnnotationsEnvsubsttrue로 설정해 활성화할 수 있습니다.

예를 들어 다음 Application 매니페스트는 app-source 어노테이션을 Application의 이름으로 설정합니다:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook-app
  namespace: argocd
spec:
  project: default
  destination:
    namespace: demo
    server: https://kubernetes.default.svc
  source:
    path: kustomize-guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
    kustomize:
      commonAnnotationsEnvsubst: true
      commonAnnotations:
        app-source: ${ARGOCD_APP_NAME}
  syncPolicy:
    syncOptions:
      - CreateNamespace=true

Helm 차트 커스터마이징

Kustomize로 Helm 차트를 렌더링하는 것이 가능합니다. 그러려면 kustomize build 명령에 --enable-helm 플래그를 전달해야 합니다. 이 플래그는 Argo CD 안의 Kustomize 옵션에 포함되지 않습니다. Argo CD 애플리케이션에서 Kustomize를 통해 Helm 차트를 렌더링하려면 두 가지 옵션이 있습니다: 커스텀 플러그인을 만들거나 argocd-cm ConfigMap을 수정해 모든 Kustomize 애플리케이션에 전역적으로 --enable-helm 플래그를 포함시키는 것입니다:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  kustomize.buildOptions: --enable-helm

매니페스트의 네임스페이스 설정

spec.destination.namespace 필드는 Kustomize가 생성한 매니페스트에서 네임스페이스가 누락된 경우에만 네임스페이스를 추가합니다. 또한 kubectl을 사용해 네임스페이스를 설정하므로 일부 리소스(예: 커스텀 리소스)의 네임스페이스 필드를 놓칠 수 있습니다. 이런 경우 ClusterRoleBinding.rbac.authorization.k8s.io "example" is invalid: subjects[0].namespace: Required value. 같은 오류가 발생할 수 있습니다.

Kustomize를 직접 사용해 누락된 네임스페이스를 설정하면 이 문제를 해결할 수 있습니다. spec.source.kustomize.namespace를 설정하면 Kustomize가 네임스페이스 필드를 주어진 값으로 설정하도록 지시합니다.

spec.destination.namespacespec.source.kustomize.namespace가 모두 설정되면 Argo CD는 후자, 즉 Kustomize가 설정한 네임스페이스 값을 따릅니다.

더 알아보기 (Learn more)