제약조건 만들기

이 페이지에서는 정책 컨트롤러 제약조건을 정의하는 방법을 보여줍니다.

정책 컨트롤러를 사용하면 하나 이상의 제약조건 객체를 정의하여 Kubernetes 클러스터에 정책을 적용할 수 있습니다. 제약조건이 설치되면 API 서버에 대한 요청이 제약조건과 대조하여 점검되며 이를 준수하지 않으면 거부됩니다. 기존의 비준수 리소스는 감사 시간에 보고됩니다.

모든 제약조건은 제약조건의 스키마와 논리를 정의하는 제약조건 템플릿으로 뒷받침됩니다. Google 및 타사에서 제공되는 제약조건 템플릿도 있고 직접 작성할 수도 있습니다. 새 템플릿을 만드는 방법에 대한 자세한 내용은 제약조건 템플릿 만들기를 참조하세요.

시작하기 전에

제약조건 템플릿 라이브러리 사용

제약조건을 정의할 때, 확장되는 제약조건 템플릿을 지정합니다. Google에서 개발한 공통 제약조건 템플릿 라이브러리는 기본적으로 설치되며 많은 조직에서는 Rego에서 직접 커스텀 제약조건 템플릿을 만들 필요가 없습니다. Google에서 제공하는 제약조건 템플릿에는 configmanagement.gke.io/configmanagement 라벨이 있습니다.

제약조건을 나열하려면 다음 명령어를 사용합니다.

kubectl get constrainttemplates \
    -l="configmanagement.gke.io/configmanagement=config-management"

제약조건 템플릿을 설명하고 필수 매개변수를 확인하려면 다음 명령어를 사용합니다.

kubectl describe constrainttemplate CONSTRAINT_TEMPLATE_NAME

또한 라이브러리에서 모든 제약조건 템플릿을 볼 수도 있습니다.

제약조건 정의

YAML을 사용하여 제약조건을 정의합니다. Rego는 이해하거나 작성할 필요가 없습니다. 대신 제약조건은 제약조건 템플릿을 호출하고 제약조건에 특정한 매개변수를 제공합니다.

구조적 저장소를 사용하는 경우 cluster/ 디렉터리에 제약조건을 만드는 것이 좋습니다.

제약조건에 포함되는 필드는 다음과 같습니다.

  • 소문자 kind는 제약조건 템플릿의 이름과 일치합니다.
  • metadata.name은 제약조건의 이름입니다.
  • match 필드는 제약조건이 적용되는 객체를 정의합니다. 제약조건에 대해 객체가 범위 내에 있기 전에 지정된 모든 조건이 일치해야 합니다. match 조건은 다음 하위 필드로 정의됩니다.
    • kinds는 제약조건이 적용되는 리소스 유형으로, 두 필드로 결정됩니다. apiGroups는 일치하는 Kubernetes API 그룹의 목록이고 kinds는 일치하는 종류의 목록입니다. '*'는 모두 일치합니다. apiGroup 최소 한 개 이상과 kind 항목 하나가 일치하면 kinds 조건이 충족됩니다.
    • namespaces는 객체가 속하는 네임스페이스 이름 목록입니다. 객체는 이러한 네임스페이스 중 하나 이상에 속해야 합니다. 네임스페이스 리소스는 마치 자신에게 속한 것처럼 취급됩니다.
    • excludedNamespaces은 객체가 속할 수 없는 네임스페이스 목록입니다.
    • labelSelector은 객체가 충족해야 하는 Kubernetes 라벨 선택기입니다.
    • namespaceSelector은 객체가 속한 네임스페이스의 라벨 선택기입니다. 네임스페이스가 객체를 만족시키지 않으면 일치하지 않습니다. 네임스페이스 리소스는 마치 자신에게 속한 것처럼 취급됩니다.
  • parameters 필드는 제약조건 템플릿이 예상하는 내용에 따라 제약조건의 인수를 정의합니다.

ns-must-have-geo라는 다음 제약조건은 Google에서 제공한 제약조건 템플릿 라이브러리에 포함된 K8sRequiredLabels라는 제약조건 템플릿을 호출합니다. 제약조건은 제약조건 템플릿이 네임스페이스의 geo 라벨이 일부 값으로 설정되어 있는지 여부를 평가하는 데 사용하는 매개변수를 정의합니다.

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

제약조건을 만들려면 kubectl apply -f를 사용합니다.

kubectl apply -f ns-must-have-geo.yaml

제약조건 감사

제약조건이 올바르게 구성되고 설치된 경우 제약조건이 제약조건을 적용하거나 테스트만 하도록 구성되는지 여부에 관계없이 status.byPod[].enforced 필드는 true로 설정됩니다.

제약조건은 기본적으로 적용되며 제약조건을 위반하면 지정된 클러스터 작업이 금지됩니다. 조작을 방해하지 않고 status.violations 필드에서 위반을 보고하도록 제약조건의 spec.enforcementActiondryrun으로 설정할 수 있습니다.

