In diesem Dokument wird ein manuelles Verfahren für Google Distributed Cloud beschrieben, wenn Sie Probleme mit NFS-Bereitstellungen mit einem hängenden Volume oder Pod haben und den Cluster mit aktiviertem DataPlane v2 erstellt haben.
Dieses Problem wurde für die folgenden Versionen behoben:
- Bei Nebenversion 1.16, Version 1.16.4-gke.37 und höher.
- Bei Nebenversion 1.28, Version 1.28.200-gke.111 und höher.
Wir empfehlen ein Upgrade auf eine Version, in der dieses Problem behoben ist. Wenn Sie kein Upgrade durchführen können, gehen Sie wie in den folgenden Abschnitten beschrieben vor.
Wenn Sie eine Version verwenden, in der dieses Problem nicht behoben ist, treten möglicherweise Probleme auf, wenn Sie Arbeitslasten mit ReadWriteMany
-Volumes haben, die von Speichertreibern unterstützt werden, die für dieses Problem anfällig sind, z. B.:
- Robin.io
- Portworx (
sharedv4
Dienst-Volumes) 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 werden. Dieses Verhalten liegt an den Einschränkungen bei der Interaktion des Linux-Kernel-Socket-Codes mit dem eBPF-Programm von Cillium. Container werden möglicherweise auf der E/A blockiert oder können sogar nicht mehr beendet werden, da die deaktivierte NFS-Bereitstellung nicht getrennt werden kann.
Dieses Problem kann auftreten, wenn Sie RWX
-Speicher auf NFS-Servern verwenden, die auf einem Kubernetes-Knoten ausgeführt werden, einschließlich softwarebasierter oder hyperkonvergierter Speicherlösungen wie Ondat, Robin.io oder Portworx.
Vorhandene Clusterkonfiguration überprü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.
Holen Sie sich die
ClusterCIDR
voncm/cilium-config
:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
Die folgende Beispielausgabe zeigt, dass Sie
192.168.0.0/16
alsClusterCIDR
verwenden würden:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Rufen Sie
APIServerAdvertiseAddress
undAPIServerPort
aus dem DaemonSetanetd
ab:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
Die folgende Beispielausgabe zeigt, dass Sie
21.1.4.119
alsAPIServerAdvertiseAddress
und443
alsAPIServerPort
verwenden:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Rufen Sie
RegistryCredentialsSecretName
aus dem DaemonSetanetd
ab:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
Die folgende Beispielausgabe zeigt, dass Sie
private-registry-creds
alsRegistryCredentialsSecretName
verwenden würden:imagePullSecrets: - name: private-registry-creds
Hol dir das
Registry
aus dem DameonSet vonanetd
:kubectl get ds -n kube-system anetd -o yaml | grep image
Die folgende Beispielausgabe zeigt, dass Sie
gcr.io/gke-on-prem-release
alsRegistry
verwenden würden:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
Rufen Sie die
KubernetesVersion
aus dem Image-Tag fürkube-apiserver
im Cluster-Namespace des Administratorclusters ab:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
Ersetzen Sie
ADMIN_KUBECONFIG
durch die kubeconfig-Datei für Ihren Administratorcluster undCLUSTER_NAME
durch den Namen Ihres Nutzerclusters.Die folgende Beispielausgabe zeigt, dass Sie
v1.26.2-gke.1001
alsKubernetesVersion
verwenden: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 erhaltenen Werte, um ein YAML-Manifest zu erstellen und anzuwenden, das kube-proxy
in Ihrem Cluster bereitstellt.
Erstellen Sie im Editor Ihrer Wahl ein Manifest mit dem Namen
kube-proxy.yaml
:nano kube-proxy.yaml
Kopieren 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-system
Legen 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
ist der Name des Image-Pull-Secrets, z. B.private-registry-creds
.
Speichern und schließen Sie die Manifestdatei in Ihrem Editor.
anetd
-Patch vorbereiten
Erstellen Sie ein Update für anetd
und bereiten Sie es vor:
Erstellen Sie im Editor Ihrer Wahl ein Manifest mit dem Namen
cilium-config-patch.yaml
:nano cilium-config-patch.yaml
Kopieren 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 den Cluster an. Erstellen Sie Sicherungen Ihrer vorhandenen Konfiguration, bevor Sie die Änderungen anwenden.
Sichern Sie Ihre 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.yaml
Wenden Sie
kube-proxy.yaml
mitkubectl
an:kubectl apply -f kube-proxy.yaml
Prüfen Sie, ob die Pods
Running
sind:kubectl get pods -n kube-system -o wide | grep kube-proxy
Das folgende Beispiel für eine komprimierte Ausgabe 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-config
mitkubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Bearbeiten Sie
anetd
mitkubectl
:kubectl edit ds -n kube-system anetd
Bearbeiten Sie im Editor, der geöffnet wird, die Spezifikation von
anetd
. Fügen Sie als erstes Element unterinitContainers
Folgendes ein:- 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
Ersetzen Sie
Image
durch 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 im Cluster neu, um diese Änderungen zu übernehmen. Um Unterbrechungen zu minimieren, können Sie versuchen, jeden Knoten vor dem Neustart per Drain zu beenden. Pods, die RWX-Volumes verwenden, können jedoch im Status
Terminating
hängen bleiben, da fehlerhafte NFS-Bereitstellungen den Drain-Prozess blockieren.Sie können das Löschen blockierter Pods erzwingen und zulassen, dass der Knoten ordnungsgemäß per Drain beendet wird:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
Ersetzen Sie
POD_NAME
durch den Pod, den Sie löschen möchten, undPOD_NAMESPACE
durch dessen Namespace.