이 페이지에서는 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나 Kubernetes Engine API를 사용하여 GKE Dataplane V2를 사용 설정할 수 있습니다. GKE 버전 1.17.9 이상을 사용하는 새 클러스터를 만들 때 미리보기에서 GKE Dataplane V2를 사용 설정할 수도 있습니다.
콘솔
GKE Dataplane V2로 새 클러스터를 만들려면 다음 작업을 수행하세요.
Google Cloud 콘솔에서 Google Kubernetes Engine 페이지로 이동합니다.
add_box만들기를 클릭합니다.
구성을 클릭하여 표준 클러스터를 구성합니다.
네트워킹 섹션에서 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 wide
GKE 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
을 클러스터 이름으로 바꾸거나 완전히 삭제하여 모든 클러스터의 로그를 확인합니다.
알려진 문제
GKE Dataplane V2 클러스터의 NodePort 범위 충돌과 관련된 간헐적인 연결 문제
GKE Dataplane V2 클러스터에서 매스커레이드 트래픽 또는 임시 포트 사용에 간헐적인 연결 문제가 발생할 수 있습니다. 이러한 문제는 예약된 NodePort 범위와의 잠재적인 포트 충돌로 인해 발생하며 일반적으로 다음 시나리오에서 발생합니다.
커스텀
ip-masq-agent
: 클러스터에 NodePort 또는 부하 분산기 서비스가 있는 커스텀ip-masq-agent
(버전 2.10 이상)를 사용하는 경우 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가 사용 설정된 클러스터의 네트워크 정책에 endPort
필드를 지정하면 적용되지 않습니다.
GKE 1.22부터 Kubernetes 네트워크 정책 API를 사용하면 네트워크 정책이 적용되는 포트 범위를 지정할 수 있습니다. 이 API는 Calico 네트워크 정책이 있는 클러스터에서 지원되지만 GKE Dataplane V2가 있는 클러스터에서는 지원되지 않습니다.
NetworkPolicy
객체를 API 서버에 작성한 후 다시 읽어 해당 객체의 동작을 확인할 수 있습니다. 객체에 여전히 endPort
필드가 포함되어 있으면 기능이 적용됩니다. endPort
필드가 누락되면 이 기능이 적용되지 않습니다. 어떤 경우든 API 서버에 저장된 객체는 네트워크 정책의 정보 소스입니다.
자세한 내용은 KEP-2079: 포트 범위를 지원하는 네트워크 정책을 참조하세요.
포드에 failed to allocate for range 0: no IP addresses available in range set
오류 메시지 표시
영향을 받는 GKE 버전: 1.22 ~ 1.25
containerd를 사용하고 GKE Dataplane V2가 사용 설정된 노드 풀을 실행하는 GKE 클러스터는 IP 주소 누출 문제가 발생할 수 있고 한 노드에서 포드 IP 주소를 모두 소진할 수 있습니다. 영향을 받는 노드에서 예약된 포드는 다음과 비슷한 오류 메시지를 표시합니다.
failed to allocate for range 0: no IP addresses available in range set: 10.48.131.1-10.48.131.62
이 문제에 대한 자세한 내용은 containerd 문제 #5768을 참조하세요.
수정된 버전
이 문제를 해결하려면 다음 GKE 버전 중 하나로 클러스터를 업그레이드합니다.
- 1.22.17-gke.3100 이상
- 1.23.16-gke.200 이상
- 1.24.9-gke.3200 이상
- 1.25.6-gke.200 이상
표준 GKE 클러스터의 해결 방법
노드의 누출된 포드 IP 주소를 삭제하여 이 문제를 완화할 수 있습니다.
누출된 포드 IP 주소를 삭제하려면 클러스터에 대해 인증 사용자 인증 정보를 가져오고 다음 단계를 실행하여 단일 노드를 삭제합니다(이름을 알고 있는 경우).
다음 셸 스크립트를
cleanup.sh
파일에 저장합니다.for hash in $(sudo find /var/lib/cni/networks/gke-pod-network -iregex '/var/lib/cni/networks/gke-pod-network/[0-9].*' -exec head -n1 {} \;); do hash="${hash%%[[:space:]]}"; if [ -z $(sudo ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then sudo grep -ilr $hash /var/lib/cni/networks/gke-pod-network; fi; done | sudo xargs -r rm
클러스터 노드에서 스크립트를 실행합니다.
gcloud compute ssh --zone "ZONE" --project "PROJECT" NODE_NAME --command "$(cat cleanup.sh)"
NODE_NAME
을 허브 이름으로 바꿉니다.
이 스크립트의 DaemonSet 버전을 실행하여 모든 노드에서 한 번에 동시에 실행할 수도 있습니다.
다음 매니페스트를
cleanup-ips.yaml
이라는 파일에 저장합니다.apiVersion: apps/v1 kind: DaemonSet metadata: name: cleanup-ipam-dir namespace: kube-system spec: selector: matchLabels: name: cleanup-ipam template: metadata: labels: name: cleanup-ipam spec: hostNetwork: true securityContext: runAsUser: 0 runAsGroup: 0 containers: - name: cleanup-ipam image: gcr.io/gke-networking-test-images/ubuntu-test:2022 command: - /bin/bash - -c - | while true; do for hash in $(find /hostipam -iregex '/hostipam/[0-9].*' -mmin +10 -exec head -n1 {} \; ); do hash="${hash%%[[:space:]]}" if [ -z $(ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then grep -ilr $hash /hostipam fi done | xargs -r rm echo "Done cleaning up /var/lib/cni/networks/gke-pod-network at $(date)" sleep 120s done volumeMounts: - name: host-ipam mountPath: /hostipam - name: host-ctr mountPath: /run/containerd volumes: - name: host-ipam hostPath: path: /var/lib/cni/networks/gke-pod-network - name: host-ctr hostPath: path: /run/containerd
클러스터에서 daemonset을 실행합니다.
kubectl apply -f cleanup-ips.yaml
이 명령어를 실행하려면 클러스터의 관리자로서 kubectl 액세스 권한이 있어야 합니다.
실행 중인 DaemonSet의 로그를 확인합니다.
kubectl -n kube-system logs -l name=cleanup-ipam
잘못된 연결 추적 조회로 인해 네트워크 정책이 연결을 중단
클라이언트 포드가 내부 패스 스루 네트워크 부하 분산기의 서비스 또는 가상 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 Dataplane V2 작동 방식에 대해 알아보기