이 페이지에서는 Google Kubernetes Engine(GKE) 클러스터에 GKE Dataplane V2를 사용 설정하고 문제를 해결하는 방법을 설명합니다.
새 Autopilot 클러스터에는 1.22.7-gke.1500 이상 버전과 1.23.4-gke.1500 이상 버전의 GKE Dataplane V2가 사용 설정되어 있습니다. GKE Dataplane V2를 사용하는 데 문제가 있는 경우 문제 해결로 건너뛰세요.
GKE Dataplane V2로 GKE 클러스터 만들기
GKE 버전 1.20.6-gke.700 이상으로 새 클러스터를 만들 때 gcloud CLI나 GKE API를 사용하여 GKE Dataplane V2를 사용 설정할 수 있습니다. GKE 버전 1.17.9 이상을 사용하는 새 클러스터를 만들 때 미리보기에서 GKE Dataplane V2를 사용 설정할 수도 있습니다.
콘솔
GKE Dataplans V2로 새 클러스터를 만들려면 다음 작업을 수행하세요.
Cloud de Confiance 콘솔에서 Kubernetes 클러스터 만들기 페이지로 이동합니다.
네트워킹 섹션에서 Dataplane V2 사용 설정 체크박스를 선택합니다. 네트워크 정책 적용이 GKE Dataplane V2에 내장되어 있으므로 Dataplane V2 사용 설정을 선택하면 Kubernetes 네트워크 정책 사용 설정 옵션이 사용 중지됩니다.
만들기를 클릭합니다.
gcloud
GKE Dataplane V2를 사용하여 새 클러스터를 만들려면 다음 명령어를 사용하세요.
gcloud container clusters create CLUSTER_NAME \
--enable-dataplane-v2 \
--enable-ip-alias \
--release-channel CHANNEL_NAME \
--location COMPUTE_LOCATION
다음을 바꿉니다.
CLUSTER_NAME: 새 클러스터의 이름입니다.CHANNEL_NAME: GKE 버전 1.20.6-gke.700 이상을 포함하는 출시 채널입니다. 출시 채널을 사용하지 않으려면 버전 1.20.6-gke.700 이상을 지정하여--release-channel대신--cluster-version플래그를 사용할 수도 있습니다.COMPUTE_LOCATION: 새 클러스터의 Compute Engine 위치입니다.
API
GKE Dataplane V2로 새 클러스터를 만들려면 클러스터 create 요청의 networkConfig 객체에서 datapathProvider 필드를 지정합니다.
다음 JSON 스니펫은 GKE Dataplane V2를 사용 설정하는 데 필요한 구성을 보여줍니다.
"cluster":{
"initialClusterVersion":"VERSION",
"ipAllocationPolicy":{
"useIpAliases":true
},
"networkConfig":{
"datapathProvider":"ADVANCED_DATAPATH"
},
"releaseChannel":{
"channel":"CHANNEL_NAME"
}
}
다음을 바꿉니다.
- VERSION: 클러스터 버전이며 GKE 1.20.6-gke.700 이상이어야 합니다.
- CHANNEL_NAME: GKE 버전 1.20.6-gke.700 이상을 포함하는 출시 채널입니다.
GKE Dataplane V2 문제 해결
이 섹션에서는 GKE Dataplane V2의 문제를 조사하고 해결하는 방법을 설명합니다.
GKE Dataplane V2가 사용 설정되어 있는지 확인합니다.
kubectl -n kube-system get pods -l k8s-app=cilium -o wideGKE Dataplane V2가 실행 중이면 출력은 프리픽스가
anetd-인 포드를 포함합니다. anetd는 GKE Dataplane V2의 네트워킹 컨트롤러입니다.서비스 또는 네트워크 정책 적용과 관련된 문제라면
anetd포드 로그를 확인합니다. Cloud Logging에서 다음 로그 선택기를 사용합니다.resource.type="k8s_container" labels."k8s-pod/k8s-app"="cilium" resource.labels.cluster_name="CLUSTER_NAME"포드 만들기가 실패하면 kubelet 로그에서 단서를 찾아보세요. Cloud Logging에서 다음 로그 선택기를 사용합니다.
resource.type="k8s_node" log_name=~".*/logs/kubelet" resource.labels.cluster_name="CLUSTER_NAME"CLUSTER_NAME을 클러스터 이름으로 바꾸거나 완전히 삭제하여 모든 클러스터의 로그를 확인합니다.anetd포드가 실행되지 않는 경우 cilium-config ConfigMap에 변경 사항이 있는지 확인합니다. 이 ConfigMap의 기존 필드를 변경하면 클러스터가 불안정해지고anetd에 문제가 발생할 수 있으므로 기존 필드는 절대 수정하지 마세요. ConfigMap은 새 필드가 추가된 경우에만 기본 상태로 자동 패치됩니다. 기존 필드를 수정한 경우에는 원래대로 복구되지 않습니다. 따라서 ConfigMap은 변경하거나 맞춤설정하지 않는 것이 좋습니다.
알려진 문제
GKE Dataplane V2를 사용하면 다음과 같은 알려진 문제가 발생할 수 있습니다.
준비되지 않은 포드의 연결 시간 초과
포드가 준비되지 않은 경우 연결된 서비스에 대한 연결이 시간 초과될 수 있습니다.
이는 GKE Dataplane V2의 예상되는 동작이며 더 빠른 connection refused 오류를 반환할 수 있는 kube-proxy와는 다릅니다.
Cilium ID의 ID 관련 라벨 필터링이 적용되지 않고 포드가 ContainerCreating 상태에서 멈춰 있음
영향을 받는 버전: 1.34, 1.35
GKE Dataplane V2 클러스터에서 kube-system/cilium-config-emergency-override ConfigMap을 통한 ID 관련 라벨 필터링의 비상 사용이 영향을 받는 버전에서 올바르게 적용되지 않습니다.
이 접근 방식은 Cilium ID 생성에 사용되는 포드 라벨을 제한합니다.
포드에서 높은 카디널리티 라벨 키/값을 방지/삭제하는 다른 메커니즘을 사용할 수 없는 경우 (예: 도구 또는 프레임워크에서 라벨을 적용하는 경우) ID 관련 라벨 필터링을 사용하여 Cilium ID 계산에서 라벨 키를 제외할 수 있습니다. 이러한 규칙 구성에 대한 자세한 내용은 Cilium 문서의 ID 관련 라벨을 참조하세요.
영향을 받는 GKE 버전의 경우 연산자가 만든 Cilium ID는 계속해서 제외된 라벨을 포함합니다.
증상
Cilium ID 생성을 위해 필터링해야 하는 라벨이 있는 포드가 시작되지 않고
ContainerCreating상태에서 멈춰 있을 수 있습니다. 포드 이벤트에 시간 초과 오류가 표시될 수 있습니다.{"level":"warning", "msg":"Error changing endpoint identity", "error":"unable to resolve identity: timed out waiting for cilium-operator to allocate CiliumIdentity for key ...;, error: exponential backoff cancelled via context: context canceled", "k8sPodName":"...", "subsys":"endpoint"}필터링된 라벨을 기반으로 ID를 공유하는 대신 고유한 라벨 값이 있는 포드가 계속해서 고유한 Cilium ID를 생성합니다. 이로 인해 ID가 급격히 증가하여 사용 가능한 Cilium ID가 소진 (최대 65,536개)되고 확장성 문제가 발생할 수 있습니다.
수정된 버전
이 문제를 해결하려면 클러스터를 다음 GKE 버전 중 하나로 업그레이드합니다.
- 1.34.6-gke.1307000 이상
- 1.35.2-gke.1962000 이상
해결 방법
해결 방법으로 라벨 필터링 규칙을 data.labels 필드에 적용하고 기본 cilium-config ConfigMap에서 삭제합니다.cilium-config-emergency-override GKE는 cilium-config ConfigMap 내에서 관리하지 않는 필드에 대한 사용자 수정을 보존하므로 이 상황은 업그레이드와 같은 컨트롤 플레인 작업을 통해 지속됩니다.
cilium-config-emergency-overrideConfigMap의data섹션에labels키가 있으면 삭제합니다.data섹션에서labels키를 추가하거나 수정하여cilium-configConfigMap을 수정합니다. 예를 들어uuid라는 라벨이 ID 생성에 사용되지 않도록 하려면 다음 안내를 따르세요.apiVersion: v1 kind: ConfigMap metadata: name: cilium-config namespace: kube-system data: # ... other existing keys labels: "!uuid" # ... other existing keys컨트롤 플레인을 실행 중인 동일한 버전으로 업그레이드하여 컨트롤 플레인에서
anet-operator를 다시 시작합니다. 이렇게 하면 연산자가 다시 시작되고 구성을 다시 로드합니다.gcloud container clusters upgrade CLUSTER_NAME \ --location CLUSTER_LOCATION \ --project PROJECT_ID \ --cluster-version $(gcloud container clusters describe CLUSTER_NAME --location CLUSTER_LOCATION --project PROJECT_ID --format="value(currentMasterVersion)") \ --master컨트롤 플레인이 다시 시작된 후
anetdDaemonSet를 다시 시작하여 노드 에이전트도 필요한 변경사항을 선택하도록 합니다.kubectl rollout restart daemonset anetd -n kube-system
GKE Dataplane V2 클러스터에서 NodePort 범위 충돌로 인해 간헐적인 연결 문제 발생
GKE Dataplane V2 클러스터에서는 마스커레이드된 트래픽이나 임시 포트를 사용하는 경우 간헐적인 연결 문제가 발생할 수 있습니다. 이러한 문제는 예약된 NodePort 범위와의 포트 충돌 가능성 때문에 발생하며 일반적으로 다음과 같은 상황에서 발생합니다.
커스텀
ip-masq-agent: 클러스터에서NodePort또는 부하 분산기를 사용하는 경우 버전 2.10 이상의 커스텀ip-masq-agent를 사용할 때NodePort범위와의 충돌로 인해 간헐적인 연결 문제가 발생할 수 있습니다. 버전 2.10부터는ip-masq-agent에--random-fully인수가 기본적으로 내부 구현되어 있습니다. 이를 완화하려면ip-masq-agent구성에서--random-fully=false(버전 2.11 이상에 적용 가능)를 명시적으로 설정해야 합니다. 구성에 관한 자세한 내용은 Standard 클러스터에서 IP 매스커레이드 에이전트 구성을 참조하세요.임시 포트 범위 겹침: GKE 노드에서
net.ipv4.ip_local_port_range로 정의된 임시 포트 범위가NodePort범위(30000~32767)와 겹치는 경우 연결 문제가 발생할 수 있습니다. 이 문제를 방지하려면 두 포트 범위가 서로 겹치지 않도록 설정해야 합니다.
ip-masq-agent 구성과 임시 포트 범위 설정을 검토하여 NodePort 범위와 충돌하지 않도록 하세요. 간헐적인 연결 문제가 발생한다면 이러한 가능한 원인들을 고려하여 구성을 조정하는 것이 좋습니다.
GKE Dataplane V2 클러스터에서 hostPort로 인한 연결 문제
영향을 받는 GKE 버전: 1.29 이상
GKE Dataplane V2를 사용하는 클러스터에서는 트래픽이 노드의 IP:포트(여기서 포트는 포드에 정의된 hostPort임)로 전달될 때 연결 오류가 발생할 수 있습니다. 이러한 문제는 다음 두 가지 기본 시나리오에서 발생합니다.
패스 스루 네트워크 부하 분산기 뒤에 있는
hostPort노드:hostPort는 특정 노드의 포트에 포드를 고정시키며, 패스 스루 네트워크 부하 분산기는 트래픽을 모든 노드에 분산시킵니다.hostPort와 패스 스루 네트워크 부하 분산기를 함께 사용하여 포드를 인터넷에 노출하는 경우 부하 분산기가 해당 포드가 실행되고 있지 않은 노드로 트래픽을 전달할 수 있으며, 이로 인해 연결 실패가 발생할 수 있습니다. 이 문제는 GKE Dataplane V2의 알려진 제한사항으로, 패스스루 네트워크 부하 분산기 트래픽이hostPort포드로 일관되게 전달되지 않는 문제에서 비롯됩니다.해결 방법: 포드의
hostPort를 패스 스루 네트워크 부하 분산기가 연결된 노드에서 노출하려는 경우 해당 포드의hostIP필드에 해당 네트워크 부하 분산기의 내부 또는 외부 IP 주소를 지정합니다.ports: - containerPort: 62000 hostPort: 62000 protocol: TCP hostIP: 35.232.62.64 - containerPort: 60000 hostPort: 60000 protocol: TCP hostIP: 35.232.62.64 # Assuming 35.232.62.64 is the external IP address of a passthrough Network Load Balancer.hostPort가 예약된NodePort범위와 충돌하는 경우:포드의
hostPort가 예약된NodePort범위(30000~32767)와 충돌하면 Cilium이 해당 포드로 트래픽을 전달하지 못할 수 있습니다. 이 현상은 클러스터 버전 1.29 이상에서 관찰되며, 해당 버전부터는 Cilium이 기존의 Portmap 방식 대신hostPort기능을 직접 관리하기 때문입니다. 이 동작은 Cilium의 예상되는 동작이며 해당 내용은 공식 문서에도 명시되어 있습니다.
이러한 제한사항은 향후 버전에서도 수정될 예정이 없습니다. 이러한 문제의 근본 원인은 Cilium의 동작 방식과 관련되어 있으며, 이는 GKE에서 직접 제어할 수 있는 범위를 벗어납니다.
권장사항: 더 높은 안정성을 위해 hostPort 대신 NodePort 서비스로 마이그레이션하는 것이 좋습니다. NodePort 서비스는 유사한 기능을 제공합니다.
네트워크 정책의 포트 범위가 적용되지 않음
GKE Dataplane V2가 사용 설정된 클러스터의 네트워크 정책에 endPort 필드를 지정하면 적용되지 않습니다.
Kubernetes 네트워크 정책 API 를 사용하면 네트워크 정책이 적용되는 포트 범위를 지정할 수 있습니다. 이 API는 Calico 네트워크 정책이 있는 클러스터에서 지원되지만 GKE Dataplane V2가 있는 클러스터에서는 지원되지 않습니다.
NetworkPolicy 객체를 API 서버에 작성한 후 다시 읽어 해당 객체의 동작을 확인할 수 있습니다. 객체에 여전히 endPort 필드가 포함되어 있으면 기능이 적용됩니다. endPort 필드가 누락되면 이 기능이 적용되지 않습니다. 어떤 경우든 API 서버에 저장된 객체는 네트워크 정책의 정보 소스입니다.
자세한 내용은 KEP-2079: 포트 범위를 지원하는 네트워크 정책을 참조하세요.
수정된 버전
이 문제를 해결하려면 클러스터를 GKE 버전 1.32 이상으로 업그레이드하세요 .
잘못된 연결 추적 조회로 인해 네트워크 정책이 연결을 중단
클라이언트 포드가 내부 패스 스루 네트워크 부하 분산기의 서비스나 가상 IP 주소를 통해 자체에 연결되면 응답 패킷은 데이터 영역의 잘못된 conntrack 조회로 인해 기존 연결의 일부로 식별되지 않습니다. 즉, 포드의 인그레스 트래픽을 제한하는 네트워크 정책이 패킷에 잘못 적용됩니다.
이 문제의 영향은 서비스에 구성된 포드 수에 따라 다릅니다. 예를 들어 서비스에 백엔드 포드가 1개 있으면 연결이 항상 실패합니다. 서비스에 백엔드 포드가 2개 있는 경우 연결의 50%가 실패합니다.
수정된 버전
이 문제를 해결하려면 다음 GKE 버전 중 하나로 클러스터를 업그레이드합니다.
- 1.28.3-gke.1090000 이상
해결 방법
서비스 매니페스트에서 port 및 containerPort를 동일한 값으로 구성하여 이 문제를 완화할 수 있습니다.
헤어핀 연결 흐름을 위한 패킷 삭제
포드가 서비스를 사용하여 자체 TCP 연결을 만들면(예: 포드가 연결의 소스이자 대상인 경우), GKE Dataplane V2 eBPF 연결 추적은 연결 상태를 잘못 추적하여 conntrack 항목의 유출로 이어지게 됩니다.
연결 튜플(프로토콜, 소스/대상 IP, 소스/대상 포트)이 유출되면 동일한 연결 튜플을 사용하는 새 연결로 인해 반환 패킷이 삭제될 수 있습니다.
수정된 버전
이 문제를 해결하려면 다음 GKE 버전 중 하나로 클러스터를 업그레이드합니다.
- 1.28.3-gke.1090000 이상
- 1.27.11-gke.1097000 이상
해결 방법
이때 다음 해결방법 중 하나를 사용해 보세요.
서비스를 사용하여 자체적으로 통신할 수 있는 포드에서 실행되는 애플리케이션에 TCP 재사용(연결 유지)을 사용 설정합니다. 이렇게 하면 TCP FIN 플래그가 발행되지 않고 conntrack 항목이 유출되지 않습니다.
단기 연결을 사용할 때는 게이트웨이와 같은 프록시 부하 분산기를 사용하여 포드를 노출하여 서비스를 노출하세요. 이렇게 하면 연결 요청의 대상이 부하 분산기의 IP 주소로 설정되어 GKE Dataplane V2가 루프백 IP 주소로 SNAT를 수행하는 것을 방지할 수 있습니다.
GKE 컨트롤 플레인 업그레이드 시 anetd 포드 교착 상태 발생
GKE Dataplane V2(고급 데이터 경로)가 사용 설정된 GKE 클러스터를 버전 1.27에서 1.28로 업그레이드할 경우 교착 상태가 발생할 수 있습니다. 이로 인해 이전 포드를 종료하거나 anetd와 같은 필수 구성요소를 예약하지 못하게 되어, 워크로드가 중단되는 문제가 발생할 수 있습니다.
원인
클러스터 업그레이드 과정에서는 GKE Dataplane V2 구성요소의 리소스 요구량이 증가합니다. 이러한 리소스 사용량 증가는 리소스 경합을 유발할 수 있으며, 그 결과 Cilium 컨테이너 네트워크 인터페이스(CNI) 플러그인과 Cilium 데몬 간의 통신이 중단될 수 있습니다.
증상
다음과 같은 증상이 발생할 수 있습니다.
anetd포드가Pending상태에서 멈춰 있는 현상- 워크로드 포드가
Terminating상태에서 종료되지 않는 현상 - Cilium 통신 오류 관련 메시지(예:
failed to connect to Cilium daemon) 포드 샌드박스의 네트워크 리소스를 정리하는 중 발생하는 오류(예: 다음과 같은 메시지)
1rpc error: code = Unknown desc = failed to destroy network for sandbox "[sandbox_id]": plugin type="cilium-cni" failed (delete): unable to connect to Cilium daemon... connection refused
해결 방법
Standard 클러스터: 문제를 해결하고 anetd 포드를 예약할 수 있도록 하려면 영향을 받은 노드의 할당 가능한 리소스를 일시적으로 증가시켜야 합니다.
영향을 받은 노드를 식별하고 해당 노드의 할당 가능한 CPU 및 메모리를 확인하려면 다음 명령어를 실행하세요.
kubectl get nodes $NODE_NAME -o json | jq '.status.allocatable | {cpu, memory}'할당 가능한 CPU 및 메모리를 일시적으로 증가시키려면 다음 명령어를 실행하세요.
kubectl patch node $NODE_NAME -p '{"status":{"allocatable":{"cpu":CPU_VALUE, "memory":MEMORY_VALUE}}}'
Autopilot 클러스터: Autopilot 클러스터에서 교착 상태 문제를 해결하려면 영향을 받은 포드를 강제로 삭제하여 리소스를 확보하세요.
kubectl delete pod POD_NAME -n NAMESPACE --grace-period=0 --force
다음을 바꿉니다.
POD_NAME: 포드의 이름입니다.NAMESPACE: 포드의 네임스페이스입니다.
노드의 할당 가능한 리소스를 증가시키고 GKE 버전 1.27에서 1.28로의 업그레이드가 완료되면 anetd 포드가 최신 버전에서 실행됩니다.
containerID 오류 누락으로 인해 NodeNotReady 상태의 노드
클러스터가 GKE 버전 1.35.1-gke.1616000 이상으로 업그레이드되면 GKE Dataplane V2와 Cloud Service Mesh가 모두 사용 설정된 경우 노드가 즉시 NodeNotReady 상태로 전환될 수 있습니다.
원인
GKE 버전 1.35.1-gke.1616000부터 GKE Dataplane V2 클러스터는 CNI 구성 파일에서 CNI 버전 1.1.0을 사용합니다. 이 변경사항을 적용하려면 Google Managed Istio와 같은 다운스트림 CNI 플러그인도 CNI 버전 1.1.0을 지원해야 합니다. Managed Istio 출시가 지연되어 일부 클러스터는 아직 호환 버전 (1.23)을 수신하지 못하여 초기화가 실패했습니다.
증상
영향을 받는 노드가 즉시 NodeNotReady로 표시됩니다. containerd 로그에 다음 오류 메시지가 표시됩니다.
NetworkPluginNotReady message:Network plugin returns error: missing containerID
해결 방법
이 문제를 완화하려면 영향을 받는 클러스터를 GKE 버전 1.35.1-gke.1616000 이전 버전으로 다운그레이드하세요.
커스텀 eBPF 프로그램 간섭
GKE는 eBPF 프로그램을 사용하여 GKE Dataplane V2의 네트워킹을 관리합니다. GKE 관리형 노드 네트워크 인터페이스에 커스텀 eBPF 프로그램을 배포하면 이러한 프로그램이 GKE 관리형 eBPF 프로그램을 방해하여 네트워킹 문제가 발생할 수 있습니다.
GKE는 다음 네트워크 인터페이스에 연결된 커스텀 eBPF 프로그램을 지원하지 않습니다.
eth*ens4locilium*gke*veth*
이러한 인터페이스에 커스텀 eBPF 프로그램이 있으면 GKE Dataplane V2 anetd 에이전트 설치 프로그램이 방해를 받아 클러스터 네트워킹이 중단될 수 있습니다. 클러스터에서 이러한 프로그램을 삽입하는 커스텀 eBPF 프로그램 또는 워크로드를 삭제하는 것이 좋습니다.
커스텀 eBPF 프로그램 검색
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: bpftool-logger
labels:
app: bpftool-logger
spec:
selector:
matchLabels:
app: bpftool-logger
template:
metadata:
labels:
app: bpftool-logger
spec:
hostPID: true
hostNetwork: true
containers:
- name: bpftool
image: ubuntu:22.04
securityContext:
privileged: true
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
command:
- /bin/bash
- -c
- |
echo "Installing dependencies..."
apt-get update -y > /dev/null 2>&1
apt-get install -y curl tar > /dev/null 2>&1
echo "Downloading and setting up bpftool..."
curl -sL https://github.com/libbpf/bpftool/releases/download/v7.7.0/bpftool-v7.7.0-amd64.tar.gz | tar xz
chmod +x bpftool
mv bpftool /usr/local/bin/
echo "========== $(date) | Node: ${NODE_NAME} =========="
bpftool net | grep -E '^(eth|ens4|lo|cilium|gke|veth)' | grep -v ' cil_'
sleep infinity
매니페스트를
ebpf-discovery.yaml로 저장하고 DaemonSet를 적용합니다.kubectl apply -f ebpf-discovery.yaml포드가 실행될 때까지 기다립니다.
kubectl rollout status ds/bpftool-logger포드의 로그를 확인하여 eBPF 프로그램을 검색합니다.
kubectl logs -l app=bpftool-logger완료되면 DaemonSet를 삭제합니다.
kubectl delete -f ebpf-discovery.yaml
다음 단계
- 네트워크 정책 로깅 사용 방법 알아보기
- 네트워크 정책을 사용하여 포드와 서비스 간의 통신을 제어하는 방법 알아보기.
- GKE Dataplane V2 자세히 알아보기
- GKE Dataplane V2 모니터링 가능성 자세히 알아보기
- GKE Dataplane V2 관측 가능성을 구성하는 방법 알아보기