Menyiapkan mesh multi-cluster di Cloud Service Mesh terkelola
Google Cloud Untuk mengetahui informasi selengkapnya, lihat Ringkasan Cloud Service Mesh.Panduan ini menjelaskan cara menggabungkan dua cluster ke dalam satu Cloud Service Mesh menggunakan CA Mesh atau Certificate Authority Service dan mengaktifkan load balancing lintas cluster. Anda dapat dengan mudah memperluas proses ini untuk menggabungkan sejumlah cluster ke dalam mesh Anda.
Konfigurasi Cloud Service Mesh multi-cluster dapat menyelesaikan beberapa skenario penting perusahaan, seperti skala, lokasi, dan isolasi. Untuk mengetahui 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 diinstal di cluster. Anda memerlukan
asmcli
, alatistioctl
, dan sampel yang didownloadasmcli
ke direktori yang Anda tentukan di--output_dir
. - Cluster di mesh Anda harus memiliki konektivitas antar-semua pod sebelum Anda mengonfigurasi Cloud Service Mesh. Selain itu, jika Anda menggabungkan cluster yang tidak berada dalam project yang sama, cluster tersebut harus didaftarkan ke project host fleet yang sama, dan cluster tersebut harus berada dalam konfigurasi VPC bersama bersama di jaringan yang sama. Sebaiknya Anda memiliki satu project untuk menghosting VPC Bersama, dan dua project layanan untuk membuat cluster. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan cluster dengan VPC Bersama.
- Jika Anda menggunakan Layanan Certificate Authority, semua cluster harus memiliki rantai kumpulan CA subordinat masing-masing ke kumpulan CA root yang sama. Jika tidak, semuanya harus menggunakan kumpulan CA yang sama.
Menetapkan variabel project dan cluster
Buat variabel lingkungan berikut untuk project ID, zona atau region cluster, 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}"
Jika ini adalah cluster yang baru dibuat, pastikan untuk mengambil kredensial untuk setiap cluster dengan perintah
gcloud
berikut. Jika tidak,context
terkaitnya tidak akan tersedia untuk digunakan pada langkah berikutnya dalam panduan ini.Perintah bergantung pada jenis cluster Anda, baik regional maupun zonal:
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 traffic antar-cluster. Misalnya, Anda perlu membuat aturan firewall jika:
- Anda menggunakan subnet yang berbeda untuk cluster di mesh Anda.
- Pod Anda membuka port selain 443 dan 15002.
GKE secara otomatis menambahkan aturan firewall ke setiap node untuk mengizinkan traffic dalam subnet yang sama. Jika mesh Anda berisi beberapa subnet, Anda harus menyiapkan aturan firewall secara eksplisit untuk mengizinkan traffic lintas subnet. Anda harus menambahkan aturan firewall baru untuk setiap subnet guna mengizinkan blok CIDR IP sumber dan port target dari semua traffic masuk.
Petunjuk berikut memungkinkan komunikasi antara semua cluster dalam project Anda atau hanya antara $CLUSTER_1
dan $CLUSTER_2
.
Kumpulkan informasi tentang jaringan cluster Anda.
Semua cluster project
Jika cluster berada dalam project yang sama, Anda dapat menggunakan perintah berikut untuk mengizinkan komunikasi antara semua cluster dalam project Anda. Jika ada cluster dalam project yang tidak ingin Anda ekspos, 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
serta 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}"))
Buat 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
Mengaktifkan 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 Anda menyediakan Cloud Service Mesh terkelola dengan alat yang berbeda, Anda dapat mengaktifkan penemuan endpoint secara manual di seluruh cluster publik atau
pribadi dalam armada dengan menerapkan konfigurasi "multicluster_mode":"connected"
di
configmap asm-options
. Cluster dengan konfigurasi ini yang diaktifkan dalam fleet yang sama
akan mengaktifkan penemuan layanan lintas cluster secara otomatis di antara
satu sama lain.
Ini adalah satu-satunya cara untuk mengonfigurasi penemuan endpoint multi-cluster jika Anda memiliki implementasi bidang kontrol yang Dikelola (TD), dan cara yang direkomendasikan untuk mengonfigurasinya jika Anda memiliki implementasi yang Dikelola (Istiod).
Sebelum melanjutkan, Anda harus membuat aturan firewall.
Aktifkan
Jika configmap 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 asm-options
configmap belum ada di cluster Anda, buat dengan data terkait dan aktifkan penemuan endpoint untuk cluster:
kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
Nonaktifkan
Menonaktifkan 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 dapat tetap berada di cluster. Anda harus membersihkan rahasia yang tersisa secara manual.
Jalankan perintah berikut untuk menemukan secret yang perlu dibersihkan:
kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=true
Hapus setiap secret:
kubectl delete secret SECRET_NAME
Ulangi langkah ini untuk setiap rahasia yang tersisa.
Memverifikasi konektivitas multi-cluster
Bagian ini menjelaskan cara men-deploy layanan HelloWorld
dan Sleep
contoh
ke lingkungan multi-cluster Anda untuk memverifikasi bahwa load balancing
lintas cluster berfungsi.
Tetapkan variabel untuk direktori sampel
Buka tempat
asmcli
didownload, lalu jalankan perintah berikut untuk menyetelASM_VERSION
export ASM_VERSION="$(./asmcli --version)"
Tetapkan folder kerja ke sampel yang Anda gunakan untuk memverifikasi bahwa load balancing lintas cluster berfungsi. Contoh terletak di subdirektori dalam direktori
--output_dir
yang Anda tentukan dalam perintahasmcli install
. Dalam perintah berikut, ubahOUTPUT_DIR
ke direktori yang Anda tentukan di--output_dir
.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Mengaktifkan injeksi sidecar
Buat namespace contoh di setiap cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample done
Aktifkan namespace untuk injeksi. Langkah-langkahnya bergantung pada implementasi bidang kontrol Anda.
Terkelola (TD)
- 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
Dikelola (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 adalah pengguna lama dengan Managed Istiod control plane: Sebaiknya gunakan injeksi default, tetapi injeksi berbasis revisi didukung. Gunakan petunjuk berikut:
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
Dalam output, nilai di kolom
NAME
adalah label revisi yang sesuai dengan saluran rilis yang tersedia untuk versi Cloud Service Mesh.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
Deploy HelloWorld v1 dan v2 ke setiap cluster
Deploy
HelloWorld v1
keCLUSTER_1
danv2
keCLUSTER_2
, yang akan membantu memverifikasi load balancing lintas cluster nanti: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
Konfirmasi bahwa
HelloWorld v1
danv2
berjalan menggunakan perintah berikut. Pastikan output-nya 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 Sleep
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
Tunggu hingga layanan
Sleep
dimulai di setiap cluster. Pastikan output-nya 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 output untuk memverifikasi
balasan bergantian dari v1 dan v2:
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 ...
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 yang di-load balance.
Mempertahankan traffic dalam cluster
Dalam beberapa kasus, perilaku load balancing lintas cluster default tidak diinginkan. Untuk menjaga traffic "cluster-local" (yaitu traffic yang dikirim dari cluster-a
hanya akan mencapai tujuan di cluster-a
), tandai nama host atau karakter pengganti sebagai clusterLocal
menggunakan MeshConfig.serviceSettings
.
Misalnya, Anda dapat menerapkan traffic lokal cluster untuk layanan individual, semua layanan dalam namespace tertentu, atau secara global untuk semua layanan dalam mesh, sebagai berikut:
per layanan
serviceSettings:
- settings:
clusterLocal: true
hosts:
- "mysvc.myns.svc.cluster.local"
per-namespace
serviceSettings:
- settings:
clusterLocal: true
hosts:
- "*.myns.svc.cluster.local"
global
serviceSettings:
- settings:
clusterLocal: true
hosts:
- "*"
Anda juga dapat menyempurnakan akses layanan dengan menetapkan aturan global cluster-local dan menambahkan pengecualian eksplisit, yang dapat berupa pengecualian spesifik atau karakter pengganti. Dalam contoh berikut, semua layanan di cluster akan tetap bersifat lokal cluster, kecuali layanan apa pun di namespace myns:
serviceSettings:
- settings:
clusterLocal: true
hosts:
- "*"
- settings:
clusterLocal: false
hosts:
- "*.myns.svc.cluster.local"
Aktifkan Layanan Cluster Lokal
Periksa peta konfigurasi MeshConfig di cluster
kubectl get configmap -n istio-system
Anda akan melihat peta konfigurasi dengan salah satu nama
istio-asm-managed
,istio-asm-managed-rapid
, atauistio-asm-managed-stable
.Jika Anda telah bermigrasi dari penerapan
ISTIOD
ke penerapanTRAFFIC_DIRECTOR
, Anda mungkin melihat lebih dari satu peta konfigurasi. Dalam hal ini, Anda dapat menentukan channel dengan menjalankan perintah berikut:kubectl get controlplanerevision -n istio-system
Saluran Revisi Bidang Kontrol yang disesuaikan adalah saluran yang ingin Anda pilih.
Perbarui Config Map
cat <<EOF > config.yaml apiVersion: v1 kind: ConfigMap metadata: name: CONFIGMAP_NAME namespace: istio-system data: config: | serviceSettings: - settings: clusterLocal: true hosts: - "*" EOF
Ganti
CONFIGMAP_NAME
dengan nama Config Map yang Anda temukan di langkah 1 dan perbarui config map.kubectl apply --context=${CTX_1} -f config.yaml
Konfirmasi bahwa fitur Cluster Lokal berfungsi seperti yang diharapkan menggunakan perintah berikut. Output untuk memanggil
HelloWorld
denganCTX_1
mirip dengan: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'
Anda akan melihat Only v1 is response dalam output:
Hello version: v1, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Jika Anda memanggil
HelloWorld
denganCTX_2
: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'
Anda akan melihat balasan bergantian dari v1 dan v2 di output.
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Membersihkan layanan HelloWorld
Setelah Anda selesai memverifikasi load balancing, hapus layanan HelloWorld
dan Sleep
dari cluster Anda.
kubectl delete ns sample --context ${CTX_1} kubectl delete ns sample --context ${CTX_2}