Anthos Config Management 1.3에 대한 문서를 보고 있습니다. 이 버전을 계속 사용하거나 현재 버전을 사용할 수 있습니다.

제약조건 템플릿 작성

이 주제에서는 커스텀 제약조건 템플릿을 작성하고 이를 사용하여 정책 컨트롤러를 확장하는 방법을 보여줍니다.

개요

제약조건 템플릿을 사용하여 정책 컨트롤러를 확장할 수 있습니다. 필요에 따라 미리 작성된 템플릿을 찾을 수 없는 경우 직접 작성할 수 있습니다.

정책 컨트롤러 정책은 OPA 제약조건 프레임워크를 사용하여 설명되며 Rego로 작성되었습니다. 정책은 Kubernetes 객체의 모든 필드를 평가할 수 있습니다.

Rego를 사용하여 정책을 작성하는 것은 전문 기술입니다. 이러한 이유로 공통 제약조건 템플릿 라이브러리가 기본 설치됩니다. 대부분의 사용자는 제약조건을 만들 때 이러한 제약조건 템플릿을 호출할 수 있습니다. 특별한 요구사항이 있으면 자체 제약조건 템플릿을 만들 수 있습니다.

제약조건 템플릿을 사용하면 재사용 및 위임을 위해 정책의 논리를 특정 요구사항과 분리할 수 있습니다. 오픈소스 프로젝트, 소프트웨어 공급업체 또는 규제 전문가와 같은 타사에서 개발한 제약조건 템플릿을 사용하여 제약조건을 작성할 수 있습니다.

시작하기 전에

제약조건 템플릿 예시

다음은 제약조건의 생성자가 제공한 값과 이름이 일치하는 모든 리소스를 거부하는 제약조건 템플릿 예시입니다. 이 페이지의 나머지 부분에서는 템플릿 내용을 설명하고 중요한 개념을 강조하여 설명합니다.

제약조건 템플릿

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdenyname
spec:
  crd:
    spec:
      names:
        kind: K8sDenyName
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            invalidName:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdenynames
        violation[{"msg": msg}] {
          input.review.object.metadata.name == input.parameters.invalidName
          msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
        }

제약조건

다음은 'policy-violation'이라는 모든 리소스를 거부하기 위해 사용자가 구현할 수 있는 제약조건의 예시입니다.

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyName
metadata:
  name: no-policy-violation
spec:
  parameters:
    invalidName: "policy-violation"

제약조건 템플릿의 일부

제약조건 템플릿에는 두 가지 중요한 부분이 있습니다.

  • 사용자가 작성하려는 제약조건의 스키마입니다. 제약조건 템플릿의 스키마는 crd 필드에 저장됩니다.

  • 제약조건이 평가될 때 실행되는 Rego 소스 코드입니다. 템플릿의 Rego 소스 코드는 targets 필드에 저장됩니다.

CRD 필드

CRD 필드는 Kubernetes API 서버에 대한 제약조건 리소스를 정의하는 Kubernetes 커스텀 리소스 정의를 작성하기 위한 청사진입니다. 다음 필드만 채우면 됩니다.

  • spec.crd.spec.names.kind는 제약조건의 종류입니다. 소문자인 경우 이 필드의 값은 metadata.name과 같아야 합니다.
  • spec.crd.spec.validation.openAPIV3Schema는 제약조건 리소스의 spec.parameters 필드에 대한 스키마입니다. 제약조건 스키마의 나머지 부분은 Anthos Config Management에서 자동으로 정의됩니다. 일반 CRD 리소스와 동일한 규칙을 따릅니다. 정의는 여기에 설명되어 있습니다.

이름이 'K8s'인 제약조건 템플릿 프리픽스는 GCP 리소스를 대상으로 하는 Forseti 템플릿과 같은 다른 종류의 제약조건 템플릿과의 충돌을 피할 수 있는 규칙입니다.

Rego 소스 코드

위치

Rego 소스 코드는 spec.targets 필드에 저장되며 여기서 targets{"target": "admission.k8s.gatekeeper.sh", "rego": <REGO SOURCE CODE>, "libs": <LIST OF REGO LIBRARIES>} 형식의 객체 배열입니다. 현재 targets에서 하나의 항목만 허용됩니다.

  • target는 Anthos Config Management에게 현재 보고 있는 시스템(이 경우 Kubernetes)을 알려줍니다.
  • rego는 제약조건의 소스 코드입니다.
  • libs는 제약조건 템플릿에 사용 가능하게 될 Rego 코드 라이브러리의 선택적 목록입니다. 공유 라이브러리를 보다 쉽게 사용할 수 있도록 하기 위한 것이며 이 가이드에서 다루지 않습니다.

소스 코드

위의 제약조건에 대한 Rego를 살펴보겠습니다.

package k8sdenynames

violation[{"msg": msg}] {
   input.review.object.metadata.name == input.parameters.invalidName
   msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}

여기에서 몇 가지 항목을 확인할 수 있습니다.

  • package k8sdenynames는 OPA(Rego 런타임)에 필요하며, 값이 무시됩니다.
  • 위반이 있는지 확인하기 위해 정책 컨트롤러가 호출하는 Rego 규칙은 violation이라고 합니다. 이 규칙이 일치하면 제약조건 위반이 발생한 것입니다.
  • violation 규칙의 서명은 violation[{"msg": "violation message for the user"}]이며 여기서 "msg" 값은 사용자에게 반환되는 위반 메시지입니다.
  • 제약조건에 제공된 매개변수는 키워드 input.parameters에서 사용 가능합니다.
  • 테스트 중인 요청은 input.review 키워드 아래에 저장됩니다.

