In diesem Dokument wird eine manuelle Vorgehensweise für Google Distributed Cloud beschrieben, wenn Sie Probleme mit NFS-Bereitstellungen mit einem hängengebliebenen Volume oder Pod haben und Ihren Cluster mit aktivierter DataPlane v2 erstellt haben.
Dieses Problem wurde in den folgenden Versionen behoben:
- Für die Nebenversion 1.16 Version 1.16.4-gke.37 und höher.
- Für die Nebenversion 1.28 Version 1.28.200-gke.111 und höher.
Wir empfehlen Ihnen, ein Upgrade auf eine Version durchzuführen, in der dieses Problem behoben ist. Wenn Sie kein Upgrade durchführen können, folgen Sie der Anleitung in den folgenden Abschnitten.
Wenn Sie eine Version verwenden, in der dieses Problem nicht behoben ist, können bei Arbeitslasten mit ReadWriteMany-Volumes, die von Speichertreibern unterstützt werden, die anfällig für dieses Problem sind, Probleme auftreten. Beispiele:
- Robin.io
- Portworx (
sharedv4-Dienstvolumes) csi-nfs
NFS-Bereitstellungen in einigen Speicherarchitekturen können hängen bleiben, wenn sie über einen Kubernetes-Dienst (ClusterIP) und DataPlane v2 mit einem Endpunkt verbunden sind. Dieses Verhalten ist auf die Einschränkungen zurückzuführen, die bei der Interaktion des Linux-Kernel-Socket-Codes mit dem eBPF-Programm von Cillium auftreten. Container können bei E/A blockiert werden oder sogar nicht zu beenden sein, da die stillgelegte NFS-Bereitstellung nicht getrennt werden kann.
Dieses Problem kann auftreten, wenn Sie RWX-Speicher verwenden, der auf NFS-Servern gehostet wird, die auf einem Kubernetes-Knoten ausgeführt werden, einschließlich softwaredefinierter oder hyperkonvergenter Speicherlösungen wie Ondat, Robin.io oder Portworx.
Vorhandene Clusterkonfiguration prüfen
Rufen Sie einige vorhandene Konfigurationswerte aus Ihrem Cluster ab. Mit den Werten aus diesen Schritten erstellen Sie im nächsten Abschnitt ein kube-proxy-Manifest.
ClusterCIDRvoncm/cilium-configabrufen:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidrIn der folgenden Beispielausgabe wird gezeigt, dass Sie
192.168.0.0/16alsClusterCIDRverwenden würden:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16Rufen Sie
APIServerAdvertiseAddressundAPIServerPortaus demanetd-DaemonSet ab:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1In der folgenden Beispielausgabe wird gezeigt, dass Sie
21.1.4.119alsAPIServerAdvertiseAddressund443alsAPIServerPortverwenden würden:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"RegistryCredentialsSecretNameaus demanetd-DaemonSet abrufen:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1In der folgenden Beispielausgabe wird gezeigt, dass Sie
private-registry-credsalsRegistryCredentialsSecretNameverwenden würden:imagePullSecrets: - name: private-registry-credsRegistryaus demanetd-Daemonset abrufen:kubectl get ds -n kube-system anetd -o yaml | grep imageIn der folgenden Beispielausgabe wird gezeigt, dass Sie
gcr.io/gke-on-prem-releasealsRegistryverwenden würden:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7Rufen Sie die
KubernetesVersionaus dem Image-Tag fürkube-apiserverim Cluster-Namespace des Administratorclusters ab:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep imageErsetzen Sie
ADMIN_KUBECONFIGdurch die kubeconfig-Datei Ihres Administratorclusters undCLUSTER_NAMEdurch den Namen Ihres Nutzerclusters.In der folgenden Beispielausgabe wird gezeigt, dass Sie
v1.26.2-gke.1001alsKubernetesVersionverwenden würden:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
kube-proxy-Manifeste vorbereiten
Verwenden Sie die im vorherigen Abschnitt ermittelten Werte, um ein YAML-Manifest zu erstellen und anzuwenden, mit dem kube-proxy in Ihrem Cluster bereitgestellt wird.
Erstellen Sie in einem Editor Ihrer Wahl ein Manifest mit dem Namen
kube-proxy.yaml:nano kube-proxy.yamlKopieren Sie die folgende YAML-Definition und fügen Sie sie ein:
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-systemLegen Sie in diesem YAML-Manifest die folgenden Werte fest:
APIServerAdvertiseAddress: der Wert vonKUBERNETES_SERVICE_HOST, z. B.21.1.4.119.APIServerPort: der Wert vonKUBERNETES_SERVICE_PORT, z. B.443.Registry: Das Präfix des Cilium-Images, z. B.gcr.io/gke-on-prem-release.RegistryCredentialsSecretName: der Name des Pull-Secrets für das Image, z. B.private-registry-creds.
Speichern und schließen Sie die Manifestdatei in Ihrem Editor.
anetd-Patch vorbereiten
So erstellen und bereiten Sie ein Update für anetd vor:
Erstellen Sie in einem Editor Ihrer Wahl ein Manifest mit dem Namen
cilium-config-patch.yaml:nano cilium-config-patch.yamlKopieren Sie die folgende YAML-Definition und fügen Sie sie ein:
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"Speichern und schließen Sie die Manifestdatei in Ihrem Editor.
kube-proxy bereitstellen und anetd neu konfigurieren
Wenden Sie die Konfigurationsänderungen auf Ihren Cluster an. Erstellen Sie Sicherungen Ihrer vorhandenen Konfiguration, bevor Sie die Änderungen anwenden.
Sichern Sie die aktuelle
anetd- undcilium-config-Konfiguration:kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yamlWenden Sie
kube-proxy.yamlmitkubectlan:kubectl apply -f kube-proxy.yamlPrüfen Sie, ob die Pods
Runningsind:kubectl get pods -n kube-system -o wide | grep kube-proxyDie folgende komprimierte Beispielausgabe zeigt, dass die Pods ordnungsgemäß ausgeführt werden:
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) [...]Patchen Sie die ConfigMap
cilium-configmitkubectl:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yamlBearbeiten Sie
anetdmitkubectl:kubectl edit ds -n kube-system anetdBearbeiten Sie im geöffneten Editor die Spezifikation von
anetd. Fügen Sie Folgendes als erstes Element unterinitContainersein:- 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: trueErsetzen Sie
Imagedurch dasselbe Image, das in den anderen Cilium-Containern imanetd-DaemonSet verwendet wird, z. B.gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7.Speichern und schließen Sie die Manifestdatei in Ihrem Editor.
Starten Sie alle Knoten in Ihrem Cluster neu, um diese Änderungen anzuwenden. Um Unterbrechungen zu minimieren, können Sie versuchen, vor dem Neustart jeden Knoten per Drain zu beenden. Pods mit RWX-Volumes können jedoch aufgrund fehlerhafter NFS-Bereitstellungen, die den Drain-Prozess blockieren, im Status
Terminatinghängen bleiben.Sie können blockierte Pods erzwungen löschen und dem Knoten ermöglichen, ordnungsgemäß per Drain beendet zu werden:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAMEErsetzen Sie
POD_NAMEdurch den Pod, den Sie löschen möchten, undPOD_NAMESPACEdurch seinen Namespace.
Nächste Schritte
Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.
Weitere Informationen zu Supportressourcen finden Sie unter Support. Dazu gehören:
- Anforderungen für das Öffnen einer Supportanfrage
- Tools zur Fehlerbehebung, z. B. Protokolle und Messwerte.
- Unterstützte Komponenten, Versionen und Funktionen von Google Distributed Cloud for VMware (nur Software)