Menggunakan GKE Dataplane V2

Halaman ini menjelaskan cara mengaktifkan dan memecahkan masalah GKE Dataplane V2 untuk cluster Google Kubernetes Engine (GKE).

Cluster Autopilot baru memiliki GKE Dataplane V2 yang diaktifkan pada versi 1.22.7-gke.1500 dan yang lebih baru serta versi 1.23.4-gke.1500 dan yang lebih baru. Jika Anda mengalami masalah saat menggunakan GKE Dataplane V2, lanjutkan ke Pemecahan masalah.

Membuat cluster GKE dengan GKE Dataplane V2

Anda dapat mengaktifkan GKE Dataplane V2 saat membuat cluster baru dengan GKE versi 1.20.6-gke.700 dan yang lebih baru menggunakan gcloud CLI atau GKE API. Anda juga dapat mengaktifkan GKE Dataplane V2 di Pratinjau saat membuat cluster baru menggunakan GKE versi 1.17.9 dan yang lebih baru

Konsol

Untuk membuat cluster baru dengan GKE Dataplane V2, lakukan tugas berikut:

  1. Di Google Cloud konsol, buka halaman Create a Kubernetes cluster.

    Buka Create a Kubernetes cluster

  2. Di bagian Networking, pilih kotak centang Enable Dataplane V2. Opsi Aktifkan Kebijakan Jaringan Kubernetes akan dinonaktifkan saat Anda memilih Aktifkan Dataplane V2 karena penerapan kebijakan jaringan disertakan dalam GKE Dataplane V2.

  3. Klik Buat.

gcloud

Untuk membuat cluster baru dengan GKE Dataplane V2, gunakan perintah berikut:

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --release-channel CHANNEL_NAME \
    --location COMPUTE_LOCATION

Ganti kode berikut:

  • CLUSTER_NAME: nama cluster baru.
  • CHANNEL_NAME: saluran rilis yang menyertakan GKE versi 1.20.6-gke.700 atau yang lebih baru. Jika memilih untuk tidak menggunakan saluran rilis, Anda juga dapat menggunakan tanda --cluster-version, bukan --release-channel, dengan menentukan versi 1.20.6-gke.700 atau yang lebih baru.
  • COMPUTE_LOCATION: lokasi Compute Engine untuk cluster baru.

API

Untuk membuat cluster baru dengan GKE Dataplane V2, tentukan kolom datapathProvider di objek networkConfig di permintaan create cluster Anda.

Cuplikan JSON berikut menunjukkan konfigurasi yang diperlukan untuk mengaktifkan GKE Dataplane V2:

"cluster":{
   "initialClusterVersion":"VERSION",
   "ipAllocationPolicy":{
      "useIpAliases":true
   },
   "networkConfig":{
      "datapathProvider":"ADVANCED_DATAPATH"
   },
   "releaseChannel":{
      "channel":"CHANNEL_NAME"
   }
}

Ganti kode berikut:

  • VERSION: versi cluster Anda yang harus berupa GKE 1.20.6-gke.700 atau yang lebih baru.
  • CHANNEL_NAME: saluran rilis yang menyertakan GKE versi 1.20.6-gke.700 atau yang lebih baru.

Memecahkan masalah pada GKE Dataplane V2

