Kubernetes 객체 구성

이 주제에서는 Git에서 읽은 Anthos Config Management 파일의 구성을 만들고 이를 자동으로 클러스터에 적용하는 방법을 보여줍니다.

시작하기 전에

  • 저장소 구조를 파악해야 합니다. 저장소 내 구성 위치는 구성이 적용되는 클러스터와 네임스페이스에 영향을 줍니다. 이는 namespaces/ 디렉터리의 경우에 특히 그러합니다. namespaces/ 디렉터리의 하위 디렉터리가 추상 네임스페이스 디렉터리에서 구성을 상속할 수 있기 때문입니다.

  • 구성을 YAML과 JSON 등 두 가지 형식 중 하나로 작성해야 하므로 기본적으로 이러한 구문을 이해하고 있어야 합니다. 이 문서에 있는 모든 예시는 YAML을 사용하기 때문에 사용자가 쉽게 읽을 수 있습니다.

  • 서로 다른 유형의 Kubernetes 객체에 구성할 수 있는 다양한 옵션이 있습니다. 이러한 객체 유형의 구성을 작성하기 전에 원하는 구성을 어떻게 수동으로 얻을 수 있는지 파악하는 것이 좋습니다.

  • 여기서는 Anthos Config Management 작동 방식을 설명하기 위해 표준 저장소 예를 생성했습니다. 이 주제의 예는 저장소에서 가져온 것이므로 저장소를 브라우저에서 열거나 로컬 시스템에 클론하면 유용할 수 있습니다.

구성 만들기

구성을 만들 때 저장소 내 최상의 위치와 포함할 필드를 결정해야 합니다.

저장소 위치

저장소 내 구성 위치는 구성을 적용할 클러스터를 결정하는 1가지 요소입니다.

  • 네임스페이스를 제외한 클러스터 범위의 객체 구성은 저장소의 cluster/ 디렉터리에 저장됩니다.
  • 네임스페이스와 네임스페이스 범위 객체의 구성은 저장소의 namespaces/ 디렉터리에 저장됩니다.
  • Anthos Config Management 구성요소의 구성은 저장소의 system/ 디렉터리에 저장됩니다.
  • Config Management Operator 구성은 저장소에 직접 저장되지 않으며 동기화되지 않습니다.

구성 내용

구성은 kubectl과 비슷한 가산적 방식을 사용합니다. 새 객체를 만들 경우 모든 필수 입력란을 포함해야 합니다. 그러나 기존 객체를 업데이트할 때는 업데이트해야 하는 입력란만 제공하면 됩니다.

구성을 적용할 때 유효한 Kubernetes 객체를 얻어야 합니다.

기존 Kubernetes 객체 구성

Anthos Config Management를 설치하기 전에 이미 클러스터에 있는 네임스페이스와 같은 기존 Kubernetes 객체 구성을 만들 수 있습니다. 그러나 객체에 configmanagement.gke.io/managed: enabled 주석이 없으면 이 구성은 무시됩니다. 기존 객체의 경우, 주석을 수동으로 적용해야 합니다.

특히 네임스페이스의 경우 Anthos Config Management는 주석 처리되지 않은 네임스페이스 내에 새 객체를 만드는 구성을 적용하고 configmanagement.gke.io/managed: enabled 주석을 이 객체에 적용합니다. 그러나 Anthos Config Management는 주석 처리되지 않은 객체를 수정하거나 클러스터에서 삭제하지 않습니다. 이 내용은 시간 경과에 따른 구성 작업의 다이어그램에 설명되어 있습니다.

CustomResourceDefinitions 구성

Anthos Config Management를 사용하면 다른 리소스를 동기화하는 것과 동일한 방식으로 CRD(CustomResourceDefinitions)를 동기화할 수 있습니다. CRD를 동기화할 때는 다음 사항에 유의해야 합니다.

  • 네임스페이스가 있는 커스텀 리소스를 선언할 때에도 CRD는 cluster/ 디렉터리에 있어야 합니다.

  • CRD 및 해당 CustomResources에 대한 업데이트는 예측 가능한 순서로 발생하지 않습니다. 동일한 커밋에서 CRD와 해당 CustomResources를 수정하면 커스텀 리소스가 업데이트되기 전에 CRD 업데이트가 발생한다고 예상되지 않습니다. 이로 인해 CustomResource와 CRD가 모두 클러스터에 나타날 때까지 syncer 로그가 잠시 일시적인 오류를 보고할 수 있습니다.

  • CRD가 저장소의 CustomResource에 의존하는 경우 Anthos Config Management는 CRD를 삭제할 수 없습니다. CRD를 삭제하려면 해당하는 CustomResource도 삭제해야 합니다. 저장소에서 동일한 커밋 모두 삭제하는 것이 좋습니다.

  • 클러스터에 CRD가 이미 있으면 CRD를 동기화하지 않고도 CustomResource를 동기화할 수 있습니다.

