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 yang ditolak (ECONNREFUSED) dengan komunikasi dari cluster ke endpoint, misalnya Memorystore Redis, CloudSQL, atau layanan eksternal apa pun yang perlu dijangkau oleh workload aplikasi Anda.

Hal ini dapat terjadi saat workload aplikasi Anda dimulai lebih cepat daripada penampung istio-proxy (Envoy) dan mencoba menjangkau endpoint eksternal. Karena pada tahap ini istio-init (initContainer) telah dijalankan, ada aturan iptables yang mengalihkan semua traffic keluar ke Envoy. Karena istio-proxy belum siap, aturan iptables akan mengalihkan traffic ke proxy file bantuan yang belum dimulai, sehingga aplikasi mendapatkan error ECONNREFUSED.

Langkah-langkah berikut menjelaskan cara memeriksa apakah ini adalah error yang Anda alami:

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

    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, gunakan resource.type="container".

    resource.type="k8s_container"
    textPayload:"$ERROR_MESSAGE$"
    
  3. Luaskan kemunculan terbaru untuk mendapatkan nama pod, lalu catat pod_name di bagian 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 bahwa error terjadi saat Envoy belum siap.

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

    Meskipun container istio-proxy dimulai terlebih dahulu, ada kemungkinan penampung tersebut tidak siap cukup cepat sebelum aplikasi mencoba terhubung ke endpoint eksternal.

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

  8. Anotasikan konfigurasi di level pod. Fitur ini hanya tersedia di level pod, bukan di level global.

    annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  9. Ubah kode aplikasi agar memeriksa apakah Envoy sudah siap sebelum mencoba membuat permintaan lain ke layanan eksternal. Misalnya, saat aplikasi dimulai, mulai loop yang membuat permintaan ke endpoint kesehatan istio-proxy dan hanya berlanjut setelah angka 200 diperoleh. Endpoint kesehatan istio-proxy 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. Jika hal ini terjadi, Pod yang dibuat akan berhenti di status Init setelah memulai ulang deployment apa pun atau 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. Istio dan vault yang memasukkan file bantuan maupun Istio harus menjadi yang terakhir melakukan hal ini, proxy istio tidak berjalan selama penampung init. Penampung init istio menyiapkan aturan iptables untuk mengalihkan semua traffic ke proxy. Karena belum berjalan, aturan tersebut tidak melakukan pengalihan, sehingga memblokir semua traffic. Inilah alasan mengapa container init harus menjadi yang terakhir, sehingga proxy aktif dan berjalan segera setelah aturan iptables disiapkan. Sayangnya, urutannya tidak determenistik, jadi jika Istio diinjeksikan terlebih dahulu, urutannya akan rusak.

Untuk memecahkan masalah kondisi ini, izinkan alamat IP vault agar traffic yang menuju ke IP Vault tidak dialihkan ke Envoy Proxy yang belum siap dan, oleh karena itu, memblokir komunikasi. Untuk mencapai hal ini, anotasi baru bernama excludeOutboundIPRanges harus ditambahkan.

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

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

Untuk Mesh Layanan Cloud dalam cluster, ada opsi untuk menetapkannya sebagai Cloud Service Mesh global dengan IstioOperator di bagian 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.