리소스 변형

이 페이지에서는 정책 컨트롤러를 사용하여 리소스를 변형하는 방법을 설명합니다. 이는 기본값 설정 등의 작업을 수행할 때 유용합니다. 예를 들어 특정 네임스페이스에 있는 모든 리소스의 라벨을 삽입하거나, 아직 설정되지 않은 경우 포드의 imagePullPolicyAlways로 기본 설정할 수 있습니다.

변형 사용 설정

콘솔

변형을 사용 설정하려면 다음 단계를 완료하세요.

  1. Google Cloud 콘솔의 상황 관리 섹션에서 GKE Enterprise 정책 페이지로 이동합니다.

    정책으로 이동

  2. 설정 탭의 클러스터 테이블에서 구성 수정 열의 수정 을 선택합니다.
  3. 정책 컨트롤러 구성 수정 메뉴를 확장합니다.
  4. 변형 웹훅 사용 설정 체크박스를 선택합니다.
  5. 변경사항 저장을 선택합니다.

gcloud 정책 컨트롤러

변형을 사용 설정하려면 다음 명령어를 실행합니다.

gcloud container fleet policycontroller update \
    --memberships=MEMBERSHIP_NAME \
    --mutation

MEMBERSHIP_NAME을 변형을 사용 설정할 등록된 클러스터의 멤버십 이름으로 바꿉니다. 여러 멤버십을 쉼표로 구분하여 지정할 수 있습니다.

gcloud ConfigManagement

config-management 리소스에서 spec.policyController.mutation.enabledtrue로 설정하여 변형을 사용 설정해야 합니다.

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
spec:
  policyController:
    enabled: true
     mutation:
      enabled: true 

gcloud CLI 명령어를 사용하는 경우 다음 예시와 같이 알파 버전을 사용하여 변형을 사용 설정해야 합니다.

  # apply-spec.yaml

  applySpecVersion: 1
  spec:
    policyController:
      enabled: true
      mutationEnabled: true

apply-spec.yaml 파일을 만든 후 다음 명령어를 실행하여 구성을 적용하세요.

  gcloud alpha container fleet config-management apply \
      --membership=MEMBERSHIP_NAME \
      --config=CONFIG_YAML_PATH \
      --project=PROJECT_ID

다음을 바꿉니다.

  • MEMBERSHIP_NAME: 사용할 정책 컨트롤러 설정이 있는 등록된 클러스터의 멤버십 이름
  • CONFIG_YAML_PATH: apply-spec.yaml 파일의 경로
  • PROJECT_ID: 프로젝트 ID

정의

  • 변형자: 정책 컨트롤러의 변형 동작을 구성하는 데 도움이 되는 Kubernetes 리소스입니다.
  • 시스템: 여러 변형자의 정렬입니다.

변형 예시

다음 예시에서는 모든 포드의 모든 컨테이너에 대한 imagePullPolicyAlways로 설정하는 변형자를 보여줍니다.

# set-image-pull-policy.yaml

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: always-pull-image
spec:
  applyTo:
  - groups: [""]
    kinds: ["Pod"]
    versions: ["v1"]
  location: "spec.containers[name: *].imagePullPolicy"
  parameters:
    assign:
      value: "Always"

이 예시에는 표준 Kubernetes 메타데이터 필드(apiVersion, kind, metadata.name)가 있지만 spec은 변형의 동작이 구성되는 위치입니다.

spec.applyTo는 변형자를 지정된 리소스에 바인딩합니다. 객체에서 특정 필드를 변경하기 때문에 해당 객체의 스키마가 암시적으로 정의됩니다. 예를 들어 현재 변형자는 Namespace 리소스에 할당된 경우 효과가 없습니다. 따라서 정책 컨트롤러에서 이 변형자가 관련된 스키마가 무엇인지 알 수 있도록 이 필드가 필요합니다. 이 목록에서 누락된 GroupVersionKinds는 변형되지 않습니다.

spec.location은 수정할 필드를 알려줍니다. 여기에서는 glob(*)를 사용하여 컨테이너 목록의 모든 항목을 수정할지를 나타냅니다. location 필드로 순회될 수 있는 목록 유형만 맵 유형 목록이고 맵의 키 필드를 지정해야 합니다. 맵 유형 목록은 Kubernetes 구성입니다. 자세한 내용은 Kubernetes 문서를 참조하세요.

spec.parameters.assign.valuelocation에 할당할 값입니다. 이 필드는 유형이 지정되지 않으며 모든 값을 사용할 수 있습니다. 하지만 Kubernetes는 여전히 변형 후 요청의 유효성을 검사하므로 수정 중인 객체에 잘못된 스키마가 포함된 값을 삽입하면 요청이 거부됩니다.

