Men-deploy Gateway multi-cluster untuk pembagian traffic berbobot

Dokumen ini memandu Anda melakukan deployment blue-green aplikasi contoh store di dua cluster GKE. Deployment blue-green adalah strategi yang efektif untuk memigrasikan aplikasi Anda ke cluster GKE baru dengan risiko minimal. Dengan mengalihkan traffic secara bertahap dari cluster saat ini (blue) ke cluster baru (green), Anda dapat memvalidasi lingkungan baru dalam produksi sebelum melakukan peralihan penuh.

Gateway multi-cluster menyediakan cara yang efektif untuk mengelola traffic layanan yang di-deploy di beberapa cluster GKE. Dengan menggunakan infrastruktur penyeimbangan beban global Google, Anda dapat membuat satu titik entri untuk aplikasi Anda, yang menyederhanakan pengelolaan dan meningkatkan keandalan.

Dalam tutorial ini, Anda akan menggunakan aplikasi store contoh untuk mensimulasikan skenario dunia nyata dengan layanan belanja online dimiliki dan dioperasikan oleh tim terpisah serta di-deploy di seluruh fleet cluster GKE bersama.

Sebelum memulai

Gateway Multi-cluster memerlukan beberapa persiapan lingkungan sebelum dapat di-deploy. Sebelum melanjutkan, ikuti langkah-langkah di bagian Menyiapkan lingkungan untuk Gateway multi-cluster:

  1. Deploy cluster GKE

  2. Daftarkan cluster Anda ke fleet (jika belum terdaftar).

  3. Aktifkan Service multi-cluster dan pengontrol Gateway multi-cluster.

Terakhir, tinjau batasan dan masalah umum GKE Gateway Controller sebelum Anda menggunakan controller di lingkungan Anda.

Pemilihan rute multi-cluster blue-green dengan Gateway

GatewayClass gke-l7-global-external-managed-*, gke-l7-regional-external-managed-*, dan gke-l7-rilb-* memiliki banyak kemampuan pemilihan rute traffic lanjutan, seperti pemisahan traffic, pencocokan header, manipulasi header, duplikasi traffic, dan sebagainya. Dalam contoh ini, Anda akan menunjukkan cara menggunakan pemisahan traffic berbasis bobot untuk mengontrol proporsi traffic di dua cluster GKE secara eksplisit.

Contoh ini memberikan beberapa langkah realistis yang harus diambil pemilik layanan agar dapat memindahkan atau memperluas aplikasi mereka ke cluster GKE baru. Tujuan blue-green deployment adalah untuk mengurangi risiko melalui beberapa langkah validasi yang mengonfirmasi bahwa cluster baru beroperasi dengan benar. Contoh ini memuat empat tahap deployment:

  1. 100%-Canary berbasis header: Gunakan pemilihan rute header HTTP untuk hanya mengirim traffic pengujian atau sintetis ke cluster baru.
  2. 100%-Menduplikasi traffic: Menduplikasi traffic pengguna ke cluster canary. Tahap ini akan menguji kapasitas cluster canary dengan menyalin 100% traffic pengguna ke cluster ini.
  3. 90%-10%: Pemisahan traffic Canary sebesar 10% untuk perlahan-lahan mengekspos cluster baru ke traffic langsung.
  4. 0%-100%: Migrasi sistem sepenuhnya ke cluster baru dengan opsi untuk beralih kembali jika setiap error teramati.

Pemisahan traffic blue-green di dua cluster GKE

Contoh ini mirip dengan contoh sebelumnya, tetapi contoh ini men-deploy Gateway multi-cluster internal. Tindakan ini akan men-deploy Load Balancer Aplikasi internal yang hanya dapat diakses secara pribadi dari dalam VPC. Anda akan menggunakan cluster dan juga aplikasi yang sama seperti yang di-deploy di langkah sebelumnya, kecuali jika Anda men-deploy-nya melalui Gateway yang berbeda.

Prasyarat

