Neste documento, detalhamos um procedimento manual do GKE no VMware se você tiver problemas
com as montagens NFS com um volume ou pod travado e tiver criado o cluster com
o DataPlane v2 ativado. Talvez você encontre problemas se tiver cargas de trabalho usando
volumes ReadWriteMany
com drivers de armazenamento suscetíveis a esse
problema, como, entre outros:
- Robin.io
- Portworx (
sharedv4
de volumes de serviço) csi-nfs
As montagens NFS em algumas arquiteturas de armazenamento podem ficar travadas quando estão conectadas a um endpoint usando um Serviço do Kubernetes (ClusterIP) e o DataPlane v2. Esse comportamento se deve às limitações na forma como o código de soquete do kernel do Linux interage com o programa eBPF do Cillium. Os contêineres podem ficar bloqueados na E/S ou até mesmo não poderem ser eliminados, já que a montagem NFS extinta não pode ser desmontada.
Você poderá enfrentar esse problema se usar o armazenamento RWX
hospedado em servidores NFS que
são executados em um nó do Kubernetes, incluindo soluções de armazenamento definidas por software ou hiperconvergentes, como Ondat, Robin.io ou Portworx.
Revisar a configuração do cluster atual
Receba alguns valores de configuração atuais do cluster. Use os valores
dessas etapas para criar um manifesto kube-proxy
na próxima seção.
Acesse o
ClusterCIDR
decm/cilium-config
:kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
O exemplo de saída a seguir mostra que você usaria
192.168.0.0/16
comoClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Receba
APIServerAdvertiseAddress
eAPIServerPort
do DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
O exemplo de saída a seguir mostra que você usaria
21.1.4.119
comoAPIServerAdvertiseAddress
e443
comoAPIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Receba o
RegistryCredentialsSecretName
do DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
O exemplo de saída a seguir mostra que você usaria
private-registry-creds
comoRegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
Receba o
Registry
do DameonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep image
O exemplo de saída a seguir mostra que você 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
Receba o
KubernetesVersion
da tag de imagem parakube-apiserver
no namespace do cluster de administrador:KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
Substitua
ADMIN_KUBECONFIG
pelo arquivo kubeconfig do cluster de administrador eCLUSTER_NAME
pelo nome do cluster de usuário.O exemplo de saída a seguir mostra que você usaria
v1.26.2-gke.1001
comoKubernetesVersion
:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Preparar manifestos kube-proxy
Use os valores da seção anterior para criar e aplicar um manifesto YAML
que implantará kube-proxy
no cluster.
Crie um manifesto chamado
kube-proxy.yaml
no editor que preferir:nano kube-proxy.yaml
Copie e cole a seguinte definição de 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
Nesse 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 Cilium, comogcr.io/gke-on-prem-release
.RegistryCredentialsSecretName
: o nome do secret de extração da imagem, comoprivate-registry-creds
.
Salve e feche o arquivo de manifesto no editor.
Preparar patch anetd
Crie e prepare uma atualização para anetd
:
Crie um manifesto chamado
cilium-config-patch.yaml
no editor que preferir:nano cilium-config-patch.yaml
Copie e cole a seguinte definição de YAML:
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
Salve e feche o arquivo de manifesto no editor.
Implantar kube-proxy
e reconfigurar anetd
Aplique as alterações de configuração ao cluster. Crie backups da configuração atual antes de aplicar as alterações.
Faça backup 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
usandokubectl
: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 condensado a seguir mostra que os pods estão sendo 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 um patch ao ConfigMap
cilium-config
usandokubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Editar
anetd
usandokubectl
:kubectl edit ds -n kube-system anetd
No editor que é aberto, 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 contêineres Cilium no DaemonSetanetd
, comogcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
.Salve e feche o arquivo de manifesto no editor.
Para aplicar essas alterações, reinicie todos os nós do cluster. Para minimizar a interrupção, tente drenar cada nó antes da reinicialização. No entanto, os pods que usam volumes RWX podem ficar travados em um estado
Terminating
devido a montagens NFS interrompidas que bloqueiam o processo de drenagem.É possível forçar a exclusão de pods bloqueados e permitir que o nó seja drenado corretamente:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
Substitua
POD_NAME
pelo pod que você está tentando excluir ePOD_NAMESPACE
pelo namespace dele.