이 문서에서는 Google Distributed Cloud (GDC) 에어 갭의 전용 노드 풀 내에서 컨테이너 워크로드를 격리하여 Kubernetes 클러스터의 보안과 관리를 강화하는 방법을 설명합니다. 워크로드를 격리하면 포드를 더 세부적으로 제어할 수 있고 Kubernetes 클러스터에서 권한 에스컬레이션 공격의 위험을 줄일 수 있습니다. 전용 노드 풀의 이점과 제한사항에 대한 자세한 내용은 노드 격리 개요를 참고하세요.
컨테이너 워크로드를 격리하는 데는 다음과 같은 여러 워크플로가 관련됩니다.
노드 풀 taint 및 라벨 지정: 노드 풀에 taint 및 라벨을 적용하여 포드가 노드 풀에서 실행되도록 명시적으로 라벨이 지정되지 않는 한 포드가 노드 풀에서 실행되지 않도록 합니다.
톨러레이션(toleration) 및 노드 어피니티 규칙 추가: 포드에 톨러레이션(toleration) 및 규칙을 적용하여 지정된 노드 풀에서만 실행되도록 합니다.
분리 작동 확인: 테인트된 노드 풀이 해당 노드 풀에서 실행되도록 라벨을 지정한 포드만 실행하는지 확인합니다.
이 워크플로는 Kubernetes 클러스터의 노드 풀을 관리하는 플랫폼 관리자 그룹의 IT 관리자, 컨테이너 워크로드를 관리하는 애플리케이션 운영자 그룹의 애플리케이션 개발자와 같은 사용자를 대상으로 합니다. 자세한 내용은 GDC 오프라인 문서의 대상을 참고하세요.
시작하기 전에
이 문서의 작업을 완료하려면 필요한 권한을 요청하고 환경을 준비해야 합니다.
IAM 역할 요청
Kubernetes 클러스터에서 컨테이너 워크로드를 격리하는 데 필요한 권한을 얻으려면 특정 역할이 있어야 합니다. 필요한 역할은 조직 범위 공유 클러스터 또는 프로젝트 범위 표준 클러스터 내에서 작업하는지에 따라 다릅니다. 자세한 내용은 Kubernetes 클러스터 구성을 참고하세요.
공유 클러스터 역할
조직 IAM 관리자에게 연락하여 공유 클러스터에서 노드 풀을 테인트하고 라벨을 지정하는 데 필요한 다음 역할을 요청하세요.
사용자 클러스터 관리자 (
user-cluster-admin): 관리 API 서버에서 호스팅되는 공유 클러스터의 리소스를 만들거나, 삭제하거나, 수정하거나, 볼 수 있습니다. 이 역할은 공유 클러스터의 노드 풀에 대한 액세스 권한을 제공합니다.사용자 클러스터 개발자 (
user-cluster-developer): 공유 클러스터를 생성, 삭제, 수정 또는 조회합니다. 이 역할은 공유 클러스터 내에 호스팅된 데이터 플레인 API에 대한 액세스를 제공합니다.
이러한 역할은 네임스페이스에 바인딩되지 않습니다.
표준 클러스터 역할
프로젝트 IAM 관리자에게 연락하여 표준 클러스터에서 노드 풀을 테인트하고 라벨을 지정할 수 있는 다음 역할을 요청하세요.
클러스터 관리자 (
cluster-admin): 표준 클러스터의 모든 리소스를 생성, 삭제, 수정 또는 볼 수 있습니다. 이 역할은 클러스터의 리소스를 관리하는 표준 클러스터 내에서 호스팅되는 데이터 영역 API에 대한 액세스 권한을 제공합니다.클러스터 개발자 (
cluster-developer): 표준 클러스터를 만들거나, 삭제하거나, 수정하거나, 볼 수 있습니다. 이 역할은 클러스터를 관리하는 표준 클러스터 내에서 호스팅되는 데이터 영역 API에 대한 액세스를 제공합니다.표준 클러스터 관리자 (
standard-cluster-admin): 관리 API 서버에서 호스팅되는 표준 클러스터의 리소스를 생성, 삭제, 수정 또는 조회합니다. 이 역할은 표준 클러스터의 노드 풀에 대한 액세스 권한을 제공합니다.
이러한 역할은 프로젝트 네임스페이스에 바인딩됩니다.
개발 환경 준비
API를 사용하여 Kubernetes 클러스터에 대해 명령어를 실행하려면 다음 리소스가 있어야 합니다.
Kubernetes 클러스터의 kubeconfig 파일을 로그인하여 생성합니다.
Kubernetes 클러스터의 kubeconfig 경로를 사용하여 이 안내의
KUBERNETES_CLUSTER_KUBECONFIG를 바꿉니다.관리 API 서버의 kubeconfig 파일을 로그인하여 생성합니다.
관리 API 서버의 kubeconfig 경로를 사용하여 이 안내의
MANAGEMENT_API_SERVER를 대체합니다.전용 노드 풀에 사용할 노드 taint와 노드 라벨의 특정 이름을 선택하세요. 예를 들면
workloadType=untrusted입니다.
새 노드 풀 taint 및 라벨 지정
새 노드 풀에 taint 또는 라벨을 적용하면 나중에 추가된 노드를 포함한 모든 노드가 지정된 taint 및 라벨을 자동으로 가져옵니다. 노드 풀에 적용된 후에는 노드 풀에서 테인트나 라벨을 삭제할 수 없습니다.
새 노드 풀에 taint와 라벨을 추가하려면 다음 단계를 완료하세요.
노드 풀을 만드는 경우
Cluster커스텀 리소스의nodePools섹션을 직접 수정합니다.nodePools: # Several lines of code are omitted here. - machineTypeName: n2-standard-2-gdc name: nodepool-1 nodeCount: 3 taints: - key: "TAINT_KEY" value: "TAINT_VALUE" effect: "TAINT_EFFECT" labels: LABEL_KEY: LABEL_VALUE다음을 바꿉니다.
TAINT_KEY:TAINT_EFFECT예약과 연결된 키-값 쌍의 taint 키 부분입니다. 예를 들면workloadType입니다.TAINT_VALUE:TAINT_EFFECT예약과 연결된 키-값 쌍의 테인트 값 부분입니다. 예를 들면untrusted입니다.TAINT_EFFECT: 다음 효과 값 중 하나입니다.NoSchedule: 이 taint를 허용하지 않는 포드는 노드에서 예약되지 않습니다. 기존 포드가 노드에서 제거되지 않습니다.PreferNoSchedule: Kubernetes는 노드에 이 taint를 허용하지 않는 포드를 예약하지 않습니다.NoExecute: 포드가 이미 노드에서 실행 중이면 포드가 노드에서 제거되고 아직 노드에서 실행되지 않은 경우 노드에 예약되지 않습니다.
LABEL_KEY: LABEL_VALUE: 워크로드 매니페스트에 지정한 선택기에 해당하는 노드 라벨의 키-값 쌍입니다.
Cluster리소스를 적용하여 새 노드 풀을 만듭니다.kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVERMANAGEMENT_API_SERVER를 Kubernetes 클러스터가 호스팅되는 영역 API 서버의 kubeconfig 경로로 바꿉니다.
기존 노드 풀 taint 및 라벨 지정
기존 노드 풀에 taint 또는 라벨을 적용하려면 각 기존 노드에 변경사항을 적용해야 합니다. 노드 풀 구성을 동적으로 업데이트할 수 없습니다.
노드 풀에 적용된 후에는 테인트나 라벨을 삭제할 수 없습니다.
기존 노드 풀에 taint와 라벨을 추가하려면 다음 단계를 완료하세요.
전용 노드 풀의 노드를 나열합니다.
kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \ -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME다음 변수를 바꿉니다.
KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes 클러스터의 kubeconfig 경로입니다.NODE_POOL_NAME: 전용 노드 풀의 이름입니다.
출력에서 노드 풀에 있는 모든 노드의 각 노드 ID를 기록합니다.
노드 풀의 각 노드에 대해 테인트를 적용합니다.
kubectl taint nodes NODE_ID \ TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG다음 변수를 바꿉니다.
NODE_ID: 전용 노드 풀의 워커 노드 ID입니다.TAINT_KEY=TAINT_VALUE:TAINT_EFFECT예약과 연결된 키-값 쌍입니다. 예를 들면workloadType=untrusted입니다.TAINT_EFFECT: 다음 효과 값 중 하나입니다.NoSchedule: 이 taint를 허용하지 않는 포드는 노드에서 예약되지 않습니다. 기존 포드가 노드에서 제거되지 않습니다.PreferNoSchedule: Kubernetes는 노드에 이 taint를 허용하지 않는 포드를 예약하지 않습니다.NoExecute: 포드가 이미 노드에서 실행 중이면 포드가 노드에서 제거되고 아직 노드에서 실행되지 않은 경우 노드에 예약되지 않습니다.
KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes 클러스터의 kubeconfig 경로입니다.
노드 풀의 각 노드에 컨테이너 워크로드에서 정의할 선택기에 해당하는 라벨을 적용합니다.
kubectl label NODE_ID \ LABEL_KEY:LABEL_VALUE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG다음 변수를 바꿉니다.
NODE_ID: 전용 노드 풀의 워커 노드 ID입니다.LABEL_KEY:LABEL_VALUE: 워크로드 매니페스트에 지정한 선택기에 해당하는 노드 라벨의 키-값 쌍입니다.KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes 클러스터의 kubeconfig 경로입니다.
톨러레이션(toleration) 및 노드 어피니티 규칙 추가
전용 노드 풀을 taint한 후에는 추가한 taint에 대한 톨러레이션(toleration)이 없으면 워크로드가 이를 예약할 수 없습니다. 워크로드 사양에 톨러레이션(toleration)을 추가하여 해당 포드가 taint된 노드 풀에서 예약할 수 있도록 합니다.
전용 노드 풀에 라벨을 지정한 경우, 노드 어피니티 규칙을 추가하여 해당 노드 풀에서만 워크로드를 예약하도록 GDC에 지시할 수도 있습니다.
전용 노드 풀에서 실행되도록 컨테이너 워크로드를 구성하려면 다음 단계를 완료하세요.
Deployment커스텀 리소스와 같은 컨테이너 워크로드 매니페스트 파일의.spec.template.spec섹션에 다음 섹션을 추가합니다.tolerations: - key: TAINT_KEY operator: Equal value: TAINT_VALUE effect: TAINT_EFFECT affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: LABEL_KEY operator: In values: - "LABEL_VALUE"다음을 바꿉니다.
TAINT_KEY: 전용 노드 풀에 적용한 taint 키TAINT_VALUE: 전용 노드 풀에 적용한 taint 값입니다.TAINT_EFFECT: 다음 효과 값 중 하나입니다.NoSchedule: 이 taint를 허용하지 않는 포드는 노드에서 예약되지 않습니다. 기존 포드가 노드에서 제거되지 않습니다.PreferNoSchedule: Kubernetes는 노드에 이 taint를 허용하지 않는 포드를 예약하지 않습니다.NoExecute: 포드가 이미 노드에서 실행 중이면 포드가 노드에서 제거되고 아직 노드에서 실행되지 않은 경우 노드에 예약되지 않습니다.
LABEL_KEY: 전용 노드 풀에 적용한 노드 라벨 키입니다.LABEL_VALUE: 전용 노드 풀에 적용한 노드 라벨 값입니다.
예를 들어 다음
Deployment리소스는workloadType=untrusted:NoExecutetaint에 대한 톨러레이션(toleration)과workloadType=untrusted노드 라벨에 대한 노드 어피니티 규칙을 추가합니다.kind: Deployment apiVersion: apps/v1 metadata: name: my-app namespace: default labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: tolerations: - key: workloadType operator: Equal value: untrusted effect: NoExecute affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: workloadType operator: In values: - "untrusted" containers: - name: my-app image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app ports: - containerPort: 80 imagePullSecrets: - name: SECRET컨테이너 워크로드를 업데이트합니다.
kubectl apply -f deployment.yaml -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG다음 변수를 바꿉니다.
NAMESPACE: 컨테이너 워크로드의 네임스페이스입니다. 공유 클러스터의 경우 프로젝트 네임스페이스여야 합니다. 표준 클러스터의 경우 모든 네임스페이스가 될 수 있습니다.KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes 클러스터의 kubeconfig 경로입니다.
GDC에서 영향을 받는 포드를 다시 만듭니다. 노드 어피니티 규칙은 생성된 전용 노드 풀로 포드를 강제 적용합니다. 톨러레이션(toleration)을 통해 이러한 포드만 노드에 배치될 수 있습니다.
분리 작동 확인
지정한 포드가 라벨이 지정된 노드 풀에서 실행 중인지 확인합니다.
지정된 네임스페이스의 포드를 나열합니다.
kubectl get pods -o=wide -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG다음 변수를 바꿉니다.
NAMESPACE: 컨테이너 워크로드의 네임스페이스입니다. 공유 클러스터의 경우 프로젝트 네임스페이스여야 합니다. 표준 클러스터의 경우 모든 네임스페이스가 될 수 있습니다.KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes 클러스터의 kubeconfig 경로입니다.
결과는 다음과 유사합니다.
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkap워크로드가 전용 노드 풀에서 실행 중인지 확인합니다.