작업에 변형자 사용

작업이나 CronJob을 구성하는 경우 다음 예시와 같이 버전과 그룹을 별도로 지정해야 합니다.

applyTo:
- groups: ["batch"]
  kind: ["Job"]
  versions: ["v1"]

작업에 변형자를 사용하면 기존 작업은 수정되지 않는 한 변경되지 않습니다. 작업을 수정하면 변형 웹훅에 대한 요청이 트리거되고 변형이 발생합니다.

실행 흐름

Kubernetes 변형 웹훅에 대해 이해해야 할 가장 중요한 개념은 재호출 정책일 것입니다. 한 변형자의 출력이 다른 변형자의 작동 방식을 변경할 수 있기 때문입니다. 예를 들어 새 사이드카 컨테이너를 추가하면 모든 컨테이너의 이미지 가져오기 정책을 설정하는 변형자에 이제 변경할 새 컨테이너가 포함됩니다.

실제로 특정 요청 컨트롤러의 변형 웹훅에 대해 2회 이상 호출될 수 있다는 의미입니다.

지연 시간을 줄이기 위해 정책 컨트롤러는 추가적인 HTTP 요청을 피하기 위해 자신을 다시 호출합니다. 즉, 사이드카 삽입 및 이미지 가져오기 정책에는 예상한 결과가 있습니다.

정책 컨트롤러의 변형 루틴은 리소스가 '수렴'될 때까지 계속 재호출되므로 추가 반복은 더 이상 영향이 없습니다.

위치 구문

위치 구문은 점(.) 접근자를 사용하여 필드를 순회합니다. 키가 지정된 목록의 경우 사용자는 [<key>: <value>] 구문을 사용하여 목록의 개별 객체를 참조하거나 [<key>: *]를 사용하여 목록의 모든 객체를 참조할 수 있습니다.