Bagian ini menunjukkan cara menyelidiki dan menyelesaikan masalah pada GKE Dataplane V2.

  1. Pastikan GKE Dataplane V2 telah diaktifkan:

    kubectl -n kube-system get pods -l k8s-app=cilium -o wide
    

    Jika GKE Dataplane V2 berjalan, output-nya akan menyertakan Pod dengan awalan anetd-. anetd adalah pengontrol jaringan untuk GKE Dataplane V2.

  2. Jika masalah ini terkait dengan penerapan kebijakan jaringan atau layanan, periksa log Pod anetd. Gunakan pemilih log berikut di Cloud Logging:

    resource.type="k8s_container"
    labels."k8s-pod/k8s-app"="cilium"
    resource.labels.cluster_name="CLUSTER_NAME"
    
  3. Jika pembuatan Pod gagal, periksa log kubelet untuk mendapatkan petunjuk. Gunakan pemilih log berikut di Cloud Logging:

    resource.type="k8s_node"
    log_name=~".*/logs/kubelet"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    Ganti CLUSTER_NAME dengan nama cluster, atau hapus seluruhnya untuk melihat log semua cluster.

  4. Jika Pod anetd tidak berjalan, periksa ConfigMap cilium-config untuk mengetahui modifikasi apa pun. Hindari mengubah kolom yang ada dalam ConfigMap ini, karena perubahan tersebut dapat mengganggu stabilitas cluster dan mengganggu anetd. ConfigMap hanya akan di-patch kembali ke status default jika kolom baru ditambahkan ke ConfigMap. Perubahan apa pun pada kolom yang ada tidak akan di-patch kembali, dan sebaiknya jangan ubah atau sesuaikan ConfigMap.

Masalah umum

Saat menggunakan GKE Dataplane V2, Anda mungkin mengalami masalah umum berikut.

Waktu tunggu koneksi habis untuk Pod yang belum siap

Jika Pod belum siap, koneksi ke Layanan terkait dapat mengalami waktu tunggu habis. Ini adalah perilaku yang diharapkan untuk GKE Dataplane V2, dan berbeda dengan kube-proxy, yang dapat menampilkan error connection refused yang lebih cepat.

Pemfilteran Label yang Relevan dengan Identitas untuk Identitas Cilium tidak berlaku dan Pod macet dalam status ContainerCreating

Versi yang terpengaruh: 1.34, 1.35

Di cluster GKE Dataplane V2, penggunaan darurat pemfilteran Label yang Relevan dengan Identitas melalui ConfigMap kube-system/cilium-config-emergency-override tidak diterapkan dengan benar pada versi yang terpengaruh.

Pendekatan ini membatasi label Pod yang digunakan untuk pembuatan Identitas Cilium.

Jika mekanisme lain untuk mencegah/menghapus kunci/nilai label kardinalitas tinggi dari Pod tidak tersedia (seperti saat label diterapkan oleh alat atau framework), pemfilteran Label yang Relevan dengan Identitas dapat digunakan untuk mengecualikan kunci label dari perhitungan Identitas Cilium. Untuk mengetahui informasi selengkapnya tentang cara mengonfigurasi aturan ini, lihat Label yang Relevan dengan Identitas dalam dokumentasi Cilium.

Untuk versi GKE yang terpengaruh, identitas Cilium yang dibuat oleh operator akan terus menyertakan label yang dikecualikan.

Gejala

  • Pod dengan label yang harus difilter untuk pembuatan Identitas Cilium mungkin gagal dimulai dan macet dalam status ContainerCreating. Peristiwa Pod mungkin menampilkan error waktu tunggu habis:

      {"level":"warning", "msg":"Error changing endpoint identity", "error":"unable to resolve identity: timed out waiting for cilium-operator to allocate CiliumIdentity for key ...;, error: exponential backoff cancelled via context: context canceled", "k8sPodName":"...", "subsys":"endpoint"}
    
  • Daripada berbagi identitas berdasarkan label yang difilter, Pod dengan nilai label unik akan terus membuat Identitas Cilium unik. Hal ini dapat menyebabkan peningkatan identitas yang tajam, yang berpotensi menghabiskan Identitas Cilium yang tersedia (hingga batas 65.536) dan menyebabkan masalah skalabilitas.

Solusi

Sebagai solusi, terapkan aturan pemfilteran label ke kolom data.labels di ConfigMap cilium-configutama dan hapus dari cilium-config-emergency-override. Situasi ini akan terus terjadi melalui operasi bidang kontrol, seperti upgrade, karena GKE mempertahankan modifikasi pengguna pada kolom yang tidak dikelolanya dalam ConfigMap cilium-config.

  1. Hapus kunci labels dari bagian data ConfigMap cilium-config-emergency-override jika ada.
  2. Edit ConfigMap cilium-config dengan menambahkan atau mengubah kunci labels di bagian data. Misalnya, untuk mencegah label bernama uuid digunakan untuk pembuatan identitas:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cilium-config
      namespace: kube-system
    data:
      # ... other existing keys
      labels: "!uuid"
      # ... other existing keys
    
  3. Mulai ulang anet-operator di bidang kontrol dengan mengupgrade bidang kontrol ke versi yang sama dengan yang dijalankannya. Tindakan ini akan memaksa operator untuk memulai ulang dan memuat ulang konfigurasinya:

    gcloud container clusters upgrade CLUSTER_NAME \
        --location CLUSTER_LOCATION \
        --project PROJECT_ID \
        --cluster-version $(gcloud container clusters describe CLUSTER_NAME --location CLUSTER_LOCATION --project PROJECT_ID --format="value(currentMasterVersion)") \
        --master
    
  4. Setelah bidang kontrol dimulai ulang, mulai ulang DaemonSet anetd untuk memastikan agen node juga mengambil perubahan yang diperlukan:

    kubectl rollout restart daemonset anetd -n kube-system
    

Masalah konektivitas sesekali terkait konflik rentang NodePort di cluster GKE Dataplane V2

Di cluster GKE Dataplane V2, masalah konektivitas sesekali dapat terjadi untuk traffic yang disamarkan atau dengan penggunaan port sementara. Masalah ini disebabkan oleh potensi konflik port dengan rentang NodePort yang dicadangkan dan biasanya terjadi dalam skenario berikut:

  • Kustom ip-masq-agent: Jika Anda menggunakan ip-masq-agent kustom (versi 2.10 atau yang lebih baru), yang clusternya memiliki NodePort atau Load Balancer layanan, Anda mungkin mengamati masalah konektivitas sesekali karena konflik dengan rentang NodePort. Sejak versi 2.10 dan yang lebih baru, ip-masq-agent memiliki argumen --random-fully yang diterapkan secara internal secara default. Untuk mengatasinya, tetapkan --random-fully=false secara eksplisit (berlaku sejak versi 2.11) di bagian argumen dalam konfigurasi ip-masq-agent Anda. Untuk mengetahui detail konfigurasi, lihat Mengonfigurasi agen penyamaran IP di cluster Standar cluster.

  • Tumpang-tindih rentang port sementara: Jika rentang port sementara yang ditentukan oleh net.ipv4.ip_local_port_range di node GKE Anda tumpang-tindih dengan rentang NodePort (30000-32767), hal ini juga dapat memicu masalah konektivitas. Untuk mencegah masalah ini, pastikan kedua rentang ini tidak tumpang-tindih.

Tinjau konfigurasi ip-masq-agent dan setelan rentang port sementara untuk memastikan keduanya tidak berkonflik dengan rentang NodePort. Jika Anda mengalami masalah konektivitas sesekali, pertimbangkan kemungkinan penyebab ini dan sesuaikan konfigurasi Anda.

Masalah konektivitas dengan hostPort di cluster GKE Dataplane V2

Versi GKE yang terpengaruh: 1.29 dan yang lebih baru

Di cluster yang menggunakan GKE Dataplane V2, Anda mungkin mengalami kegagalan konektivitas saat traffic menargetkan IP:Port node dengan port adalah hostPort yang ditentukan di Pod. Masalah ini muncul dalam dua skenario utama:

  • Node dengan hostPort di belakang Load Balancer Jaringan passthrough:

    hostPort mengikat Pod ke port node tertentu, dan Load Balancer Jaringan passthrough mendistribusikan traffic ke semua node. Saat Anda mengekspos Pod ke internet menggunakan hostPort dan Load Balancer Jaringan passthrough, load balancer mungkin mengirimkan traffic ke node tempat Pod tidak berjalan, sehingga menyebabkan kegagalan koneksi. Hal ini disebabkan oleh batasan umum di GKE Dataplane V2 tempat traffic Load Balancer Jaringan passthrough tidak diteruskan secara konsisten ke Pod hostPort.

    Solusi: Saat mengekspos hostPort Pod di node dengan Load Balancer Jaringan passthrough, tentukan alamat IP internal atau eksternal Load Balancer Jaringan di kolom hostIP Pod.

    ports:
    - containerPort: 62000
      hostPort: 62000
      protocol: TCP
      hostIP: 35.232.62.64
    - containerPort: 60000
      hostPort: 60000
      protocol: TCP
      hostIP: 35.232.62.64
      # Assuming 35.232.62.64 is the external IP address of a passthrough Network Load Balancer.
    
  • KonflikhostPort dengan rentang NodePort yang dicadangkan:

    Jika hostPort Pod berkonflik dengan rentang NodePort yang dicadangkan (30000-32767), Cilium mungkin gagal meneruskan traffic ke Pod. Perilaku ini telah diamati di cluster versi 1.29 dan yang lebih baru karena Cilium kini mengelola kemampuan hostPort, menggantikan metode Portmap sebelumnya. Ini adalah perilaku yang diharapkan untuk Cilium dan disebutkan dalam dokumentasi publiknya.

Kami tidak berencana memperbaiki batasan ini di versi mendatang. Penyebab utama masalah ini terkait dengan perilaku Cilium dan berada di luar kontrol langsung GKE.

Rekomendasi: Sebaiknya migrasikan ke Layanan NodePort, bukan hostPort, untuk meningkatkan keandalan. Layanan NodePort menyediakan kemampuan serupa.

Rentang port Kebijakan Jaringan tidak diterapkan

Jika Anda menentukan kolom endPort di Kebijakan Jaringan di cluster yang telah mengaktifkan GKE Dataplane V2, kolom tersebut tidak akan diterapkan.

Kubernetes Network Policy API memungkinkan Anda menentukan berbagai port tempat Kebijakan Jaringan diterapkan. API ini didukung dalam cluster dengan Kebijakan Jaringan Calico, tetapi tidak didukung di cluster yang menggunakan GKE Dataplane V2.

Anda dapat memverifikasi perilaku objek NetworkPolicy dengan membacanya kembali setelah selesai menulisnya ke server API. Jika objek masih berisi kolom endPort, fitur ini akan diterapkan. Jika kolom endPort tidak ada, fitur tidak akan diterapkan. Untuk semua kasus, objek yang disimpan di server API adalah sumber tepercaya untuk Kebijakan Jaringan.

Untuk mengetahui informasi selengkapnya, lihat KEP-2079: Kebijakan Jaringan untuk mendukung Rentang Port.

Versi tetap

Untuk memperbaiki masalah ini, upgrade cluster Anda ke GKE versi 1.32 atau yang lebih baru

Kebijakan Jaringan memutuskan koneksi karena pencarian pelacakan koneksi salah

Saat Pod klien terhubung ke dirinya sendiri menggunakan Service atau alamat IP virtual dari Load Balancer Jaringan passthrough internal, paket balasan tidak akan diidentifikasi sebagai bagian dari koneksi yang ada karena pencarian koneksi yang salah di dataplane. Ini berarti Kebijakan Jaringan yang membatasi traffic masuk untuk Pod tidak diterapkan dengan benar di paket.

Dampak masalah ini bergantung pada jumlah Pod yang dikonfigurasi untuk Service. Misalnya, jika Service memiliki 1 Pod backend, koneksi akan selalu gagal. Jika Service memiliki 2 Pod backend, koneksi akan gagal 50% dari waktu tersebut.

Versi tetap

Untuk memperbaiki masalah ini, upgrade cluster Anda ke salah satu versi GKE berikut:

  • 1.28.3-gke.1090000 atau yang lebih baru.

Solusi

Anda dapat mengurangi masalah ini dengan mengonfigurasi port dan containerPort di manifes Service ke nilai yang sama.

Penurunan paket untuk alur koneksi hairpin

Saat Pod membuat koneksi TCP ke dirinya sendiri menggunakan Service—Pod tersebut menjadi sumber sekaligus tujuan koneksi—maka pelacakan koneksi eBPF GKE Dataplane V2 akan salah melacak status koneksi sehingga menyebabkan kebocoran entri conntrack.

Jika tuple koneksi (protokol, IP sumber/tujuan, dan port sumber/tujuan) bocor, koneksi baru yang menggunakan tuple koneksi yang sama dapat mengakibatkan paket yang ditampilkan dihapus.

Versi tetap

Untuk memperbaiki masalah ini, upgrade cluster Anda ke salah satu versi GKE berikut:

  • 1.28.3-gke.1090000 atau yang lebih baru
  • 1.27.11-gke.1097000 atau yang lebih baru

Solusi

Gunakan salah satu dari solusi sementara berikut:

  • Mengaktifkan penggunaan ulang TCP (keep-alive) untuk aplikasi yang berjalan di Pod yang dapat berkomunikasi dengan dirinya sendiri melalui Service. Tindakan ini akan mencegah flag TCP FIN dikeluarkan dan menghindari kebocoran entri conntrack.

  • Saat menggunakan koneksi dengan durasi aktif pendek, ekspos Pod akan menggunakan load balancer proxy, seperti Gateway, untuk mengekspos Service. Akibatnya, tujuan permintaan koneksi ditetapkan ke alamat IP load balancer sehingga mencegah GKE Dataplane V2 melakukan SNAT ke alamat IP loopback.

Upgrade bidang kontrol GKE menyebabkan kebuntuan Pod anetd

Saat mengupgrade cluster GKE yang mengaktifkan GKE Dataplane V2 (datapath lanjutan) dari versi 1.27 ke 1.28, Anda mungkin mengalami situasi kebuntuan. Workload mungkin mengalami gangguan karena tidak dapat menghentikan Pod lama atau menjadwalkan komponen yang diperlukan seperti anetd.

Penyebab

Proses upgrade cluster meningkatkan persyaratan resource untuk komponen GKE Dataplane V2. Peningkatan ini dapat menyebabkan pertentangan resource, yang mengganggu komunikasi antara plugin Cilium Container Network Interface (CNI) dan daemon Cilium.

Gejala

Anda mungkin melihat gejala berikut:

  • Pod anetd tetap macet dalam status Pending.
  • Pod workload macet dalam status Terminating.
  • Error yang menunjukkan kegagalan komunikasi Cilium, seperti failed to connect to Cilium daemon.
  • Error selama pembersihan resource jaringan untuk sandbox Pod, misalnya:

    1rpc error: code = Unknown desc = failed to destroy network for sandbox "[sandbox_id]": plugin type="cilium-cni" failed (delete): unable to connect to Cilium daemon... connection refused
    

Solusi

Cluster Standar: Untuk mengatasi masalah ini dan mengizinkan Pod anetd dijadwalkan, tingkatkan sementara resource yang dapat dialokasikan di node yang terpengaruh.

  1. Untuk mengidentifikasi node yang terpengaruh dan memeriksa CPU serta memori yang dapat dialokasikan, jalankan perintah berikut:

    kubectl get nodes $NODE_NAME -o json | jq '.status.allocatable | {cpu, memory}'
    
  2. Untuk meningkatkan sementara CPU dan memori yang dapat dialokasikan, jalankan perintah berikut:

    kubectl patch node $NODE_NAME -p '{"status":{"allocatable":{"cpu":CPU_VALUE, "memory":MEMORY_VALUE}}}'
    

Cluster Autopilot: Untuk mengatasi masalah kebuntuan di cluster Autopilot, kosongkan resource dengan menghapus Pod yang terpengaruh secara paksa:

kubectl delete pod POD_NAME -n NAMESPACE --grace-period=0 --force

Ganti kode berikut:

  • POD_NAME: nama Pod.
  • NAMESPACE: namespace Pod.

Setelah Anda meningkatkan resource yang dapat dialokasikan di node dan saat upgrade dari GKE versi 1.27 ke 1.28 selesai, Pod anetd akan berjalan di versi yang lebih baru.

Node dalam status NodeNotReady karena error containerID tidak ada

Saat cluster diupgrade ke GKE versi 1.35.1-gke.1616000 dan yang lebih baru, node mungkin langsung memasuki status NodeNotReady jika GKE Dataplane V2 dan Cloud Service Mesh diaktifkan.

Penyebab

Mulai GKE versi 1.35.1-gke.1616000, cluster GKE Dataplane V2 menggunakan CNI versi 1.1.0 dalam file konfigurasi CNI-nya. Perubahan ini mengharuskan plugin CNI hilir, seperti Google Managed Istio, juga mendukung CNI versi 1.1.0. Karena penundaan dalam peluncuran Managed Istio, beberapa cluster belum menerima versi yang kompatibel (1.23), sehingga menyebabkan kegagalan inisialisasi.

Gejala

Node yang terpengaruh akan langsung ditampilkan sebagai NodeNotReady. Pesan error berikut muncul di log containerd:

NetworkPluginNotReady message:Network plugin returns error: missing containerID

Solusi

Untuk mengatasi masalah ini, downgrade cluster yang terpengaruh ke GKE versi yang lebih lama dari 1.35.1-gke.1616000.

Gangguan program eBPF kustom

GKE menggunakan program eBPF untuk mengelola jaringan untuk GKE Dataplane V2. Jika Anda men-deploy program eBPF kustom di antarmuka jaringan node yang dikelola GKE, program ini dapat mengganggu program eBPF yang dikelola GKE dan menyebabkan masalah jaringan.

GKE tidak mendukung program eBPF kustom yang terlampir ke antarmuka jaringan berikut:

  • eth*
  • ens4
  • lo
  • cilium*
  • gke*
  • veth*

Keberadaan program eBPF kustom di antarmuka ini dapat mengganggu program yang diinstal agen anetd GKE Dataplane V2, yang dapat mengganggu jaringan cluster. Sebaiknya hapus program eBPF kustom atau workload yang menyuntikkan program tersebut dari cluster Anda.

Menemukan program eBPF kustom

Untuk menemukan program eBPF kustom yang berjalan di node cluster, Anda dapat membuat DaemonSet yang dikonfigurasi dengan setelan hostNetwork: true, yang menggunakan bpftool untuk membuat kueri program eBPF tersebut:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: bpftool-logger
  labels:
    app: bpftool-logger
spec:
  selector:
    matchLabels:
      app: bpftool-logger
  template:
    metadata:
      labels:
        app: bpftool-logger
    spec:
      hostPID: true
      hostNetwork: true
      containers:
      - name: bpftool
        image: ubuntu:22.04
        securityContext:
          privileged: true
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        command:
        - /bin/bash
        - -c
        - |
          echo "Installing dependencies..."
          apt-get update -y > /dev/null 2>&1
          apt-get install -y curl tar > /dev/null 2>&1

          echo "Downloading and setting up bpftool..."
          curl -sL https://github.com/libbpf/bpftool/releases/download/v7.7.0/bpftool-v7.7.0-amd64.tar.gz | tar xz
          chmod +x bpftool
          mv bpftool /usr/local/bin/

          echo "========== $(date) | Node: ${NODE_NAME} =========="
          bpftool net | grep -E '^(eth|ens4|lo|cilium|gke|veth)' | grep -v ' cil_'
          sleep infinity
  1. Simpan manifes sebagai ebpf-discovery.yaml dan terapkan DaemonSet:

    kubectl apply -f ebpf-discovery.yaml
    
  2. Tunggu hingga Pod berjalan:

    kubectl rollout status ds/bpftool-logger
    
  3. Periksa log dari Pod untuk menemukan program eBPF:

    kubectl logs -l app=bpftool-logger
    
  4. Setelah selesai, hapus DaemonSet:

    kubectl delete -f ebpf-discovery.yaml
    

Langkah berikutnya