전용 노드 풀에서 워크로드 격리
이 페이지에서는 권한이 있는 관리형 워크로드가 아닌 별도의 전용 노드 풀에 워크로드를 예약하도록 Azure용 GKE를 구성하여 클러스터에서 권한 에스컬레이션 공격의 위험을 줄이는 방법을 보여줍니다.
개요
Azure용 GKE 클러스터는 권한 있는 워크로드를 사용하여 측정항목 수집과 같은 특정 클러스터 기능을 사용 설정합니다. 이러한 워크로드에는 클러스터에서 올바르게 실행될 수 있는 특수한 권한이 부여됩니다.
노드에 배포하는 워크로드는 악의적인 항목에 의해 손상될 가능성이 있습니다. 권한이 있는 시스템 워크로드와 함께 이러한 워크로드를 실행하면 손상된 컨테이너를 침입한 공격자가 노드에서 권한이 있는 워크로드의 사용자 인증 정보를 사용하여 클러스터의 권한을 에스컬레이션할 수 있습니다.
컨테이너 소그룹 방지
기본 방어는 애플리케이션이어야 합니다. Azure용 GKE에는 클러스터 및 포드를 강화하는 데 사용할 수 있는 여러 기능이 있습니다. 대부분의 경우 정책 컨트롤러 및 커널 보안 기능을 사용하여 워크로드를 강화하는 것이 가장 좋습니다. 보안 권장사항은 보안 개요를 참조하세요.
권한 에스컬레이션 공격 방지
다른 강화 조치 외에 추가 격리 레이어가 필요한 경우 노드 taint 및노드 어피니티를 사용하여 전용 노드 풀에서 워크로드를 예약할 수 있습니다.
노드 taint는 Azure용 GKE에 해당 노드에서 해당 톨러레이션(toleration)(예: Azure용 GKE 관리 워크로드) 없이 워크로드를 예약하지 않도록 지시합니다. 자체 워크로드의 노드 어피니티는 전용 노드에서 포드를 예약하도록 Azure용 GKE에 지시합니다.
노드 격리 제한사항
- 공격자는 여전히 손상된 노드에서 서비스 거부 (DoS) 공격을 시작할 수 있습니다.
- 손상된 노드는 클러스터의 모든 포드 및 네임스페이스를 포함하여 여러 리소스를 계속 읽을 수 있습니다.
- 손상된 노드는 해당 노드에서 실행되는 모든 포드에서 사용되는 보안 비밀과 사용자 인증 정보에 액세스할 수 있습니다.
- 별도의 노드 풀을 사용하여 워크로드를 격리하면 비용 효율성, 자동 확장, 리소스 사용률에 영향을 미칠 수 있습니다.
- 손상된 노드는 계속해서 이그레스 네트워크 정책을 우회할 수 있습니다.
- 일부 Azure용 GKE 관리 워크로드는 클러스터의 모든 노드에서 실행되어야 하며 모든 taint를 허용하도록 구성됩니다.
- 권한이 승격되고 taint를 허용할 수 있는 DaemonSet을 배포하는 경우, 해당 포드는 손상된 노드에서 권한 에스컬레이션을 위한 경로가 될 수 있습니다.
노드 격리 작동 방식
워크로드의 노드 격리를 구현하려면 다음을 수행해야 합니다.
- 워크로드의 노드 풀을 taint하고 라벨을 지정합니다.
- 해당 톨러레이션(toleration) 및 노드 어피니티 규칙으로 워크로드를 업데이트합니다.
이 가이드는 클러스터에서 노드 풀 한 개로 시작한다고 가정합니다. 노드 taint 외에 노드 어피니티를 반드시 사용할 필요는 없지만 예약을 보다 효율적으로 제어할 수 있으므로 이를 사용하는 것이 좋습니다.
시작하기 전에
이 페이지의 단계를 수행하려면 먼저 다음을 완료합니다.
워크로드의 노드 풀 taint 및 라벨 지정
워크로드의 새 노드 풀을 만들고 노드 taint 및 노드 라벨을 적용합니다. 노드 풀 수준에서 taint 또는 라벨을 적용하면 자동 확장으로 생성된 노드와 같이 모든 새 노드는 지정된 taint 및 라벨을 자동으로 가져옵니다.
또한 기존 노드 풀에 노드 taint와 노드 라벨을 추가할 수 있습니다. NoExecute
효과를 사용하면 Azure용 GKE는 새 taint에 대한 톨러레이션(toleration)이 없는 노드에서 실행 중인 모든 포드를 삭제합니다.
새 노드 풀에 taint와 라벨을 추가하려면 다음 명령어를 실행합니다.
gcloud container azure node-pools create POOL_NAME \
--cluster CLUSTER_NAME \
--node-taints TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels LABEL_KEY=LABEL_VALUE
다음을 바꿉니다.
POOL_NAME
: 워크로드의 새 노드 풀 이름입니다.CLUSTER_NAME
: Azure용 GKE 클러스터의 이름입니다.TAINT_KEY=TAINT_VALUE
:TAINT_EFFECT
예약과 연결된 키 값 쌍입니다. 예를 들면workloadType=untrusted
입니다.TAINT_EFFECT
: 효과 값 중 하나입니다(NoSchedule
,PreferNoSchedule
,NoExecute
).NoExecute
는NoSchedule
보다 더 나은 제거를 보장합니다.LABEL_KEY
=LABEL_VALUE
: 워크로드 매니페스트에 지정한 선택기에 해당하는 노드 라벨의 키-값 쌍입니다.
워크로드에 톨러레이션(toleration) 및 노드 어피니티 규칙 추가
전용 노드 풀을 taint한 후에는 추가한 taint에 대한 톨러레이션(toleration)이 없으면 워크로드가 이를 예약할 수 없습니다. 워크로드 사양에 톨러레이션(toleration)을 추가하여 해당 포드가 taint된 노드 풀에서 예약할 수 있도록 합니다.
전용 노드 풀에 라벨을 지정한 경우, 노드 어피니티 규칙을 추가하여 해당 노드 풀에서만 워크로드를 예약하도록 Azure용 GKE에 지시할 수도 있습니다.
다음 예시에서는 workloadType=untrusted:NoExecute
taint에 대한 톨러레이션(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: TAINT_KEY
operator: Equal
value: TAINT_VALUE
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: LABEL_KEY
operator: In
values:
- "LABEL_VALUE"
containers:
- name: sleep
image: ubuntu
command: ["/bin/sleep", "inf"]
다음을 바꿉니다.
TAINT_KEY
: 전용 노드 풀에 적용한 taint 키입니다.TAINT_VALUE
: 전용 노드 풀에 적용한 taint 값입니다.LABEL_KEY
: 전용 노드 풀에 적용한 노드 라벨 키입니다.LABEL_VALUE
: 전용 노드 풀에 적용한 노드 라벨 값입니다.
kubectl apply
로 배포를 업데이트하면 Azure용 GKE가 영향을 받는 포드를 다시 만듭니다. 노드 어피니티 규칙은 생성된 전용 노드 풀로 포드를 강제 적용합니다. 톨러레이션(toleration)을 통해 이러한 포드만 노드에 배치될 수 있습니다.
분리 작동 확인
예약이 올바르게 작동하는지 확인하려면 다음 명령어를 실행하고 워크로드가 전용 노드 풀에 있는지 확인합니다.
kubectl get pods -o=wide
추천 및 권장사항
노드 격리를 설정한 후에는 다음을 수행하는 것이 좋습니다.
components.gke.io/gke-managed-components
taint를 추가하여 특정 노드 풀을 Azure용 GKE 관리 워크로드로 제한합니다. 이 taint를 추가하면 자체 Pod가 이러한 노드에서 예약되지 않도록 하여 격리가 향상됩니다.- 새 노드 풀을 만들 때 노드 풀에 자체 taint를 추가하여 대부분의 Azure용 GKE 관리 워크로드가 이러한 노드에서 실행되지 않도록 합니다.
- 타사 도구를 설치할 때와 같이 새 워크로드를 클러스터에 배포할 때마다 포드에 필요한 권한을 감사합니다. 가능하면 공유 노드에 승격된 권한을 사용하는 워크로드를 배포하지 마세요.