값과 필드는 작은따옴표(') 또는 큰따옴표(")로 묶을 수 있습니다. 이는 마침표나 공백과 같은 특수문자가 있는 경우에 필요합니다.

따옴표로 묶인 값에서 특수문자를 \ 프리픽스를 사용하여 이스케이프할 수 있습니다. "Use \" to escape and \\\" to escape"Use " to escape and \" to escape로 변환됩니다.

다음은 v1/Pod 리소스의 몇 가지 예시입니다.

  • spec.priorityspec.priority를 참조합니다.
  • spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnlyfoo 컨테이너의 /my/mount 마운트에서 readOnly 필드를 참조합니다.
  • spec.containers[name: *].volumeMounts[mountPath: "/my/mount"].readOnly는 모든 컨테이너의 /my/mount 마운트에서 readOnly 필드를 참조합니다.

현재 리소스에 없는 위치를 참조하면 위치가 기본적으로 생성됩니다. 이 동작은 경로 테스트를 통해 구성할 수 있습니다.

경로 테스트

이미 존재하는 값을 수정하지 않고 기본값을 적용하려면 어떻게 해야 할까요? 모든 컨테이너에 대해 /secure-mount를 읽기 전용으로 설정하되, 아직 컨테이너가 없는 경우 /secure-mount를 만들지 않는 것이 좋습니다. 경로 테스트를 통해 이러한 작업 중 하나를 수행할 수 있습니다.

다음은 imagePullPolicy가 이미 설정되어 있는 경우 변형을 방지되는 예시입니다.

# set-image-pull-policy.yaml

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: always-pull-image
spec:
  applyTo:
  - groups: [""]
    kinds: ["Pod"]
    versions: ["v1"]
  location: "spec.containers[name: *].imagePullPolicy"
  parameters:
    assign:
      value: "Always"
    pathTests:
    - subPath: "spec.containers[name: *].imagePullPolicy"
      condition: "MustNotExist"

다음은 빈 sidecar 컨테이너가 아직 존재하지 않는 경우 이를 만들지 않는 또 다른 예시입니다.

# set-image-pull-policy.yaml

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: always-pull-image
spec:
  applyTo:
  - groups: [""]
    kinds: ["Pod"]
    versions: ["v1"]
  location: 'spec.containers[name: "sidecar"].imagePullPolicy'
  parameters:
    assign:
      value: "Always"
    pathTests:
    - subPath: 'spec.containers[name: "sidecar"]'
      condition: "MustExist"

필요한 경우 여러 경로 테스트를 지정할 수 있습니다.

subPathlocation의 프리픽스이거나 동일해야 합니다.

condition에 유효한 값은 MustExistMustNotExist뿐입니다.

일치

변형자는 제약조건과 동일한 기준을 사용하여 일치시킬 수도 있습니다.

변형자

현재 변형자에는 AssignAssignMetadata의 두 가지 종류가 있습니다.

Assign

Assign은 리소스의 metadata 필드 외부에 있는 모든 값을 변경할 수 있습니다. 모든 GroupVersionKinds에는 고유한 스키마가 있으므로 특정 GroupVersionKinds 집합에 바인딩되어야 합니다.

여기에는 다음 스키마가 포함됩니다.

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: always-pull-image
spec:
  applyTo:
  - groups: [""]
    kinds: ["Pod"]
    versions: ["v1"]
  match:
    kinds: # redundant because of `applyTo`, but left in for consistency
      - apiGroups: ["*"]
        kinds: ["*"]
    namespaces: ["my-namespace"]
    scope: "Namespaced" # or "Cluster"
    excludedNamespaces: ["some-other-ns"]
    labelSelector:
      matchLabels:
        mutate: "yes"
      matchExpressions:
      - key: "my-label"
        operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
        values: ["my-value"]
    namespaceSelector:
      matchLabels:
        mutate: "yes"
      matchExpressions:
      - key: "my-label"
        operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
        values: ["my-value"]
  location: "spec.containers[name: *].imagePullPolicy"
  parameters:
    pathTests:
    - subPath: 'spec.containers[name: "sidecar"]' # must be a prefix of `location`
      condition: "MustExist" # or "MustNotExist"
    - subPath: "spec.containers[name: *].imagePullPolicy"
      condition: "MustNotExist"
    assign:
      value: "Always" # any type can go here, not just a string

AssignMetadata

AssignMetadata는 새 메타데이터 라벨을 추가할 수 있습니다. 기존 메타데이터 라벨의 값은 변경할 수 없습니다. 그렇지 않으면 무기한 반복되어 요청이 시간 초과될 수 있는 변형자 시스템이 작성될 수 있습니다.

모든 리소스가 동일한 metadata 스키마를 공유하므로 AssignMetadata가 적용되는 리소스를 지정할 필요가 없습니다.

또한 AssignMetadata는 그다지 많은 일을 하는 것이 허용되지 않기 때문에 스키마가 조금 더 간단합니다.

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: AssignMetadata
metadata:
  name: set-team-name
spec:
  match:
    kinds:
      - apiGroups: ["*"]
        kinds: ["*"]
    namespaces: ["my-namespace"]
    scope: "Namespaced" # or "Cluster"
    excludedNamespaces: ["some-other-ns"]
    labelSelector:
      matchLabels:
        mutate: "yes"
      matchExpressions:
      - key: "my-label"
        operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
        values: ["my-value"]
    namespaceSelector:
      matchLabels:
        mutate: "yes"
      matchExpressions:
      - key: "my-label"
        operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
        values: ["my-value"]
  location: "metadata.labels.team" # must start with `metadata.labels`
  parameters:
    assign:
      value: "Always" # any type can go here, not just a string

권장사항

Kubernetes 주의사항

Kubernetes 문서에서는 변형 웹훅 사용에 대한 몇 가지 중요한 고려사항을 보여줍니다. 정책 컨트롤러가 Kubernetes 허용 웹훅으로 작동하기 때문에 해당 조언이 여기에 적용됩니다.

정책 컨트롤러의 변형 구문은 멱등성을 포함한 변형 웹훅과 관련된 운영 문제를 쉽게 준수할 수 있도록 설계되었습니다.

변형자 작성

원자성

각 변형자는 가능한 독립되어 있으면 좋습니다. Kubernetes가 eventual consistency를 가지므로 특정 변형자는 작업을 수행하기 위해 이전에 인식된 두 번째 변형자에 의지해서는 안 됩니다. 예를 들어 사이드카를 추가할 때는 전체 사이드카를 추가해야 하며, 여러 변형자를 통해 부분적으로 구성하지 않도록 하세요.

검증

적용할 조건이 있는 경우 변형자에 일치하는 제약조건이 있는 것이 좋습니다. 이렇게 하면 위반 요청이 거부되고 기존 위반은 감사에서 반드시 감지되게 할 수 있습니다.

응급 복구

변형은 Kubernetes 변형 웹훅으로 구현됩니다. 검증 웹훅과 동일한 방법으로 저장될 수 있지만 관련 리소스는 gatekeeper-mutating-webhook-configuration이라는 MutatingWebhookConfiguration입니다.

다음 단계