Questo documento descrive una procedura manuale per Google Distributed Cloud se hai problemi con i mount NFS con un volume o un pod bloccato e hai creato il cluster con DataPlane v2 abilitato.
Questo problema è stato risolto per le seguenti versioni:
- Per la versione secondaria 1.16, la versione 1.16.4-gke.37 e successive.
- Per la versione secondaria 1.28, la versione 1.28.200-gke.111 e successive.
Ti consigliamo di eseguire l'upgrade a una versione in cui questo problema è stato risolto. Se non riesci a eseguire l'upgrade, utilizza le procedure descritte nelle sezioni seguenti.
Se utilizzi una versione in cui questo problema non è stato risolto, potresti riscontrare problemi se hai carichi di lavoro che utilizzano volumi ReadWriteMany
basati su driver di archiviazione soggetti a questo problema, ad esempio (a titolo esemplificativo):
- Robin.io
- Portworx (volumi di servizio
sharedv4
) csi-nfs
I mount NFS su alcune architetture di archiviazione potrebbero bloccarsi quando sono collegati a un endpoint utilizzando un servizio Kubernetes (ClusterIP) e DataPlane v2. Questo comportamento è dovuto alle limitazioni del modo in cui il codice socket del kernel di Linux interagisce con il programma eBPF di Cillium. I container potrebbero bloccarsi sull'I/O o persino non essere uccisi, poiché il montaggio NFS non funzionante non può essere smontato.
Questo problema potrebbe verificarsi se utilizzi lo spazio di archiviazione RWX
ospitato su server NFS
che vengono eseguiti su un nodo Kubernetes, incluse soluzioni di archiviazione hyperconverged o software-defined come Ondat, Robin.io o Portworx.
Rivedi la configurazione del cluster esistente
Ottieni alcuni valori di configurazione esistenti dal tuo cluster. Utilizza i valori
di questi passaggi per creare un manifest kube-proxy
nella sezione successiva.
Ricevi il
ClusterCIDR
dacm/cilium-config
:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
L'esempio di output seguente mostra che dovresti utilizzare
192.168.0.0/16
comeClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Recupera
APIServerAdvertiseAddress
eAPIServerPort
dal DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
L'esempio di output seguente mostra che dovresti utilizzare
21.1.4.119
comeAPIServerAdvertiseAddress
e443
comeAPIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Ottieni
RegistryCredentialsSecretName
dalanetd
DaemonSet:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
L'esempio di output seguente mostra che dovresti utilizzare
private-registry-creds
comeRegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
Ottieni
Registry
dal set di demonianetd
:kubectl get ds -n kube-system anetd -o yaml | grep image
L'esempio di output seguente mostra che dovresti utilizzare
gcr.io/gke-on-prem-release
comeRegistry
:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
Recupera
KubernetesVersion
dal tag immagine perkube-apiserver
nello spazio dei nomi del cluster di amministrazione:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
Sostituisci
ADMIN_KUBECONFIG
con il file kubeconfig per il tuo cluster amministrativo eCLUSTER_NAME
con il nome del tuo cluster utente.L'esempio di output seguente mostra che devi utilizzare
v1.26.2-gke.1001
comeKubernetesVersion
:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Prepara i manifest kube-proxy
Utilizza i valori ottenuti nella sezione precedente per creare e applicare un manifest YAML che eseguirà il deployment di kube-proxy
nel tuo cluster.
Crea un file manifest denominato
kube-proxy.yaml
nell'editor che preferisci:nano kube-proxy.yaml
Copia e incolla la seguente definizione 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
In questo manifest YAML, imposta i seguenti valori:
APIServerAdvertiseAddress
: il valore diKUBERNETES_SERVICE_HOST
, ad esempio21.1.4.119
.APIServerPort
: il valore diKUBERNETES_SERVICE_PORT
, ad esempio443
.Registry
: il prefisso dell'immagine Cilium, ad esempiogcr.io/gke-on-prem-release
.RegistryCredentialsSecretName
: il nome del segreto per il recupero delle immagini, ad esempioprivate-registry-creds
.
Salva e chiudi il file manifest nell'editor.
Prepara la patch anetd
Crea e prepara un aggiornamento per anetd
:
Crea un file manifest denominato
cilium-config-patch.yaml
nell'editor che preferisci:nano cilium-config-patch.yaml
Copia e incolla la seguente definizione YAML:
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
Salva e chiudi il file manifest nell'editor.
Esegui il deployment di kube-proxy
e riconfigura anetd
Applica le modifiche alla configurazione al cluster. Crea i backup della configurazione esistente prima di applicare le modifiche.
Esegui il backup della configurazione attuale di
anetd
ecilium-config
:kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
Applica
kube-proxy.yaml
utilizzandokubectl
:kubectl apply -f kube-proxy.yaml
Verifica che i pod siano
Running
:kubectl get pods -n kube-system -o wide | grep kube-proxy
L'esempio seguente mostra l'output condensato che indica che i pod sono in esecuzione correttamente:
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) [...]
Esegui la patch del ConfigMap
cilium-config
utilizzandokubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Modifica
anetd
utilizzandokubectl
:kubectl edit ds -n kube-system anetd
Nell'editor che si apre, modifica le specifiche di
anetd
. Inserisci quanto segue come primo elemento ininitContainers
:- 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
Sostituisci
Image
con la stessa immagine utilizzata negli altri container Cilium nel DaemonSetanetd
, ad esempiogcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
.Salva e chiudi il file manifest nell'editor.
Per applicare queste modifiche, riavvia tutti i nodi del cluster. Per ridurre al minimo la interruzione, puoi provare a svuotare ogni nodo prima del riavvio. Tuttavia, i pod che utilizzano volumi RWX potrebbero rimanere bloccati in uno stato
Terminating
a causa di montaggi NFS danneggiati che bloccano il processo di svuotamento.Puoi eliminare forzatamente i pod bloccati e consentire il corretto svuotamento del nodo:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
Sostituisci
POD_NAME
con il pod che stai tentando di eliminare ePOD_NAMESPACE
con il relativo spazio dei nomi.