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 terkait pengambilan gambar paket jaringan, termasuk gejala seperti waktu tunggu koneksi habis, koneksi ditolak error, atau perilaku aplikasi yang tidak terduga. Masalah konektivitas ini dapat terjadi di level node atau level Pod.

Masalah konektivitas di jaringan cluster Anda sering kali sebagai berikut kategori:

  • 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 pengiriman.
  • 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, yaitu:

  • Kesalahan konfigurasi jaringan: Kebijakan jaringan, aturan firewall, atau tabel {i>routing<i}.
  • Bug aplikasi: Error dalam kode aplikasi yang memengaruhi jaringan interaksi.
  • Masalah infrastruktur: Kemacetan jaringan, kegagalan hardware, atau keterbatasan resource.

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

  1. Identifikasi node tempat Pod yang bermasalah berjalan dengan 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 dalam container di Node GKE untuk proses debug dan pemecahan masalah. 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 perintah 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-nya 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 spesifik dari paket tcpdump dan libpcap.
  3. Mulai penangkapan 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.
  4. Hentikan penangkapan paket dan interupsi tcpdump.

  5. Keluar dari toolbox dengan mengetikkan exit.

  6. Tampilkan daftar file tangkapan paket dan periksa ukurannya:

    ls -ltr /mnt/stateful_partition/CAPTURE_FILE_NAME
    
  7. Salin tangkapan 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.
    • ZONE: nama zona Anda.

Perintah alternatif

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

  • Workload debug ephemeral yang ditambahkan ke container Pod.

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

Masalah konektivitas jaringan pod

Sebagaimana disebutkan dalam Ringkasan Jaringan diskusi ini, penting untuk memahami bagaimana Pod terhubung dari namespace jaringan ke namespace root pada node untuk 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 pada node tertentu tidak memiliki ketersediaan

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 (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 iptable. 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 ke 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 berjalan tertinggal dan basi. Proses 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 sedang 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 akan memiliki docker-containerd-shim memproses yang memiliki ID penampung dalam argumen juga. 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 dijeda
    • docker-containerd-shim ab4c7762f5abf40951770 untuk sh dengan penundaan (sleep-ctr)
    • docker-containerd-shim 44e76e50e5ef4156fd5d3 untuk nginx (echoserver-ctr)
  5. Periksa yang ada 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 harus menautkan jaringan namespace dari proses secara manual, karena Docker tidak melakukan link:

    # 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 mendahului, dan mengakhiri proses menggunakan perintah kill [PID].

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

  • Proses Zombie menumpuk, jadi kehabisan namespace PID
  • Bug di Docker
  • Tekanan resource / OOM

Langkah selanjutnya