Menyelesaikan masalah proxy di Cloud Service Mesh

Dokumen ini menjelaskan masalah umum Cloud Service Mesh dan cara mengatasinya. Jika Anda memerlukan bantuan tambahan, lihat Mendapatkan dukungan.

Koneksi Ditolak saat mencapai endpoint dengan Istio

Anda mungkin sesekali mengalami error koneksi ditolak (ECONNREFUSED) untuk berkomunikasi dari cluster Anda ke endpoint, misalnya Memorystore Redis, CloudSQL, atau layanan eksternal apa pun yang diperlukan oleh workload aplikasi Anda jangkauan.

Hal ini dapat terjadi jika beban kerja aplikasi Anda dimulai lebih cepat daripada container istio-proxy (Envoy) dan mencoba menjangkau endpoint eksternal. Karena di tahap ini istio-init (initContainer) sudah dieksekusi, ada aturan iptables yang mengalihkan semua traffic keluar ke Envoy. Sejak istio-proxy belum siap, aturan iptables akan mengalihkan lalu lintas ke {i>sidecar proxy<i} yang belum dimulai dan oleh karena itu, aplikasi mendapatkan ECONNREFUSED error.

Langkah-langkah berikut menjelaskan cara memeriksa apakah ini adalah kesalahan yang Anda mengalami:

  1. Periksa log stackdriver dengan Filter berikut untuk mengidentifikasi pod mana yang bermasalah.

    Contoh berikut menunjukkan pesan error umum:

    Error: failed to create connection to feature-store redis, err=dial tcp   192.168.9.16:19209: connect: connection refused
    [ioredis] Unhandled error event: Error: connect ECONNREFUSED
    
  2. Telusuri kemunculan masalah. Jika Anda menggunakan Stackdriver versi lama, lalu gunakan resource.type="container".

    resource.type="k8s_container"
    textPayload:"$ERROR_MESSAGE$"
    
  3. Luaskan kemunculan terbaru untuk mendapatkan nama pod, lalu catat dari pod_name pada resource.labels.

  4. Dapatkan kemunculan masalah pertama untuk pod tersebut:

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Contoh output:

    E 2020-03-31T10:41:15.552128897Z
    post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
    connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
    connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb
    
  5. Catat stempel waktu error pertama untuk pod ini.

  6. Gunakan filter berikut untuk melihat peristiwa startup pod.

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Contoh output:

    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Container image "docker.io/istio/proxyv2:1.3.3" already present on machine  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Created container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Started container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{APP-CONTAINER-NAME} Created container  spec.containers{APP-CONTAINER-NAME}
    W 2020-03-31T10:41:17Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:26Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:28Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:31Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:58Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    
  7. Gunakan stempel waktu error dan peristiwa startup istio-proxy untuk mengonfirmasi terjadi error saat Envoy belum siap.

    Jika terjadi error saat penampung istio-proxy belum siap, normal untuk memperoleh kesalahan koneksi yang ditolak. Pada contoh sebelumnya, pod mencoba terhubung ke Redis segera setelah 2020-03-31T10:41:15.552128897Z tetapi 2020-03-31T10:41:58Z istio-proxy masih gagal dalam pemeriksaan kesiapan.

    Meskipun kontainer {i>istio-proxy<i} dimulai terlebih dahulu, ada kemungkinan bahwa belum siap cukup cepat sebelum aplikasi mencoba terhubung ke endpoint eksternal.

    Jika ini adalah masalah yang Anda alami, lanjutkan melalui mengikuti langkah-langkah pemecahan masalah.

  8. Anotasikan konfigurasi di level pod. Ini hanya tersedia di pod bukan pada tingkat global.

    annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  9. Mengubah kode aplikasi agar memeriksa apakah Envoy sudah siap sebelumnya mencoba membuat permintaan lain ke layanan eksternal. Misalnya, di aplikasi dijalankan, mulai loop yang membuat permintaan ke istio-proxy kesehatan dan hanya berlanjut setelah nilai 200 diperoleh. Istio-proxy endpoint health adalah sebagai berikut:

    http://localhost:15020/healthz/ready
    

Kondisi balapan selama injeksi file bantuan antara vault dan istio

Saat menggunakan vault untuk pengelolaan secret, terkadang vault memasukkan file bantuan sebelum istio, yang menyebabkan Pod macet dalam status Init. Ketika ini terjadi, Pod yang dibuat macet dalam status Init setelah memulai ulang deployment apa pun atau untuk men-deploy yang baru. Contoh:

E 2020-03-31T10:41:15.552128897Z
post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb

Masalah ini disebabkan oleh kondisi race, baik Istio maupun vault yang memasukkan file bantuan dan Istio harus menjadi yang terakhir melakukan hal ini, proxy istio tidak berjalan selama container init. Penampung init istio menyiapkan aturan iptables untuk mengalihkan semua lalu lintas ke {i>proxy<i}. Karena belum berjalan, aturan-aturan tersebut mengalihkan ke nol, memblokir semua lalu lintas. Inilah sebabnya mengapa container init harus menjadi yang terakhir, sehingga {i>proxy<i} langsung aktif dan berjalan setelah aturan iptables siap. Sayangnya, urutannya tidak determenistik, jadi jika Istio dimasukkan lebih dahulu rusak.

Untuk memecahkan masalah kondisi ini, izinkan alamat IP vault agar traffic membuka IP Vault tidak akan dialihkan ke Envoy Proxy yang belum siap sehingga dapat memblokir komunikasi. Untuk mencapai hal ini, anotasi baru yang bernama excludeOutboundIPRanges harus ditambahkan.

Untuk Cloud Service Mesh terkelola, hal ini hanya dapat dilakukan pada level Pod atau Deployment di bagian spec.template.metadata.annotations, misalnya:

apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
  template:
    metadata:
      annotations:
        traffic.sidecar.istio.io/excludeOutboundIPRanges:

Untuk Cloud Service Mesh dalam cluster, ada opsi untuk menyetelnya sebagai global dengan IstioOperator di bawah spec.values.global.proxy.excludeIPRanges, misalnya:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      proxy:
        excludeIPRanges: ""

Setelah menambahkan anotasi, mulai ulang beban kerja Anda.