구성 예시

다음 구성 예는 모두 저장소 예에서 가져온 것이며, 이를 바탕으로 자신의 구성을 작성할 수 있습니다. 이 목록은 완전한 목록이 아닙니다. Anthos Config Management를 사용하면 모든 유형의 Kubernetes 객체를 구성할 수 있습니다.

네임스페이스 구성

이 구성은 audit이라는 네임스페이스를 만듭니다.

apiVersion: v1
kind: Namespace
metadata:
  name: audit

네임스페이스 구성을 만들 때 네임스페이스에 라벨이나 주석을 추가할 수도 있습니다. NamespaceSelector를 사용하는 경우 라벨이 필요합니다.

다음 구성 예시에서는 shipping-prod라는 네임스페이스가 없거나 관리되지 않는 경우 이 네임스페이스를 만듭니다. 네임스페이스의 라벨은 env: prod이고 주석은 audit: true입니다. 누군가가 직접 객체의 메타데이터를 수정하면 Anthos Config Management는 구성의 값으로 신속하게 재설정합니다.

apiVersion: v1
kind: Namespace
metadata:
  name: shipping-prod
  labels:
    env: prod
  annotations:
    audit: "true"

네임스페이스 작업에 대한 자세한 내용은 네임스페이스와 네임스페이스 범위 객체 구성을 참조하세요.

ClusterRole 구성

다음 구성에서는 클러스터의 모든 namespace 객체를 읽을 수 있는 권한(get, watch, list)을 제공하는 namespace-reader라는 ClusterRole을 만듭니다. ClusterRole 구성은 주로 ClusterRoleBinding 구성과 함께 사용됩니다.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]

ClusterRoleBinding 구성

다음 구성에서는 사용자에게 cheryl@foo-corp.com namespace-reader ClusterRole 권한을 부여하는 namespace-readers라는 ClusterRoleBinding을 만듭니다.

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-readers
subjects:
- kind: User
  name: cheryl@foo-corp.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: namespace-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding은 클러스터 범위이며 네임스페이스 디렉터리나 추상 네임스페이스에 배치될 수 없습니다.

PodSecurityPolicy 구성

다음 예시에서는 psp라는 PodSecurityPolicy를 만듭니다. 이 정책은 권한이 있는 실행 중인 컨테이너를 사용 중지하지만 컨테이너가 노드의 유효한 사용자로 실행되도록 허용합니다.

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp
spec:
  privileged: false
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

PodSecurityPolicy는 클러스터 범위이며 네임스페이스 디렉터리나 추상 네임스페이스에 배치될 수 없습니다.

NetworkPolicy 구성

다음 예시에서는 default-deny-all-traffic이라는 NetworkPolicy를 만듭니다.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all-traffic
spec:
  podSelector: {}

NetworkPolicy는 네임스페이스 범위이며 네임스페이스 디렉터리나 추상 네임스페이스에만 배치될 수 있습니다.

위의 NetworkPolicy를 단일 네임스페이스에 적용하면 이 네임스페이스에 있는 모든 Pod가 인그레스 트래픽과 이그레스 트래픽에서 분리됩니다.

하위 네임스페이스가 있는 추상 네임스페이스에 동일한 NetworkPolicy를 배치하여 여러 네임스페이스에 적용하면 각 네임스페이스가 NetworkPolicy를 상속합니다. 저장소 예시에서 shipping-app-backendshipping-dev, shipping-prod, shipping-stage의 구성이 포함된 추상 네임스페이스입니다. 위의 NetworkPolicy 예를 여기에 추가하면 각각 NetworkPolicy를 상속하므로 각 Pod가 인그레스 트래픽과 이그레스 트래픽으로부터 보호됩니다.

네임스페이스 상속을 사용하면 최소 권한 보안 방식을 적용할 수 있습니다. 예를 들어, 이전 NetworkPolicy 예가 shipping-app-backend에 적용되고 다음 NetworkPolicy가 shipping-dev 네임스페이스에 추가되는 경우 인그레스 트래픽은 app:nginx 라벨이 있는 해당 네임스페이스의 Pod에만 적용됩니다. shipping-prodshipping-staging 네임스페이스는 이 NetworkPolicy의 영향을 받지 않습니다.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-nginx-ingress
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - {}

ResourceQuota 구성

다음 예시에서는 Pod 1개, 100밀리 CPU, 100MiB 메모리에 대한 엄격한 제한을 설정하는 quota라는 ResourceQuota를 만듭니다.

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
spec:
  hard:
    pods: "1"
    cpu: "100m"
    memory: 100Mi

지정된 유형의 새 객체를 만들면 기존 ResourceQuota를 위반하게 되는 경우, Kubernetes는 더 이상 ResourceQuota를 위반하지 않을 때까지 객체를 만들 수 없습니다.

다음 단계