Memecahkan masalah Google Distributed Cloud NFS dan DataPlane v2

Dokumen ini menjelaskan prosedur manual untuk Google Distributed Cloud jika Anda mengalami masalah dengan penyangga NFS yang memiliki volume macet atau Pod, dan Anda telah membuat cluster dengan DataPlane v2 diaktifkan.

Masalah ini telah diperbaiki untuk versi berikut:

  • Untuk versi minor 1.16, versi 1.16.4-gke.37 dan yang lebih tinggi.
  • Untuk versi minor 1.28, versi 1.28.200-gke.111 dan yang lebih tinggi.

Sebaiknya upgrade ke versi versi di mana masalah ini telah diperbaiki. Jika Anda tidak dapat melakukan upgrade, gunakan prosedur yang diuraikan di bagian-bagian berikut.

Jika Anda menggunakan versi yang belum memperbaiki masalah ini, Anda mungkin mengalami masalah jika Anda memiliki workload yang menggunakan volume ReadWriteMany yang didukung oleh penyimpanan pengemudi yang rentan terhadap masalah ini, seperti (tetapi tidak terbatas pada):

  • Robin.io
  • Portworx (sharedv4 volume layanan)
  • csi-nfs

Pemasangan NFS pada beberapa arsitektur penyimpanan dapat macet ketika yang terhubung ke endpoint menggunakan Layanan Kubernetes (ClusterIP) dan DataPlane v2. Perilaku ini disebabkan oleh keterbatasan cara kerja kode soket {i>kernel<i} Linux berinteraksi dengan program eBPF Cillium. Container dapat diblokir di I/O atau bahkan tidak dapat dimatikan, karena dudukan NFS yang sudah tidak berfungsi tidak dapat dilepas.

Anda mungkin mengalami masalah ini jika menggunakan penyimpanan RWX yang dihosting di server NFS yang berjalan pada node Kubernetes, termasuk software-defined atau hyperkonvergensi solusi penyimpanan Anda seperti {i>Ondat<i}, Robin.io, atau Portworx.

Jika Anda memerlukan bantuan tambahan, hubungi Cloud Customer Care.

Tinjau konfigurasi cluster yang ada

Dapatkan beberapa nilai konfigurasi yang ada dari cluster Anda. Anda menggunakan nilai-nilai dari langkah-langkah ini untuk membuat manifes kube-proxy di bagian berikutnya.

  1. Dapatkan ClusterCIDR dari cm/cilium-config:

    kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
    

    Contoh output berikut menunjukkan bahwa Anda akan menggunakan 192.168.0.0/16 sebagai ClusterCIDR:

    ipv4-native-routing-cidr: 192.168.0.0/16
    native-routing-cidr: 192.168.0.0/16
    
  2. Dapatkan APIServerAdvertiseAddress dan APIServerPort dari anetd DaemonSet:

    kubectl get ds -n kube-system  anetd -o yaml | grep KUBERNETES -A 1
    

    Contoh output berikut menunjukkan bahwa Anda akan menggunakan 21.1.4.119 sebagai APIServerAdvertiseAddress dan 443 sebagai APIServerPort:

    - name: KUBERNETES_SERVICE_HOST
      value: 21.1.4.119
    - name: KUBERNETES_SERVICE_PORT
      value: "443"
    
  3. Mendapatkan RegistryCredentialsSecretName dari anetd Set Daemon:

    kubectl get ds -n kube-system  anetd -o yaml | grep imagePullSecrets -A 1
    

    Contoh {i>output<i} berikut menunjukkan bahwa Anda akan menggunakan private-registry-creds sebagai RegistryCredentialsSecretName:

    imagePullSecrets:
      - name: private-registry-creds
    
  4. Mendapatkan Registry dari DameonSet anetd:

    kubectl get ds -n kube-system  anetd -o yaml | grep image
    

    Contoh {i>output<i} berikut menunjukkan bahwa Anda akan menggunakan gcr.io/gke-on-prem-release sebagai Registry:

    image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
    
  5. Dapatkan KubernetesVersion dari tag gambar untuk kube-apiserver di namespace cluster cluster admin:

    KUBECONFIG=ADMIN_KUBECONFIG
    kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
    

    Ganti ADMIN_KUBECONFIG dengan file kubeconfig untuk Anda cluster admin dan CLUSTER_NAME dengan nama pengguna Anda .

    Contoh output berikut menunjukkan bahwa Anda akan menggunakan v1.26.2-gke.1001 sebagai KubernetesVersion:

    image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001
    imagePullPolicy: IfNotPresent
    