Contoh berikut dibuat berdasarkan beberapa langkah dalam Men-deploy Gateway multi-cluster eksternal. Pastikan Anda telah melakukan langkah-langkah berikut sebelum melanjutkan contoh ini:

  1. Menyiapkan lingkungan untuk Gateway multi-cluster

  2. Men-deploy aplikasi demo

    Contoh ini menggunakan cluster gke-west-1 dan gke-west-2 yang sudah Anda siapkan. Cluster ini berada di region yang sama karena GatewayClass gke-l7-rilb-mc bersifat regional dan hanya mendukung backend cluster di region yang sama.

  3. Deploy Service dan ServiceExport yang diperlukan di setiap cluster. Jika Anda men-deploy Service dan ServiceExport dari contoh sebelumnya, berarti Anda sudah men-deploy beberapa dari resource ini.

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
    

    Contoh ini men-deploy serangkaian resource yang serupa ke setiap cluster:

    service/store created
    serviceexport.net.gke.io/store created
    service/store-west-2 created
    serviceexport.net.gke.io/store-west-2 created
    

Mengonfigurasi subnet khusus proxy

Jika Anda belum melakukannya, konfigurasi subnet khusus proxy untuk setiap region tempat Anda men-deploy Gateway internal. Subnet ini digunakan untuk menyediakan alamat IP internal ke proxy load balancer dan harus dikonfigurasi dengan --purpose yang ditetapkan ke REGIONAL_MANAGED_PROXY saja.

Anda harus membuat subnet khusus proxy sebelum membuat Gateway yang mengelola Load Balancer Aplikasi internal. Setiap region jaringan Virtual Private Cloud (VPC) tempat Anda menggunakan Load Balancer Aplikasi internal harus memiliki subnet khusus proxy.

Perintah gcloud compute networks subnets create membuat subnet khusus proxy.

gcloud compute networks subnets create SUBNET_NAME \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=REGION \
    --network=VPC_NETWORK_NAME \
    --range=CIDR_RANGE

Ganti kode berikut:

  • SUBNET_NAME: nama subnet khusus proxy.
  • REGION: region subnet khusus proxy.
  • VPC_NETWORK_NAME: nama jaringan VPC yang berisi subnet.
  • CIDR_RANGE: rentang alamat IP utama subnet. Anda harus menggunakan subnet mask dengan ukuran maksimal /26 agar ada minimal 64 alamat IP yang tersedia untuk proxy di region tersebut. Subnet mask yang direkomendasikan adalah /23.

Men-deploy Gateway

Gateway berikut dibuat dari GatewayClass gke-l7-rilb-mc, yang merupakan Gateway internal regional yang hanya dapat menargetkan cluster GKE di region yang sama.

  1. Terapkan manifes Gateway berikut ke cluster konfigurasi, gke-west-1 dalam contoh ini:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-rilb-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    
  2. Validasi bahwa Gateway berhasil muncul. Anda dapat memfilter hanya peristiwa dari Gateway ini dengan perintah berikut:

    kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
    

    Deployment Gateway berhasil jika output-nya terlihat seperti berikut:

    LAST SEEN   TYPE     REASON   OBJECT                  MESSAGE
    5m18s       Normal   ADD      gateway/internal-http   store/internal-http
    3m44s       Normal   UPDATE   gateway/internal-http   store/internal-http
    3m9s        Normal   SYNC     gateway/internal-http   SYNC on store/internal-http was a success
    

Canary berbasis header

