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
ClusterCIDR
na estaçãocm/cilium-config
:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
O exemplo de resultado seguinte mostra que usaria
192.168.0.0/16
como oClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Obtenha o
APIServerAdvertiseAddress
e oAPIServerPort
do DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
O resultado do exemplo seguinte mostra que usaria
21.1.4.119
comoAPIServerAdvertiseAddress
e443
comoAPIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Obtenha o
RegistryCredentialsSecretName
doanetd
DaemonSet:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
O exemplo de resultado seguinte mostra que usaria
private-registry-creds
comoRegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
Obtenha o
Registry
do DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep image
O exemplo de resultado seguinte mostra que usaria
gcr.io/gke-on-prem-release
comoRegistry
:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
Obtenha o
KubernetesVersion
da etiqueta de imagem parakube-apiserver
no espaço de nomes do cluster do cluster de administrador:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
Substitua
ADMIN_KUBECONFIG
pelo ficheiro kubeconfig do cluster de administrador eCLUSTER_NAME
pelo nome do cluster de utilizador.O exemplo de saída seguinte mostra que usaria
v1.26.2-gke.1001
comoKubernetesVersion
: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.yaml
no editor à sua escolha:nano kube-proxy.yaml
Copie 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-system
Neste 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.yaml
no editor à sua escolha:nano cilium-config-patch.yaml
Copie 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
anetd
e docilium-config
:kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
Aplique
kube-proxy.yaml
através dekubectl
:kubectl apply -f kube-proxy.yaml
Verifique se os Pods estão
Running
:kubectl get pods -n kube-system -o wide | grep kube-proxy
O 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-config
ConfigMap através dekubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Edite
anetd
comkubectl
:kubectl edit ds -n kube-system anetd
No 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: true
Substitua
Image
pela 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
Terminating
devido 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_NAME
Substitua
POD_NAME
pelo pod que está a tentar eliminar ePOD_NAMESPACE
pelo 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).