Este documento detalha um procedimento manual para o Google Distributed Cloud se tiver problemas com montagens NFS com um volume ou um pod bloqueado e tiver criado o cluster com o DataPlane v2 ativado.
Este problema foi corrigido para as seguintes versões:
- Para a versão secundária 1.16, versão 1.16.4-gke.37 e superior.
- Para a versão secundária 1.28, versão 1.28.200-gke.111 e superior.
Recomendamos que atualize para uma versão em que este problema esteja corrigido. Se não conseguir atualizar, use os procedimentos descritos nas secções seguintes.
Se estiver a usar uma versão em que este problema não está corrigido, pode ter problemas se tiver cargas de trabalho que usem volumes ReadWriteMany com tecnologia de controladores de armazenamento suscetíveis a este problema, como (entre outros):
- Robin.io
- Portworx (volumes de serviço
sharedv4) csi-nfs
As montagens NFS em algumas arquiteturas de armazenamento podem ficar bloqueadas quando estão ligadas a um ponto final através de um serviço Kubernetes (ClusterIP) e do DataPlane v2. Este comportamento deve-se às limitações na forma como o código de soquete do kernel do Linux interage com o programa eBPF do Cillium. Os contentores podem ficar bloqueados na E/S ou até mesmo não ser elimináveis, uma vez que não é possível desmontar a montagem NFS obsoleta.
Pode ter este problema se usar o armazenamento RWX alojado em servidores NFS
que são executados num nó do Kubernetes, incluindo soluções de armazenamento
definidas por software ou hiperconverged, como Ondat, Robin.io ou Portworx.
Reveja a configuração do cluster existente
Obter alguns valores de configuração existentes do seu cluster. Use os valores
destes passos para criar um kube-proxy manifesto na secção seguinte.
Apanhe a linha
ClusterCIDRna estaçãocm/cilium-config:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidrO exemplo de resultado seguinte mostra que usaria
192.168.0.0/16como oClusterCIDR:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16Obtenha o
APIServerAdvertiseAddresse oAPIServerPortdo DaemonSetanetd:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1O resultado do exemplo seguinte mostra que usaria
21.1.4.119comoAPIServerAdvertiseAddresse443comoAPIServerPort:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"Obtenha o
RegistryCredentialsSecretNamedoanetdDaemonSet:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1O exemplo de resultado seguinte mostra que usaria
private-registry-credscomoRegistryCredentialsSecretName:imagePullSecrets: - name: private-registry-credsObtenha o
Registrydo DaemonSetanetd:kubectl get ds -n kube-system anetd -o yaml | grep imageO exemplo de resultado seguinte mostra que usaria
gcr.io/gke-on-prem-releasecomoRegistry:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7Obtenha o
KubernetesVersionda etiqueta de imagem parakube-apiserverno espaço de nomes do cluster do cluster de administrador:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep imageSubstitua
ADMIN_KUBECONFIGpelo ficheiro kubeconfig do cluster de administrador eCLUSTER_NAMEpelo nome do cluster de utilizador.O exemplo de saída seguinte mostra que usaria
v1.26.2-gke.1001comoKubernetesVersion:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Prepare kube-proxy manifestos
Use os valores obtidos na secção anterior para criar e aplicar um manifesto YAML que implemente o kube-proxy no cluster.
Crie um manifesto denominado
kube-proxy.yamlno editor à sua escolha:nano kube-proxy.yamlCopie e cole a seguinte definição 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-systemNeste manifesto YAML, defina os seguintes valores:
APIServerAdvertiseAddress: o valor deKUBERNETES_SERVICE_HOST, como21.1.4.119.APIServerPort: o valor deKUBERNETES_SERVICE_PORT, como443.Registry: o prefixo da imagem do Cilium, comogcr.io/gke-on-prem-release.RegistryCredentialsSecretName: o nome do segredo de obtenção de imagens, comoprivate-registry-creds.
Guarde e feche o ficheiro de manifesto no editor.
Prepare o patch anetd
Crie e prepare uma atualização para anetd:
Crie um manifesto com o nome
cilium-config-patch.yamlno editor à sua escolha:nano cilium-config-patch.yamlCopie e cole a seguinte definição YAML:
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"Guarde e feche o ficheiro de manifesto no editor.
Implemente kube-proxy e reconfigure anetd
Aplique as alterações de configuração ao cluster. Crie cópias de segurança da sua configuração existente antes de aplicar as alterações.
Faça uma cópia de segurança da configuração atual do
anetde docilium-config:kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yamlAplique
kube-proxy.yamlatravés dekubectl:kubectl apply -f kube-proxy.yamlVerifique se os Pods estão
Running:kubectl get pods -n kube-system -o wide | grep kube-proxyO exemplo de saída condensada seguinte mostra que os pods estão a ser executados corretamente:
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) [...]Aplique uma correção ao
cilium-configConfigMap através dekubectl:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yamlEdite
anetdcomkubectl:kubectl edit ds -n kube-system anetdNo editor apresentado, edite a especificação de
anetd. Insira o seguinte como o primeiro item eminitContainers:- 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: trueSubstitua
Imagepela mesma imagem usada nos outros contentores Cilium no DaemonSetanetd, comogcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7.Guarde e feche o ficheiro de manifesto no editor.
Para aplicar estas alterações, reinicie todos os nós no cluster. Para minimizar a interrupção, pode tentar esgotar cada nó antes do reinício. No entanto, os pods que usam volumes RWX podem ficar bloqueados num estado
Terminatingdevido a montagens NFS danificadas que bloqueiam o processo de drenagem.Pode forçar a eliminação de pods bloqueados e permitir que o nó seja esvaziado corretamente:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAMESubstitua
POD_NAMEpelo pod que está a tentar eliminar ePOD_NAMESPACEpelo respetivo espaço de nomes.
O que se segue?
Se precisar de assistência adicional, contacte o apoio ao cliente do Google Cloud.
Também pode consultar o artigo Receber apoio técnico para mais informações sobre recursos de apoio técnico, incluindo o seguinte:
- Requisitos para abrir um registo de apoio técnico.
- Ferramentas para ajudar a resolver problemas, como registos e métricas.
- Componentes suportados, versões e funcionalidades do Google Distributed Cloud para VMware (apenas software).