Canary berbasis header memungkinkan pemilik layanan mencocokkan traffic pengujian sintetis yang tidak berasal dari pengguna sebenarnya. Ini adalah cara mudah untuk memvalidasi bahwa jaringan dasar aplikasi berfungsi tanpa mengekspos pengguna secara langsung.

  1. Terapkan manifes HTTPRoute berikut ke cluster konfigurasi, gke-west-1 dalam contoh ini:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Matches for env=canary and sends it to store-west-2 ServiceImport
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-west-2
            port: 8080
      # All other traffic goes to store-west-1 ServiceImport
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
    EOF
    

    Setelah di-deploy, HTTPRoute ini akan mengonfigurasi perilaku perutean berikut:

    • Permintaan internal ke store.example.internal tanpa header HTTP env: canary dirutekan ke Pod store di cluster gke-west-1
    • Permintaan internal ke store.example.internal dengan header HTTP env: canary dirutekan ke Pod store di cluster gke-west-2

    Dengan HTTPRoute, pemilihan rute ke berbagai cluster dapat dilakukan berdasarkan header HTTP

    Validasi bahwa HTTPRoute berfungsi baik dengan mengirimkan traffic ke alamat IP Gateway.

  2. Ambil alamat IP internal dari internal-http.

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    Ganti VIP di langkah berikut dengan alamat IP yang Anda terima sebagai output.

  3. Kirim permintaan ke Gateway menggunakan header HTTP env: canary. Tindakan ini akan mengonfirmasi bahwa traffic dirutekan ke gke-west-2. Gunakan klien pribadi di VPC yang sama dengan cluster GKE untuk mengonfirmasi bahwa permintaan dirutekan dengan benar. Perintah berikut harus dijalankan di komputer yang memiliki akses pribadi ke alamat IP Gateway. Jika tidak, perintah tersebut tidak akan berfungsi.

    curl -H "host: store.example.internal" -H "env: canary" http://VIP
    

    Output tersebut mengonfirmasi bahwa permintaan dilayani oleh Pod dari cluster gke-west-2:

    {
        "cluster_name": "gke-west-2", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-9kdb5",
        "pod_name_emoji": "😂",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:21:55",
        "zone": "us-west1-a"
    }
    

Duplikasi traffic

Tahap ini tidak hanya mengirimkan traffic ke cluster yang diinginkan, tetapi juga menduplikasi traffic tersebut ke cluster canary.

