Menyiapkan mesh multi-cluster pada Cloud Service Mesh terkelola

Panduan ini menjelaskan cara menggabungkan dua cluster menjadi satu Cloud Service Mesh menggunakan Mesh CA atau {i>Certificate Authority Service<i} dan mengaktifkan load balancing lintas cluster. Anda dapat dengan mudah memperluas proses ini untuk menggabungkan sejumlah klaster ke dalam {i>mesh<i} Anda.

Konfigurasi Cloud Service Mesh multi-cluster dapat menyelesaikan berbagai masalah yang berbeda, seperti skala, lokasi, dan isolasi. Untuk informasi selengkapnya, lihat Kasus penggunaan multi-cluster.

Prasyarat

Panduan ini mengasumsikan bahwa Anda memiliki dua atau lebih Google Cloud Cluster GKE yang memenuhi persyaratan berikut:

  • Cloud Service Mesh yang diinstal pada cluster. Anda perlu asmcli, alat istioctl, dan contoh yang didownload asmcli ke yang Anda tentukan di --output_dir.
  • Cluster di mesh harus memiliki konektivitas antara semua pod sebelum Anda dan mengonfigurasi Cloud Service Mesh. Selain itu, jika Anda bergabung dengan cluster yang tidak dalam proyek yang sama, mereka harus didaftarkan ke project host perangkat, dan cluster harus berada dalam konfigurasi VPC bersama bersama-sama pada jaringan yang sama. Kami juga menyarankan Anda memiliki satu project untuk menghosting VPC Bersama, dan dua project layanan untuk membuat cluster. Untuk selengkapnya informasi, lihat Menyiapkan cluster dengan VPC Bersama.
  • Jika Anda menggunakan Certificate Authority Service, semua cluster harus memiliki rantai kumpulan CA bawahan masing-masing ke kumpulan root CA yang sama. Jika tidak, semuanya harus menggunakan kumpulan CA yang sama.

Menetapkan variabel project dan cluster

  1. Buat variabel lingkungan berikut untuk project ID, cluster zona atau region, nama cluster, dan konteks.

    export PROJECT_1=PROJECT_ID_1
    export LOCATION_1=CLUSTER_LOCATION_1
    export CLUSTER_1=CLUSTER_NAME_1
    export CTX_1="gke_${PROJECT_1}_${LOCATION_1}_${CLUSTER_1}"
    
    export PROJECT_2=PROJECT_ID_2
    export LOCATION_2=CLUSTER_LOCATION_2
    export CLUSTER_2=CLUSTER_NAME_2
    export CTX_2="gke_${PROJECT_2}_${LOCATION_2}_${CLUSTER_2}"
    
  2. Jika ini adalah cluster yang baru dibuat, pastikan untuk mengambil kredensial untuk setiap cluster cluster dengan perintah gcloud berikut atau yang terkait dengannya context tidak akan dapat digunakan pada langkah berikutnya dalam panduan ini.

    Perintah ini bergantung pada jenis cluster Anda, baik regional maupun zona:

    Regional

    gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1}
    gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}
    

    Zonal

    gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1}
    gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
    

Buat aturan firewall

Dalam beberapa kasus, Anda perlu membuat aturan firewall untuk mengizinkan lintas cluster kemacetan. Misalnya, Anda perlu membuat aturan firewall jika:

  • Anda akan menggunakan subnet yang berbeda untuk cluster di mesh.
  • Pod Anda membuka port selain 443 dan 15002.

GKE secara otomatis menambahkan aturan firewall ke setiap node untuk mengizinkan traffic jaringan dalam subnet yang sama. Jika mesh Anda berisi beberapa subnet, Anda harus secara eksplisit mengatur aturan {i>firewall<i} untuk mengizinkan lalu lintas lintas subnet. Anda harus menambahkan aturan firewall baru untuk setiap subnet agar IP CIDR sumber dapat memblokir dan menargetkan porta dari semua traffic masuk.