input.review에는 다음과 같은 필드가 있습니다.

  • uid는 이 특정 요청의 고유 ID이며 감사 중에는 사용할 수 없습니다.
  • kind는 테스트 대상 객체에 대한 종류 정보입니다. 형식은 다음과 같습니다.
    • kind는 리소스 종류입니다.
    • group은 리소스 그룹입니다.
    • version은 리소스 버전입니다.
  • name은 리소스 이름입니다. 사용자가 CREATE 요청 시 이름을 생성하는 데 API 서버를 사용하는 경우에는 비어 있을 수 있습니다.
  • namespace는 리소스 네임스페이스입니다(클러스터 범위 리소스에는 제공되지 않음).
  • operation은 요청된 작업(예: CREATE 또는 UPDATE)이며 감사 중에는 사용할 수 없습니다.
  • userInfo는 요청하는 사용자 정보이며 감사 중에는 사용할 수 없습니다.
    • username는 요청을 보내는 사용자입니다.
    • uid는 사용자의 UID입니다.
    • groups는 사용자가 속한 그룹 목록입니다.
    • extra는 Kubernetes에서 제공하는 추가 사용자 정보입니다.
  • object는 사용자가 수정/생성하려고 하는 객체입니다.
  • oldObject는 객체의 원래 상태이며 UPDATE 작업에서만 사용 가능합니다.
  • dryRun은 이 요청이 kubectl --dry-run으로 호출되었는지 여부이며 감사 중에는 사용할 수 없습니다.

참조 제약조건 템플릿 작성

참조 제약조건 템플릿은 사용자가 한 객체를 다른 객체와 관련하여 제약할 수 있는 템플릿입니다. 이에 대한 예시는 '일치하는 인그레스가 존재하는 것으로 알려지기 전에 pod를 만들 수 없음'일 수 있습니다. 다른 예시는 '두 서비스가 동일한 호스트 이름을 갖도록 허용하지 않음'일 수 있습니다.

정책 컨트롤러를 사용하면 API 서버에서 사용자가 제공한 리소스 집합을 확인하여 참조 제약조건을 작성할 수 있습니다. 리소스가 수정되면 정책 컨트롤러는 리소스를 로컬에서 캐시하여 Rego 소스 코드에서 쉽게 참조할 수 있도록 합니다. 정책 컨트롤러는 이 캐시를 data.inventory 키워드 아래에서 사용할 수 있도록 합니다.

클러스터 범위 리소스는 다음 위치에 캐시됩니다.

data.inventory.cluster[<groupVersion>][<kind>][<name>]

예를 들어 my-favorite-node라는 노드는 다음 위치에서 찾을 수 있습니다.

data.inventory.cluster["v1"]["Node"]["my-favorite-node"]

네임스페이스 범위의 리소스는 여기에 캐시됩니다.

data.inventory.namespace[<namespace>][<groupVersion>][<kind>][<name>]

예를 들어 네임스페이스 shipping-prod의 이름이 production-variables인 ConfigMap은 다음 위치에서 찾을 수 있습니다.

data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]

객체의 전체 내용은 이 캐시 위치에 저장되며 적합한 방법에 따라 Rego에서 참조할 수 있습니다.

Rego에 대한 자세한 내용

위의 정보는 Rego의 Kubernetes 리소스 제약조건을 쉽게 작성할 수 있도록 하는 정책 컨트롤러의 고유한 기능을 제공합니다. Rego로 작성하는 방법에 대한 전체 가이드는 이 가이드에서 다루지 않습니다. 그러나 Open Policy Agent 웹사이트에는 Rego 언어 자체의 구문 및 기능에 대한 문서가 있습니다.

제약조건 템플릿 설치

제약조건 템플릿을 만든 후 kubectl apply를 사용하면 정책 컨트롤러가 수집을 처리합니다. 제약조건 템플릿의 status 필드를 확인하여 인스턴스화 오류가 없는지 확인하세요. 수집에 성공하면 status 필드에 created: true가 표시되고 status 필드에 표시된 observedGenerationmetadata.generation 필드와 같아야 합니다.

템플릿을 수집한 후에는 제약조건 만들기에 설명된 대로 템플릿을 적용할 수 있습니다.

제약조건 템플릿 제거

먼저 유지하려는 제약조건이 제약조건 템플릿을 사용하지 않는지 확인하십시오.

kubectl get [TEMPLATE-NAME]

제약조건 템플릿 이름과 클러스터의 다른 객체 간에 이름이 충돌하는 경우 대신 다음 명령어를 사용할 수 있습니다.

kubectl get [TEMPLATE-NAME].constraints.gatekeeper.sh

제약조건 템플릿을 제거합니다.

kubectl delete constrainttemplate [CONSTRAINT-TEMPLATE-NAME]

제약조건 템플릿을 제거하면 더 이상 제약조건을 참조하는 제약조건을 작성할 수 없습니다.

다음 단계