Penggunaan duplikasi akan berguna dalam menentukan pengaruh beban traffic terhadap performa aplikasi tanpa memengaruhi respons terhadap klien Anda dengan cara apa pun. Tindakan ini mungkin tidak diperlukan untuk semua jenis peluncuran, tetapi dapat berguna saat meluncurkan perubahan besar yang dapat memengaruhi performa atau beban.

  1. Terapkan manifes HTTPRoute berikut ke cluster konfigurasi, gke-west-1 dalam contoh ini:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Sends all traffic to store-west-1 ServiceImport
      - backendRefs:
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
        # Also mirrors all traffic to store-west-2 ServiceImport
        filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              group: net.gke.io
              kind: ServiceImport
              name: store-west-2
              port: 8080
    EOF
    
  2. Dengan menggunakan klien pribadi Anda, kirim permintaan ke Gateway internal-http. Gunakan jalur /mirror agar Anda dapat mengidentifikasi permintaan ini secara unik di log aplikasi pada langkah berikutnya.

    curl -H "host: store.example.internal" http://VIP/mirror
    
  3. Output mengonfirmasi bahwa klien menerima respons dari Pod di cluster gke-west-1:

    {
        "cluster_name": "gke-west-1", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-brg5w",
        "pod_name_emoji": "🎖",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:24:51",
        "zone": "us-west1-a"
    }
    

    Tindakan ini memastikan bahwa cluster utama merespons traffic. Anda tetap harus mengonfirmasi bahwa cluster tempat Anda bermigrasi menerima traffic yang diduplikasi.

  4. Periksa log aplikasi untuk Pod store di cluster gke-west-2. Log akan mengonfirmasi bahwa Pod menerima traffic yang diduplikasi dari load balancer.

    kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
    
  5. Output ini mengonfirmasi bahwa Pod di cluster gke-west-2 juga menerima permintaan yang sama, tetapi responsnya terhadap permintaan tersebut tidak dikirim kembali kepada klien. Alamat IP yang terlihat di log adalah alamat IP internal load balancer yang berkomunikasi dengan Pod Anda.

    Found 2 pods, using pod/store-5c65bdf74f-vpqbs
    [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    

Pembagian traffic

Pemisahan traffic adalah salah satu metode paling umum untuk meluncurkan kode baru atau men-deploy ke lingkungan baru dengan aman. Pemilik layanan menetapkan persentase eksplisit traffic yang dikirim ke backend canary, dan ini biasanya merupakan jumlah yang sangat kecil dari keseluruhan traffic, sehingga keberhasilan peluncuran dapat ditentukan dari jumlah risiko yang dapat diterima terhadap permintaan pengguna yang sebenarnya.

Denagn melakukan pemisahan traffic dengan sebagian kecil traffic, pemilik layanan dapat memeriksa kondisi aplikasi beserta responsnya. Jika semua sinyal terlihat baik-baik saja, sinyal tersebut dapat diproses sepenuhnya.

  1. Terapkan manifes HTTPRoute berikut ke cluster konfigurasi, gke-west-1 dalam contoh ini:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      - backendRefs:
        # 90% of traffic to store-west-1 ServiceImport
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 90
        # 10% of traffic to store-west-2 ServiceImport
        - name: store-west-2
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 10
    EOF
    
  2. Dengan menggunakan klien pribadi Anda, kirim permintaan curl berkelanjutan ke Gateway internal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    Output akan serupa dengan ini, yang menunjukkan bahwa pemisahan traffic 90/10 sedang berlangsung.

    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    ...
    

Migrasi sistem traffic

Tahap terakhir dari migrasi blue-green adalah menutup sempurna cluster dan menghapus cluster lama. Jika pemilik layanan benar-benar melakukan orientasi cluster kedua ke cluster yang sudah ada, langkah terakhir ini akan berbeda karena langkah terakhir merupakan traffic yang mengarah ke kedua cluster tersebut. Dalam skenario tersebut, satu ServiceImport store direkomendasikan, yaitu yang memiliki Pod dari cluster gke-west-1 dan gke-west-2. Dengan cara ini, load balancer dapat membuat keputusan terkait arah tujuan traffic untuk aplikasi aktif-aktif, berdasarkan kedekatan, kondisi, dan kapasitas.

  1. Terapkan manifes HTTPRoute berikut ke cluster konfigurasi, gke-west-1 dalam contoh ini:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
        - backendRefs:
          # No traffic to the store-west-1 ServiceImport
          - name: store-west-1
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 0
          # All traffic to the store-west-2 ServiceImport
          - name: store-west-2
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 100
    EOF
    
  2. Dengan menggunakan klien pribadi Anda, kirim permintaan curl berkelanjutan ke Gateway internal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    Output akan serupa dengan ini, yang menunjukkan bahwa semua traffic kini akan mengarah ke gke-west-2.

    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    ...
    

Langkah terakhir ini menyelesaikan migrasi lengkap aplikasi blue-green dari satu cluster GKE ke cluster GKE lainnya.

Pembersihan

Setelah menyelesaikan latihan dalam dokumen ini, ikuti langkah-langkah berikut untuk menghapus resource dan mencegah timbulnya biaya yang tidak diinginkan pada akun Anda:

  1. Hapus cluster.

  2. Batalkan pendaftaran cluster dari fleet jika tidak perlu didaftarkan untuk tujuan lain.

  3. Nonaktifkan fitur multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. Nonaktifkan Multi Cluster Ingress:

    gcloud container fleet ingress disable
    
  5. Nonaktifkan API:

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

Pemecahan masalah

Tidak ada upstream yang sehat

Gejala:

Masalah berikut dapat terjadi saat Anda membuat Gateway, tetapi tidak dapat mengakses layanan backend (kode respons 503):

no healthy upstream

Alasan:

Pesan error ini menunjukkan bahwa pemeriksa health check tidak dapat menemukan layanan backend yang sehat. Mungkin saja layanan backend Anda dalam kondisi baik, tetapi Anda mungkin perlu menyesuaikan health check.

Solusi:

Untuk mengatasi masalah ini, sesuaikan health check Anda berdasarkan persyaratan aplikasi Anda (misalnya, /health) menggunakan HealthCheckPolicy.

Langkah berikutnya