감사에 대한 자세한 내용은 제약조건을 사용하여 감사를 참조하세요.

제약조건 동기화 시 주의사항

제약조건을 동기화할 때 다음 사항에 유의하세요.

eventual consistency

저장소에 제약조건을 커밋하고 ClusterSelectors 또는 NamespaceSelectors를 사용하여 제한을 적용할 수 있습니다. 동기화는 eventual consistency를 가지므로 다음 사항에 유의하세요.

  • 클러스터 작업이 NamespaceSelector가 동기화되지 않은 네임스페이스를 참조하는 제약조건을 트리거하면 제약조건이 적용되고 작업이 금지됩니다. 다시 말해 누락된 네임스페이스 'fails closed'입니다.
  • 네임스페이스 라벨을 변경하면 캐시에 짧은 시간 동안 오래된 데이터가 포함될 수 있습니다.

네임스페이스 이름을 바꾸거나 라벨을 변경해야 하는 필요성을 최소화하고 이름이 바뀌거나 라벨이 다시 지정된 네임스페이스에 영향을 미치는 제약조건을 테스트하여 예상대로 작동하는지 확인합니다.

참조 제약조건에 맞게 Policy Controller 구성

참조 제약조건을 사용 설정하려면 네임스페이스와 같은 감시할 객체의 종류를 정책 컨트롤러에 알려주는 구성을 만들어야 합니다.

다음 YAML 매니페스트를 파일에 저장하고 kubectl로 적용하세요. 매니페스트는 네임스페이스와 인그레스를 감시하도록 정책 컨트롤러를 구성합니다. spec.sync.syncOnly에서 group, version, kind를 사용하여 보고자하는 각 유형의 객체에 대한 값을 사용하여 항목을 만듭니다.

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

참조 제약조건 사용

참조 제약조건은 해당 정의에서 다른 객체를 참조합니다. 예를 들어 클러스터의 인그레스 객체에 고유한 호스트 이름이 필요한 제약조건을 만들 수 있습니다. 제약조건 템플릿이 Rego에 문자열 data.inventory를 포함하는 경우 제약조건은 참조입니다.

참조 제약조건은 정책 컨트롤러에서 기본적으로 비활성화되어 있습니다. 참조 제약조건은 eventual consistency를 가지도록 보장되며 이는 다음과 같은 위험을 초래합니다.

  • 오버로드된 API 서버에서 정책 컨트롤러 캐시의 내용이 오래되어 참조 제약조건이 'fail open'으로 표시될 수 있습니다. 즉, 강제 조치가 작동하지 않을 때 작동하는 것으로 나타납니다. 예를 들어 승인 컨트롤러가 중복을 감지할 수 없을 정도로 중복 호스트 이름으로 인그레스를 작성할 수 있습니다.

  • 제약조건이 설치되는 순서와 캐시가 업데이트되는 순서는 모두 임의입니다.

이러한 위험을 이해하고 참조 제약조건에 대한 지원을 계속 사용하려면 Operator 객체에서 policyController.referentialRulesEnabledtrue로 설정하세요.

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

모든 제약조건 나열

클러스터에 설치된 모든 제약조건을 나열하려면 다음 명령어를 사용합니다.

kubectl get constraint

제약조건 삭제

제약조건 템플릿을 사용하는 모든 제약조건을 찾으려면 다음 명령어를 사용하여 제약조건 템플릿의 metadata.name과 동일한 kind의 객체를 모두 나열합니다.

kubectl get CONSTRAINT_TEMPLATE_NAME

제약조건을 삭제하려면 kindname을 지정하세요.

kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME

제약조건에 사용되는 제약조건 템플릿을 삭제하려면 제약조건의 kind를 확인합니다.

제약조건을 삭제하면 API 서버에 제약조건이 삭제된 것으로 표시되는 즉시 적용이 중단됩니다.

모든 제약조건 템플릿 삭제

spec.policyController.templateLibraryInstalledfalse로 설정합니다. 이렇게 하면 Operator가 라이브러리를 자동으로 다시 설치할 수 없습니다.

모든 제약조건 템플릿과 모든 제약조건을 삭제하려면 다음 명령어를 사용합니다.

kubectl delete constrainttemplate --all

제약조건 템플릿 라이브러리 복원

제약조건 템플릿 라이브러리를 사용하지 않거나 모든 제약조건 템플릿을 제거한 경우 Operator 구성에서 spec.policyController.templateLibraryInstalledtrue로 설정하여 복원할 수 있습니다.

문제 해결

제약조건 템플릿 생성 오류

disallowed ref를 언급하는 오류가 표시되면 참조 제약조건을 사용하는지 확인합니다. 예를 들어 먼저 참조 제약조건 사용 없이 제약조건 템플릿에서 data.inventory를 사용하는 경우 다음과 같은 오류가 발생합니다.

admission webhook "validation.gatekeeper.sh" denied the request: check refs failed on module {templates["admission.k8s.gatekeeper.sh"]["MyTemplate"]}: disallowed ref data.inventory...

다음 단계