Menyiapkan manifes kube-proxy

Gunakan nilai yang diperoleh di bagian sebelumnya untuk membuat dan menerapkan YAML manifes yang akan men-deploy kube-proxy ke cluster Anda.

  1. Buat manifes bernama kube-proxy.yaml di editor pilihan Anda:

    nano kube-proxy.yaml
    
  2. Salin dan tempel definisi YAML berikut:

    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
    

    Dalam manifes YAML ini, tetapkan nilai berikut:

    • APIServerAdvertiseAddress: nilai KUBERNETES_SERVICE_HOST, seperti 21.1.4.119.
    • APIServerPort: nilai KUBERNETES_SERVICE_PORT, seperti 443.
    • Registry: awalan gambar Cilium, seperti gcr.io/gke-on-prem-release.
    • RegistryCredentialsSecretName: rahasia pull image seperti private-registry-creds.
  3. Simpan dan tutup file manifes di editor Anda.

Siapkan patch anetd

Membuat dan menyiapkan update untuk anetd:

  1. Buat manifes bernama cilium-config-patch.yaml di editor file pilihan:

    nano cilium-config-patch.yaml
    
  2. Salin dan tempel definisi YAML berikut:

    data:
      kube-proxy-replacement: "disabled"
      kube-proxy-replacement-healthz-bind-address: ""
      retry-kube-proxy-healthz-binding: "false"
      enable-host-reachable-services: "false"
    
  3. Simpan dan tutup file manifes di editor Anda.

Men-deploy kube-proxy dan mengonfigurasi ulang anetd

Terapkan perubahan konfigurasi pada cluster Anda. Buat cadangan konfigurasi yang ada sebelum Anda menerapkan perubahan.

  1. Cadangkan konfigurasi anetd dan cilium-config Anda saat ini:

    kubectl get ds -n kube-system anetd > anetd-original.yaml
    kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
    
  2. Terapkan kube-proxy.yaml menggunakan kubectl:

    kubectl apply -f kube-proxy.yaml
    
  3. Pastikan Pod adalah Running:

    kubectl get pods -n kube-system -o wide | grep kube-proxy
    

    Contoh output ringkas berikut menunjukkan bahwa Pod sedang berjalan dengan benar:

    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)    [...]
    
  4. Tambahkan patch ConfigMap cilium-config menggunakan kubectl:

    kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
    
  5. Edit anetd menggunakan kubectl:

    kubectl edit ds -n kube-system anetd
    

    Di editor yang terbuka, edit spesifikasi anetd. Sisipkan kolom berikut sebagai item pertama pada initContainers:

    - 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
    

    Ganti Image dengan gambar yang sama dengan yang digunakan di Cilium lainnya container di DaemonSet anetd, seperti gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7.

  6. Simpan dan tutup file manifes di editor Anda.

  7. Untuk menerapkan perubahan ini, mulai ulang semua node di cluster Anda. Untuk meminimalkan gangguan, Anda dapat mencoba menguras setiap {i>node<i} sebelum {i>reboot<i}. Namun, Pod yang menggunakan volume RWX dapat macet dalam status Terminating karena NFS rusak penyangga yang menghalangi proses pengosongan.

    Anda dapat menghapus paksa Pod yang diblokir dan membiarkan Node berfungsi dengan benar:

    kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
    

    Ganti POD_NAME dengan Pod yang Anda coba hapus dan POD_NAMESPACE dengan namespace-nya.

Langkah selanjutnya

Jika Anda memerlukan bantuan tambahan, hubungi Cloud Customer Care.