Instruksi berikut memungkinkan komunikasi antara semua cluster dalam project atau hanya antara $CLUSTER_1 dan $CLUSTER_2.

  1. Kumpulkan informasi tentang cluster Anda jaringan.

    Semua cluster project

    Jika cluster berada dalam project yang sama, Anda dapat menggunakan perintah berikut untuk memungkinkan komunikasi antara semua klaster dalam proyek Anda. Jika ada cluster dalam project yang tidak ingin Anda tampilkan, gunakan perintah di tab Cluster tertentu.

    function join_by { local IFS="$1"; shift; echo "$*"; }
    ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project $PROJECT_1 --format='value(clusterIpv4Cidr)' | sort | uniq)
    ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
    ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --project $PROJECT_1 --format='value(tags.items.[0])' | sort | uniq)
    ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
    

    Cluster tertentu

    Perintah berikut memungkinkan komunikasi antara $CLUSTER_1 dan $CLUSTER_2 dan tidak mengekspos cluster lain dalam project Anda.

    function join_by { local IFS="$1"; shift; echo "$*"; }
    ALL_CLUSTER_CIDRS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P container clusters list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(clusterIpv4Cidr)'; done | sort | uniq)
    ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
    ALL_CLUSTER_NETTAGS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P compute instances list  --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(tags.items.[0])' ; done | sort | uniq)
    ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
    
  2. Membuat aturan firewall.

    GKE

    gcloud compute firewall-rules create istio-multicluster-pods \
        --allow=tcp,udp,icmp,esp,ah,sctp \
        --direction=INGRESS \
        --priority=900 \
        --source-ranges="${ALL_CLUSTER_CIDRS}" \
        --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet \
        --network=YOUR_NETWORK
    

    Autopilot

    TAGS=""
    for CLUSTER in ${CLUSTER_1} ${CLUSTER_2}
    do
        TAGS+=$(gcloud compute firewall-rules list --filter="Name:$CLUSTER*" --format="value(targetTags)" | uniq) && TAGS+=","
    done
    TAGS=${TAGS::-1}
    echo "Network tags for pod ranges are $TAGS"
    
    gcloud compute firewall-rules create asm-multicluster-pods \
        --allow=tcp,udp,icmp,esp,ah,sctp \
        --network=gke-cluster-vpc \
        --direction=INGRESS \
        --priority=900 --network=VPC_NAME \
        --source-ranges="${ALL_CLUSTER_CIDRS}" \
        --target-tags=$TAGS
    

Mengonfigurasi penemuan endpoint

Memungkinkan penemuan endpoint antara cluster publik atau pribadi dengan API deklaratif

Mengaktifkan Cloud Service Mesh terkelola dengan fleet API akan mengaktifkan penemuan endpoint untuk cluster ini. Jika menyediakan Cloud Service Mesh terkelola dengan alat lain, Anda dapat mengaktifkan penemuan endpoint secara manual di seluruh cluster pribadi dalam fleet dengan menerapkan konfigurasi "multicluster_mode":"connected" di Konfigurasi peta asm-options. Cluster yang mengaktifkan konfigurasi ini di fleet yang sama akan mengaktifkan penemuan layanan lintas cluster secara otomatis di antara setiap lainnya.

Ini adalah satu-satunya cara untuk mengonfigurasi penemuan endpoint multi-cluster jika Anda memiliki Penerapan bidang kontrol terkelola (TD), dan cara yang disarankan untuk mengonfigurasinya jika Anda memiliki penerapan Terkelola (Istiod).

Sebelum melanjutkan, Anda harus memiliki membuat aturan firewall.

Aktifkan

Jika peta konfigurasi asm-options sudah ada di cluster Anda, aktifkan penemuan endpoint untuk cluster:

      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'

Jika peta konfigurasi asm-options belum ada di cluster Anda, maka membuatnya dengan data yang terkait dan mengaktifkan penemuan endpoint untuk :

      kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')

Nonaktifkan

Nonaktifkan penemuan endpoint untuk cluster:

      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'

Jika Anda membatalkan pendaftaran cluster dari fleet tanpa menonaktifkan penemuan endpoint, secret bisa tetap berada di cluster. Anda harus secara manual membersihkan sisa rahasia.

  1. Jalankan perintah berikut untuk menemukan rahasia yang memerlukan pembersihan:

    kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=true
    
  2. Hapus setiap secret:

    kubectl delete secret SECRET_NAME
    

    Ulangi langkah ini untuk setiap secret yang tersisa.

Memverifikasi konektivitas multi-cluster

Bagian ini menjelaskan cara men-deploy contoh layanan HelloWorld dan Sleep ke lingkungan multi-cluster Anda untuk memverifikasi bahwa beban lintas cluster cara kerja balancing.

