如果使用 NFS 掛接時發生問題,導致磁碟區或 Pod 停滯,且您建立叢集時已啟用 DataPlane v2,請按照本文的詳細手動程序操作。
下列版本已修正這個問題:
- 次要版本 1.16,版本 1.16.4-gke.37 以上。
- 次要版本 1.28:1.28.200-gke.111 以上版本。
建議升級至已修正這個問題的版本。如果無法升級,請按照下列各節所述程序操作。
如果您使用的版本未修正這個問題,且工作負載使用由儲存空間驅動程式支援的 ReadWriteMany
磁碟區,而這些驅動程式容易發生這個問題 (例如但不限於):
- Robin.io
- Portworx (
sharedv4
服務量) csi-nfs
透過 Kubernetes 服務 (ClusterIP) 和 DataPlane v2 連線至端點時,某些儲存空間架構上的 NFS 掛接點可能會停滯。這是因為 Linux 核心通訊端程式碼與 Cillium 的 eBPF 程式互動時,會受到限制。由於無法解除掛接已停用的 NFS 掛接點,容器可能會遭到 I/O 封鎖,甚至無法終止。
如果您使用 Kubernetes 節點上執行的 NFS 伺服器代管的 RWX
儲存空間,包括軟體定義或超融合儲存空間解決方案 (例如 Ondat、Robin.io 或 Portworx),就可能會遇到這個問題。
查看現有叢集設定
從叢集取得一些現有的設定值。您可以使用這些步驟中的值,在下一節中建立 kube-proxy
資訊清單。
從
cm/cilium-config
取得ClusterCIDR
:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
下列輸出範例顯示您會使用
192.168.0.0/16
做為ClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
從
anetd
DaemonSet 取得APIServerAdvertiseAddress
和APIServerPort
:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
下列範例輸出內容顯示您會使用
21.1.4.119
做為APIServerAdvertiseAddress
,並使用443
做為APIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
從
anetd
DaemonSet 取得RegistryCredentialsSecretName
:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
下列輸出範例顯示您會使用
private-registry-creds
做為RegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
從
anetd
DaemonSet 取得Registry
:kubectl get ds -n kube-system anetd -o yaml | grep image
下列輸出範例顯示您會使用
gcr.io/gke-on-prem-release
做為Registry
:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
在管理員叢集的叢集命名空間中,從映像檔標記取得
KubernetesVersion
:kube-apiserver
KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
將
ADMIN_KUBECONFIG
替換為管理員叢集的 kubeconfig 檔案,並將CLUSTER_NAME
替換為使用者叢集的名稱。以下輸出範例顯示您會將
v1.26.2-gke.1001
用做KubernetesVersion
:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
準備 kube-proxy
資訊清單
使用上一節取得的值建立並套用 YAML 資訊清單,將 kube-proxy
部署至叢集。
在您選擇的編輯器中建立名為
kube-proxy.yaml
的資訊清單:nano kube-proxy.yaml
複製並貼上下列 YAML 定義:
apiVersion: apps/v1 kind: DaemonSet metadata: labels: k8s-app: kube-proxy name: kube-proxy namespace: kube-system spec: selector: matchLabels: k8s-app: kube-proxy template: metadata: annotations: scheduler.alpha.kubernetes.io/critical-pod: "" labels: k8s-app: kube-proxy spec: containers: - command: - kube-proxy - --v=2 - --profiling=false - --iptables-min-sync-period=10s - --iptables-sync-period=1m - --oom-score-adj=-998 - --ipvs-sync-period=1m - --ipvs-min-sync-period=10s - --cluster-cidr=ClusterCIDR env: - name: KUBERNETES_SERVICE_HOST value:APIServerAdvertiseAddress - name: KUBERNETES_SERVICE_PORT value: "APIServerPort" image: Registry/kube-proxy-amd64:KubernetesVersion imagePullPolicy: IfNotPresent name: kube-proxy resources: requests: cpu: 100m memory: 15Mi securityContext: privileged: true volumeMounts: - mountPath: /run/xtables.lock name: xtables-lock - mountPath: /lib/modules name: lib-modules imagePullSecrets: - name: RegistryCredentialsSecretName nodeSelector: kubernetes.io/os: linux hostNetwork: true priorityClassName: system-node-critical serviceAccount: kube-proxy serviceAccountName: kube-proxy tolerations: - effect: NoExecute operator: Exists - effect: NoSchedule operator: Exists volumes: - hostPath: path: /run/xtables.lock type: FileOrCreate name: xtables-lock - hostPath: path: /lib/modules type: DirectoryOrCreate name: lib-modules --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:kube-proxy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:node-proxier subjects: - kind: ServiceAccount name: kube-proxy namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-proxy namespace: kube-system
在這個 YAML 資訊清單中,請設定下列值:
APIServerAdvertiseAddress
:KUBERNETES_SERVICE_HOST
的值,例如21.1.4.119
。APIServerPort
:KUBERNETES_SERVICE_PORT
的值,例如443
。Registry
:Cilium 映像檔的前置字串,例如gcr.io/gke-on-prem-release
。RegistryCredentialsSecretName
:圖片提取密碼名稱,例如private-registry-creds
。
在編輯器中儲存並關閉資訊清單檔案。
準備 anetd
修補程式
為 anetd
建立及準備更新:
在您選擇的編輯器中建立名為「
cilium-config-patch.yaml
」的資訊清單:nano cilium-config-patch.yaml
複製並貼上下列 YAML 定義:
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
在編輯器中儲存並關閉資訊清單檔案。
部署 kube-proxy
及重新設定 anetd
將設定變更套用至叢集。請先備份現有設定,再套用變更。
備份目前的
anetd
和cilium-config
設定:kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
使用
kubectl
套用kube-proxy.yaml
:kubectl apply -f kube-proxy.yaml
確認 Pod 處於
Running
狀態:kubectl get pods -n kube-system -o wide | grep kube-proxy
以下範例的精簡輸出內容顯示 Pod 正常運作:
kube-proxy-f8mp9 1/1 Running 1 (4m ago) [...] kube-proxy-kndhv 1/1 Running 1 (5m ago) [...] kube-proxy-sjnwl 1/1 Running 1 (4m ago) [...]
使用
kubectl
修補cilium-config
ConfigMap:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
使用
kubectl
編輯anetd
:kubectl edit ds -n kube-system anetd
在開啟的編輯器中,編輯
anetd
的規格。在initContainers
底下插入下列內容做為第一個項目:- name: check-kube-proxy-rules image: Image imagePullPolicy: IfNotPresent command: - sh - -ec - | if [ "$KUBE_PROXY_REPLACEMENT" != "strict" ]; then kube_proxy_forward() { iptables -L KUBE-FORWARD; } until kube_proxy_forward; do sleep 2; done fi; env: - name: KUBE_PROXY_REPLACEMENT valueFrom: configMapKeyRef: key: kube-proxy-replacement name: cilium-config optional: true securityContext: privileged: true
將
Image
換成anetd
DaemonSet 中其他 Cilium 容器使用的相同映像檔,例如gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
。在編輯器中儲存並關閉資訊清單檔案。
如要套用這些變更,請重新啟動叢集中的所有節點。為盡量減少中斷,您可以在重新啟動前嘗試排空每個節點。不過,由於 NFS 掛接中斷,導致 Pod 無法順利排空,因此使用 RWX 磁碟區的 Pod 可能會停留在
Terminating
狀態。您可以強制刪除遭封鎖的 Pod,並允許節點正確排空:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
將
POD_NAME
替換為要刪除的 Pod,並將POD_NAMESPACE
替換為該 Pod 的命名空間。
後續步驟
如需其他協助,請與 Cloud Customer Care 團隊聯絡。
如要進一步瞭解支援資源,包括下列項目,請參閱「取得支援」: