Memecahkan masalah konektivitas di cluster Anda


Halaman ini menunjukkan cara menyelesaikan masalah konektivitas di cluster Anda.

Masalah konektivitas terkait pengambilan paket jaringan di GKE

Bagian ini menjelaskan cara memecahkan masalah konektivitas yang terkait dengan pengambilan paket jaringan, termasuk gejala seperti waktu tunggu koneksi habis, error koneksi menolak, atau perilaku aplikasi yang tidak terduga. Masalah konektivitas ini dapat terjadi di tingkat node atau di tingkat Pod.

Masalah konektivitas di jaringan cluster Anda sering kali berada dalam kategori berikut:

  • Pod tidak dapat dijangkau: Pod mungkin tidak dapat diakses dari dalam atau luar cluster karena kesalahan konfigurasi jaringan.
  • Gangguan layanan: Layanan mungkin mengalami gangguan atau keterlambatan.
  • Masalah komunikasi antar-Pod: Pod mungkin tidak dapat berkomunikasi satu sama lain secara efektif.

Masalah konektivitas di cluster GKE Anda dapat berasal dari berbagai penyebab, termasuk hal berikut:

  • Kesalahan konfigurasi jaringan: Kebijakan jaringan, aturan firewall, atau tabel pemilihan rute yang salah.
  • Bug aplikasi: Error dalam kode aplikasi yang memengaruhi interaksi jaringan.
  • Masalah infrastruktur: Kepadatan jaringan, kegagalan hardware, atau batasan resource.

Bagian berikut menunjukkan cara menyelesaikan masalah pada node atau Pod yang bermasalah.

  1. Identifikasi node tempat Pod bermasalah berjalan menggunakan perintah berikut:

    kubectl get pods POD_NAME -o=wide -n NAMESPACE
    

    Ganti kode berikut:

    • POD_NAME dengan nama Pod.
    • NAMESPACE dengan namespace Kubernetes.
  2. Hubungkan ke node:

    gcloud compute ssh NODE_NAME \
        --zone=ZONE
    

    Ganti kode berikut:

    • NODE_NAME: nama node Anda.
    • ZONE: nama zona tempat node berjalan.
  3. Untuk men-debug Pod tertentu, identifikasi antarmuka veth yang terkait dengan Pod:

    ip route | grep POD_IP
    

    Ganti POD_IP dengan alamat IP Pod.

  4. Jalankan perintah toolbox.

Perintah toolbox

toolbox adalah utilitas yang menyediakan lingkungan container dalam node GKE Anda untuk proses debug dan pemecahan masalah. Bagian ini menjelaskan cara menginstal utilitas toolbox dan menggunakannya untuk memecahkan masalah node.

  1. Saat terhubung ke node, mulai alat toolbox:

    toolbox
    

    Tindakan ini akan mendownload file yang memfasilitasi utilitas toolbox.

  2. Di prompt root toolbox, instal tcpdump:

    • Untuk cluster dengan alamat IP eksternal atau Cloud NAT:

      apt update -y && apt install -y tcpdump
      
    • Untuk cluster pribadi tanpa Cloud NAT:

      Jika memiliki cluster pribadi tanpa Cloud NAT, Anda tidak dapat menginstal tcpdump menggunakan apt. Sebagai gantinya, download file rilis libpcap dan tcpdump dari repositori resmi dan salin file ke VM menggunakan gcloud compute scp atau gsutil. Kemudian, instal library secara manual menggunakan langkah-langkah berikut:

      cp /media/root/home/USER_NAME/tcpdump-VERSION.tar.gz  /usr/sbin/
      cp /media/root/home/USER_NAME/libpcap-VERSION.tar.gz  /usr/sbin/
      cd /usr/sbin/
      tar -xvzf tcpdump-VERSION.tar.gz
      tar -xvzf libpcap-VERSION.tar.gz
      cd libpcap-VERSION
      ./configure ; make ; make install
      cd ../tcpdump-VERSION
      ./configure ; make ; make install
      tcpdump --version
      

      Ganti kode berikut:

      • USER_NAME: Nama pengguna Anda di sistem tempat file berada.
      • VERSION: Nomor versi tertentu dari paket tcpdump dan libpcap.
  3. Mulai perekaman paket:

    tcpdump -i eth0 -s 100 "port PORT" \
    -w /media/root/mnt/stateful_partition/CAPTURE_FILE_NAME
    

    Ganti kode berikut:

    • PORT: nama nomor port Anda.
    • CAPTURE_FILE_NAME: nama file rekaman Anda.
  4. Hentikan penangkapan paket dan interupsi tcpdump.

  5. Keluar dari toolbox dengan mengetik exit.

  6. Cantumkan file rekaman aktivitas paket dan periksa ukurannya:

    ls -ltr /mnt/stateful_partition/CAPTURE_FILE_NAME
    
  7. Salin rekaman aktivitas paket dari node ke direktori kerja saat ini di komputer Anda:

    gcloud compute scp NODE_NAME:/mnt/stateful_partition/CAPTURE_FILE_NAME \
        --zone=ZONE
    

    Ganti kode berikut:

    • NODE_NAME: nama node Anda.
    • CAPTURE_FILE_NAME: nama file rekaman Anda.
    • ZONE: nama zona Anda.

Perintah alternatif

Anda juga dapat menggunakan cara berikut untuk memecahkan masalah konektivitas pada Pod yang bermasalah:

  • Workload debug efemeral yang dilampirkan ke penampung Pod.

  • Jalankan shell langsung di Pod target menggunakan kubectl exec, lalu instal dan luncurkan perintah tcpdump.

Masalah konektivitas jaringan pod

Seperti yang telah disebutkan dalam diskusi Ringkasan Jaringan, penting untuk memahami cara Pod terhubung dari namespace jaringannya ke namespace root di node agar dapat memecahkan masalah secara efektif. Untuk diskusi berikut, kecuali jika dinyatakan lain, asumsikan bahwa cluster menggunakan CNI native GKE, bukan Calico. Artinya, tidak ada kebijakan jaringan yang telah diterapkan.

Pod di node tertentu tidak tersedia

Jika Pod pada node tertentu tidak memiliki konektivitas jaringan, pastikan bridge Linux sudah aktif:

ip address show cbr0

Jika bridge Linux nonaktif, aktifkan bridge tersebut:

sudo ip link set cbr0 up

Pastikan node tersebut mempelajari alamat MAC Pod yang dilampirkan ke cbr0:

arp -an

Pod pada node tertentu memiliki konektivitas minimal

Jika Pod pada node tertentu memiliki konektivitas minimal, Anda harus mengonfirmasi terlebih dahulu apakah ada paket yang hilang dengan menjalankan tcpdump dalam container toolbox:

sudo toolbox bash

Instal tcpdump di toolbox jika Anda belum melakukannya:

apt install -y tcpdump

Jalankan tcpdump pada cbr0:

tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]

Jika terlihat bahwa paket besar hilang setelah melewati bridge (misalnya, handshake TCP selesai, tetapi tidak ada pesan SSL yang diterima), pastikan MTU untuk setiap antarmuka Linux Pod ditetapkan dengan benar ke MTU jaringan VPC cluster.

ip address show cbr0

Saat overlay digunakan (misalnya, Weave atau Flannel), MTU ini harus dikurangi lebih lanjut untuk mengakomodasi overhead enkapsulasi pada overlay.

MTU GKE

MTU yang dipilih untuk antarmuka Pod bergantung pada Antarmuka Jaringan Container (Container Network Interface/CNI) yang digunakan oleh Node cluster dan setelan MTU VPC yang mendasarinya. Untuk mengetahui informasi selengkapnya, lihat Pod.

Nilai MTU antarmuka Pod adalah 1460 atau diwarisi dari antarmuka utama Node.

CNI MTU GKE Standard
kubenet 1460 Default
kubenet
(GKE versi 1.26.1 dan yang lebih baru)
Diwarisi Default
Calico 1460

Diaktifkan menggunakan --enable-network-policy.

Untuk mengetahui detailnya, silakan melihat Mengontrol komunikasi antara Pod dan Layanan menggunakan kebijakan jaringan.

netd Diwarisi Diaktifkan menggunakan salah satu opsi berikut:
GKE Dataplane V2 Diwarisi

Diaktifkan menggunakan --enable-dataplane-v2.

Untuk mengetahui detailnya, silakan melihat Menggunakan GKE Dataplane V2.

Koneksi gagal secara berkala

Koneksi ke dan dari Pod diteruskan oleh iptables. Alur dilacak sebagai entri dalam tabel pelacakan koneksi dan, jika ada banyak workload per node, habisnya tabel pelacakan koneksi dapat menghasilkan kegagalan. Hal ini dapat dicatat ke dalam log di konsol serial node, misalnya:

nf_conntrack: table full, dropping packet

Jika Anda dapat menentukan bahwa masalah yang terjadi secara berkala disebabkan oleh habisnya pelacakan koneksi, Anda dapat meningkatkan ukuran cluster (sehingga mengurangi jumlah workload dan alur per node), atau meningkatkan nf_conntrack_max:

new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
  && echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf

Anda juga dapat menggunakan NodeLocal DNSCache untuk mengurangi entri pelacakan koneksi.

"bind: Alamat sudah digunakan " dilaporkan untuk penampung

Container dalam Pod tidak dapat dimulai karena menurut log container, port tempat aplikasi akan di-bind sudah dicadangkan. Container mengalami loop error. Misalnya, di Cloud Logging:

resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"

2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use

Saat Docker mengalami error, terkadang container yang sedang berjalan tertinggal dan tidak berlaku lagi. Proses ini masih berjalan di namespace jaringan yang dialokasikan untuk Pod, dan memproses port-nya. Karena Docker dan kubelet tidak tahu tentang container yang sudah tidak berlaku tersebut, keduanya mencoba memulai container baru dengan proses baru, yang tidak dapat melakukan binding port saat sudah ditambahkan ke namespace jaringan yang terkait dengan Pod.

Untuk mendiagnosis masalah ini:

  1. Anda memerlukan UUID Pod di kolom .metadata.uuid:

    kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg
    
    name                      UUID
    ubuntu-6948dd5657-4gsgg   db9ed086-edba-11e8-bdd6-42010a800164
    
  2. Dapatkan output perintah berikut dari node:

    docker ps -a
    ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]
    
  3. Periksa proses yang berjalan dari Pod ini. Karena UUID namespace cgroup berisi UUID Pod, Anda dapat melakukan grep untuk UUID Pod dalam output ps. Grep juga baris sebelumnya, sehingga Anda memiliki proses docker-containerd-shim serta memiliki ID container dalam argumen. Potong sisa kolom cgroup untuk mendapatkan output yang lebih sederhana:

    # ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/
    1283089     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim 276e173b0846e24b704d4 12:
    1283107 1283089 Ss   sys_pause            4026532393         pause           /pause                                     12:
    1283150     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim ab4c7762f5abf40951770 12:
    1283169 1283150 Ss   do_wait              4026532393         sh              /bin/sh -c echo hello && sleep 6000000     12:
    1283185 1283169 S    hrtimer_nanosleep    4026532393           sleep           sleep 6000000                            12:
    1283244     959 Sl   futex_wait_queue_me  4026531993       docker-co       docker-containerd-shim 44e76e50e5ef4156fd5d3 12:
    1283263 1283244 Ss   sigsuspend           4026532393         nginx           nginx: master process nginx -g daemon off; 12:
    1283282 1283263 S    ep_poll              4026532393           nginx           nginx: worker process
    
  4. Dari daftar ini, Anda dapat melihat ID container, yang juga akan terlihat di docker ps.

    Dalam kasus ini:

    • docker-containerd-shim 276e173b0846e24b704d4 untuk jeda
    • docker-containerd-shim ab4c7762f5abf40951770 untuk sh dengan penundaan (sleep-ctr)
    • docker-containerd-shim 44e76e50e5ef4156fd5d3 untuk nginx (echoserver-ctr)
  5. Periksa di output docker ps:

    # docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3'
    44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f   gcr.io/google_containers/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc                   "nginx -g 'daemon off;'"                                                                                                                                                                                                                                                                                                                                                                     14 hours ago        Up 14 hours                             k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0
    ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475   ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78                                                "/bin/sh -c 'echo hello && sleep 6000000'"                                                                                                                                                                                                                                                                                                                                                   14 hours ago        Up 14 hours                             k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0
    276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327   registry.k8s.io/pause-amd64:3.1
    

    Umumnya Anda akan melihat semua ID container dari ps muncul dalam docker ps. Jika ada yang tidak Anda lihat, ini adalah container yang sudah tidak berlaku, dan mungkin Anda akan melihat proses turunan dari docker-containerd-shim process, yang diproses pada port TCP, yang dilaporkan sebagai sudah digunakan.

    Untuk memastikannya, jalankan netstat di namespace jaringan container. Dapatkan pid dari semua proses container (jadi BUKAN docker-containerd-shim) untuk Pod.

    Dari contoh sebelumnya:

    • 1283107 - jeda
    • 1283169 - sh
    • 1283185 - penundaan
    • 1283263 - master nginx
    • 1283282 - worker nginx
    # nsenter -t 1283107 --net netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    

    Anda juga dapat menjalankan netstat menggunakan ip netns, tetapi Anda perlu menautkan namespace jaringan proses secara manual, karena Docker tidak melakukan penautan:

    # ln -s /proc/1283169/ns/net /var/run/netns/1283169
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list
    1283169 (id: 2)
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1283263/nginx: mast
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
    unix  3      [ ]         STREAM     CONNECTED     3097406  1283263/nginx: mast
    unix  3      [ ]         STREAM     CONNECTED     3097405  1283263/nginx: mast
    gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
    

Mitigasi:

Mitigasi jangka pendek adalah mengidentifikasi proses yang sudah tidak berlaku dengan metode yang diuraikan sebelumnya, dan mengakhiri proses menggunakan perintah kill [PID].

Mitigasi jangka panjang melibatkan identifikasi penyebab Docker mengalami error dan memperbaikinya. Kemungkinan alasannya mencakup:

  • Proses zombie menumpuk, sehingga kehabisan namespace PID
  • Bug di docker
  • Tekanan resource / OOM

Langkah selanjutnya