Menetapkan variabel untuk direktori contoh

  1. Buka tempat asmcli didownload, lalu jalankan perintah berikut untuk menyetel ASM_VERSION

    export ASM_VERSION="$(./asmcli --version)"
    
  2. Tetapkan folder kerja ke contoh yang Anda gunakan untuk memverifikasi bahwa load balancing lintas cluster. Sampel terletak di di direktori --output_dir yang telah Anda tentukan di dalam perintah asmcli install. Pada perintah berikut, ubah OUTPUT_DIR ke direktori yang Anda tentukan di --output_dir.

    export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
    

Aktifkan injeksi file bantuan

  1. Buat namespace contoh di setiap cluster.

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl create --context=${CTX} namespace sample
    done
    
  2. Mengaktifkan namespace untuk injeksi. Langkah-langkah bergantung pada penerapan bidang kontrol Anda.

    Terkelola (TD)

    1. Terapkan label injeksi default ke namespace:
    for CTX in ${CTX_1} ${CTX_2}
    do
       kubectl label --context=${CTX} namespace sample
          istio.io/rev- istio-injection=enabled --overwrite
    done
    

    Terkelola (Istiod)

    Direkomendasikan: Jalankan perintah berikut untuk menerapkan label injeksi default ke namespace:

     for CTX in ${CTX_1} ${CTX_2}
     do
        kubectl label --context=${CTX} namespace sample \
           istio.io/rev- istio-injection=enabled --overwrite
     done
    

    Jika Anda sudah menjadi pengguna dengan bidang kontrol Istio Terkelola: Kami menyarankan agar Anda menggunakan injeksi default, tetapi injeksi berbasis revisi didukung. Gunakan petunjuk berikut:

    1. Jalankan perintah berikut untuk menemukan saluran rilis yang tersedia:

      kubectl -n istio-system get controlplanerevision
      

      Outputnya mirip dengan hal berikut ini:

      NAME                AGE
      asm-managed-rapid   6d7h
      

      Pada output, nilai pada kolom NAME adalah label revisi yang sesuai dengan saluran rilis yang tersedia untuk versi Cloud Service Mesh.

    2. Terapkan label revisi ke namespace:

      for CTX in ${CTX_1} ${CTX_2}
      do
        kubectl label --context=${CTX} namespace sample \
           istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      done
      

Menginstal layanan HelloWorld

  • Buat layanan HelloWorld di kedua cluster:

    kubectl create --context=${CTX_1} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    
    kubectl create --context=${CTX_2} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    

Men-deploy HelloWorld v1 dan v2 ke setiap cluster

  1. Deploy HelloWorld v1 ke CLUSTER_1 dan v2 ke CLUSTER_2, yang nantinya akan membantu memverifikasi load balancing lintas cluster:

    kubectl create --context=${CTX_1} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v1 -n sample
    kubectl create --context=${CTX_2} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v2 -n sample
  2. Pastikan HelloWorld v1 dan v2 berjalan menggunakan perintah berikut. Pastikan output mirip dengan yang ditampilkan.:

    kubectl get pod --context=${CTX_1} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v1-86f77cd7bd-cpxhv  2/2       Running   0          40s
    kubectl get pod --context=${CTX_2} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v2-758dd55874-6x4t8  2/2       Running   0          40s

Men-deploy layanan Tidur

  1. Deploy layanan Sleep ke kedua cluster. Pod ini menghasilkan traffic jaringan buatan untuk tujuan demonstrasi:

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl apply --context=${CTX} \
            -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample
    done
    
  2. Tunggu hingga layanan Sleep dimulai di setiap cluster. Pastikan output mirip dengan yang ditampilkan:

    kubectl get pod --context=${CTX_1} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-n6bzf           2/2     Running   0          5s
    kubectl get pod --context=${CTX_2} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-dzl9j           2/2     Running   0          5s

Memverifikasi load balancing lintas cluster

Panggil layanan HelloWorld beberapa kali dan periksa outputnya untuk memverifikasi balasan alternatif dari v1 dan v2:

  1. Panggil layanan HelloWorld:

    kubectl exec --context="${CTX_1}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_1}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    Outputnya mirip dengan yang ditampilkan:

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...
  2. Panggil layanan HelloWorld lagi:

    kubectl exec --context="${CTX_2}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_2}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    Outputnya mirip dengan yang ditampilkan:

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...

Selamat, Anda telah memverifikasi Cloud Service Mesh multi-cluster dengan load balancing.

Membersihkan layanan HelloWorld

Setelah Anda selesai memverifikasi load balancing, hapus HelloWorld dan Sleep dari cluster Anda.

kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}