Halaman ini menjelaskan cara men-deploy resource Gateway Kubernetes untuk load balancing traffic masuk di beberapa cluster (atau fleet) Google Kubernetes Engine (GKE). Sebelum men-deploy Gateway multi-cluster, lihat Mengaktifkan Gateway multi-cluster untuk menyiapkan lingkungan Anda.
Untuk men-deploy Gateway guna melakukan load balancing traffic masuk ke satu cluster GKE saja, lihat Men-deploy Gateway.
Gateway Multi-cluster
Gateway multi-cluster adalah resource Gateway yang melakukan load balancing pada traffic di
beberapa cluster Kubernetes. Di GKE, gke-l7-global-external-managed-mc
,
gke-l7-regional-external-managed-mc
, gke-l7-rilb-mc
, dan gke-l7-gxlb-mc
GatewayClasses men-deploy Gateway multi-cluster yang menyediakan perutean HTTP, pemisahan
traffic, duplikasi traffic, failover berbasis kondisi, dan banyak lagi di berbagai
cluster GKE, Namespace Kubernetes, dan berbagai region.
Dengan Gateway Multi-cluster, pengelolaan jaringan aplikasi di banyak cluster
dan tim menjadi mudah, aman, dan skalabel bagi administrator infrastruktur.
Halaman ini memperkenalkan tiga contoh untuk mengajari Anda cara men-deploy Gateway multi-cluster menggunakan pengontrol Gateway GKE:
- Contoh 1: Gateway multi-cluster eksternal yang menyediakan load balancing di dua cluster GKE untuk traffic internet.
- Contoh 2: Gateway lintas regional lapisan 7 pribadi.
- Contoh 3: Pemisahan traffic berbasis bobot blue-green dan duplikasi traffic di dua cluster GKE untuk traffic VPC internal.
- Contoh 4: Gateway berbasis kapasitas untuk melakukan load balancing permintaan ke backend yang berbeda berdasarkan kapasitas maksimumnya.
Setiap contoh akan menggunakan aplikasi store dan site yang sama untuk membuat model skenario dunia nyata dengan layanan belanja online dan layanan situs dimiliki serta dikelola oleh tim terpisah dan di-deploy di seluruh fleet cluster GKE bersama. Setiap contoh menyoroti topologi dan kasus penggunaan berbeda yang diaktifkan oleh Gateway multi-cluster.
Gateway Multi-cluster memerlukan beberapa persiapan lingkungan sebelum dapat di-deploy. Sebelum melanjutkan, ikuti langkah-langkah di bagian Mengaktifkan Gateway multi-cluster:
Deploy cluster GKE
Daftarkan cluster Anda ke fleet.
Aktifkan Service multi-cluster dan pengontrol Gateway multi-cluster.
Terakhir, tinjau batasan dan masalah umum Gateway GKE Controller sebelum menggunakannya di lingkungan Anda.
Gateway eksternal, multi-cluster, multi-region
Dalam tutorial ini, Anda akan membuat Gateway multi-cluster eksternal yang menyalurkan traffic eksternal di seluruh aplikasi yang berjalan di dua cluster GKE.
Pada langkah berikut, Anda akan:
- Men-deploy aplikasi
store
contoh ke clustergke-west-1
dangke-east-1
. - Mengonfigurasi Service di setiap cluster untuk diekspor ke fleet Anda (Service multi-cluster).
- Deploy Gateway multi-cluster eksternal dan HTTPRoute
ke cluster konfigurasi Anda (
gke-west-1
).
Setelah aplikasi dan resource Gateway di-deploy, Anda dapat mengontrol traffic di kedua cluster GKE menggunakan perutean berbasis jalur:
- Permintaan ke
/west
dirutekan ke Podstore
di clustergke-west-1
. - Permintaan ke
/east
dirutekan ke Podstore
di clustergke-east-1
. - Permintaan ke jalur lain akan diarahkan ke salah satu cluster, sesuai dengan kondisi, kapasitas, dan jaraknya dengan klien yang meminta.
Men-deploy aplikasi demo
Buat Deployment dan Namespace
store
di ketiga cluster yang di-deploy di Mengaktifkan Gateway multi-cluster:kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.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.yaml kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
Solusi ini akan men-deploy resource berikut ke setiap cluster:
namespace/store created deployment.apps/store created
Semua contoh di halaman ini menggunakan aplikasi yang di-deploy pada langkah ini. Pastikan aplikasi di-deploy di ketiga cluster sebelum mencoba salah satu langkah lainnya. Contoh ini hanya menggunakan cluster
gke-west-1
dangke-east-1
, dangke-west-2
digunakan dalam contoh lain.
Service Multi-cluster
Service adalah cara Pod diekspos kepada klien. Karena GKE Gateway Controller menggunakan load balancing berbasis container, GKE ini tidak menggunakan load balancing ClusterIP atau Kubernetes untuk menjangkau Pod. Traffic dikirim langsung dari load balancer ke alamat IP Pod. Namun, Service masih memainkan peran penting sebagai ID logis untuk pengelompokan Pod.
Multi-cluster Services (MCS) adalah standar API untuk Service yang mencakup cluster dan pengontrol GKE-nya menyediakan penemuan layanan di seluruh cluster GKE. Pengontrol Gateway multi-cluster menggunakan resource API MCS untuk mengelompokkan Pod ke dalam Service yang dapat ditangani di seluruh cluster atau menjangkau beberapa cluster.
API Service multi-cluster menentukan resource kustom berikut:
- ServiceExports dipetakan ke Service Kubernetes, yang mengekspor endpoint Service tersebut ke semua cluster yang terdaftar di fleet. Jika Service memiliki ServiceExport yang sesuai, berarti Service tersebut dapat ditangani oleh Gateway multi-cluster.
- ServiceImports secara otomatis dibuat oleh pengontrol Service multi-cluster. ServiceExport dan ServiceImport berpasangan. Jika ServiceExport ada di fleet, ServiceImport yang sesuai akan dibuat agar Service yang dipetakan ke ServiceExport dapat diakses dari berbagai cluster.
Pengeksporan Service berfungsi dengan cara berikut. Service penyimpanan ada di
gke-west-1
yang memilih grup Pod di cluster tersebut. ServiceExport
dibuat di cluster yang memungkinkan Pod di gke-west-1
dapat diakses
dari cluster lain di fleet. ServiceExport akan dipetakan ke dan menampilkan Service yang memiliki nama dan Namespace yang sama dengan resource ServiceExport.
apiVersion: v1
kind: Service
metadata:
name: store
namespace: store
spec:
selector:
app: store
ports:
- port: 8080
targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
name: store
namespace: store
Diagram berikut menunjukkan hal yang terjadi setelah ServiceExport di-deploy. Jika
ada pasangan ServiceExport dan Service, pengontrol Service multi-cluster akan
men-deploy ServiceImport yang sesuai ke setiap cluster GKE
di fleet. ServiceImport adalah representasi lokal dari Service store
di setiap cluster. Dengan adanya ServiceImport, Pod client
di gke-east-1
dapat menggunakan ClusterIP atau
Service headless untuk menjangkau Pod store
di gke-west-1
. Jika digunakan dengan cara ini,
Service multi-cluster akan menyediakan load balancing east-west antar-cluster tanpa
memerlukan Layanan LoadBalancer internal.
Agar dapat menggunakan Service multi-cluster untuk load balancing cluster-ke-cluster, lihat
Mengonfigurasi Service multi-cluster.
Gateway multi-cluster juga menggunakan ServiceImports, tetapi tidak untuk load balancing cluster-ke-cluster. Sebagai gantinya, Gateway menggunakan ServiceImports sebagai ID logis untuk Service yang ada di cluster lain atau yang tersebar di beberapa cluster. HTTPRoute berikut merujuk ke ServiceImport, bukan resource Service. Dengan mereferensikan ServiceImport, tindakan ini menunjukkan bahwa traffic meneruskan ke grup Pod backend yang berjalan di satu atau beberapa cluster.
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-route
namespace: store
labels:
gateway: multi-cluster-gateway
spec:
parentRefs:
- kind: Gateway
namespace: store
name: external-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- group: net.gke.io
kind: ServiceImport
name: store
port: 8080
Diagram berikut menunjukkan cara HTTPRoute merutekan traffic store.example.com
ke
Pod store
di gke-west-1
dan gke-east-1
. Load balancer memperlakukannya sebagai
satu kumpulan backend. Jika Pod dari salah satu cluster menjadi tidak responsif,
tidak dapat dijangkau, atau tidak memiliki kapasitas traffic, beban traffic akan diseimbangkan dengan
Pod lainnya di cluster lain. Cluster baru dapat ditambahkan atau dihapus dengan
Service store
dan ServiceExport. Tindakan ini akan menambahkan atau menghapus
Pod backend secara transparan tanpa perubahan konfigurasi pemilihan rute eksplisit.
Mengekspor Service
Di tahap ini, aplikasi berjalan di kedua cluster. Selanjutnya, Anda akan mengekspos dan mengekspor aplikasi dengan men-deploy Service dan ServiceExport ke setiap cluster.
Terapkan manifes berikut ke cluster
gke-west-1
untuk membuat Service dan ServiceExportstore
danstore-west-1
:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 namespace: store EOF
Terapkan manifes berikut ke cluster
gke-east-1
untuk membuat Service dan ServiceExportstore
danstore-east-1
:cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 namespace: store EOF
Pastikan ServiceExport yang benar telah dibuat di cluster.
kubectl get serviceexports --context CLUSTER_NAME --namespace store
Ganti CLUSTER_NAME dengan
gke-west-1
dangke-east-1
. Output akan terlihat seperti berikut:# gke-west-1 NAME AGE store 2m40s store-west-1 2m40s # gke-east-1 NAME AGE store 2m25s store-east-1 2m25s
Hal ini menunjukkan bahwa Service
store
berisi Podstore
di kedua cluster sementara Servicestore-west-1
danstore-east-1
hanya berisi Podstore
di cluster masing-masing. Service yang tumpang-tindih ini digunakan untuk menargetkan Pod di beberapa cluster atau subset Pod di satu cluster.Setelah beberapa menit, pastikan
ServiceImports
yang menyertainya telah otomatis dibuat oleh pengontrol Layanan multi-cluster di semua cluster dalam fleet.kubectl get serviceimports --context CLUSTER_NAME --namespace store
Ganti CLUSTER_NAME dengan
gke-west-1
dangke-east-1
. Output akan terlihat seperti berikut:# gke-west-1 NAME TYPE IP AGE store ClusterSetIP ["10.112.31.15"] 6m54s store-east-1 ClusterSetIP ["10.112.26.235"] 5m49s store-west-1 ClusterSetIP ["10.112.16.112"] 6m54s # gke-east-1 NAME TYPE IP AGE store ClusterSetIP ["10.72.28.226"] 5d10h store-east-1 ClusterSetIP ["10.72.19.177"] 5d10h store-west-1 ClusterSetIP ["10.72.28.68"] 4h32m
Hal ini menunjukkan bahwa ketiga Service dapat diakses dari kedua cluster di fleet. Namun, karena hanya ada satu cluster konfigurasi aktif per fleet, Anda hanya dapat men-deploy Gateway dan HTTPRoute yang mereferensikan ServiceImport ini di
gke-west-1
. Saat HTTPRoute di cluster konfigurasi merujuk ServiceImport ini sebagai backend, Gateway dapat meneruskan traffic ke Service ini, terlepas dari cluster tempat traffic tersebut diekspor.
Men-deploy Gateway dan HTTPRoute
Setelah aplikasi di-deploy, Anda dapat mengonfigurasi Gateway menggunakan
GatewayClass gke-l7-global-external-managed-mc
. Gateway ini membuat Load Balancer Aplikasi eksternal yang dikonfigurasi untuk mendistribusikan traffic di seluruh cluster target Anda.
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/v1beta1 metadata: name: external-http namespace: store spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Konfigurasi Gateway ini men-deploy resource Load Balancer Aplikasi eksternal dengan konvensi penamaan berikut:
gkemcg1-NAMESPACE-GATEWAY_NAME-HASH
.Resource default yang dibuat dengan konfigurasi ini adalah:
- 1 load balancer:
gkemcg1-store-external-http-HASH
- 1 alamat IP publik:
gkemcg1-store-external-http-HASH
- 1 aturan penerusan:
gkemcg1-store-external-http-HASH
- 2 layanan backend:
- Layanan backend 404 default:
gkemcg1-store-gw-serve404-HASH
- Layanan backend 500 default:
gkemcg1-store-gw-serve500-HASH
- Layanan backend 404 default:
- 1 Health check:
- Pemeriksaan kesehatan 404 default:
gkemcg1-store-gw-serve404-HASH
- Pemeriksaan kesehatan 404 default:
- 0 aturan pemilihan rute (URLmap kosong)
Pada tahap ini, setiap permintaan ke GATEWAY_IP:80 akan menghasilkan halaman default yang menampilkan pesan berikut:
fault filter abort
.- 1 load balancer:
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/v1beta1 metadata: name: public-store-route namespace: store labels: gateway: external-http spec: hostnames: - "store.example.com" parentRefs: - name: external-http rules: - matches: - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-1 port: 8080 - matches: - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 port: 8080 - backendRefs: - group: net.gke.io kind: ServiceImport name: store port: 8080 EOF
Pada tahap ini, setiap permintaan ke GATEWAY_IP:80 akan menghasilkan halaman default yang menampilkan pesan berikut:
fault filter abort
.Setelah di-deploy, HTTPRoute ini akan mengonfigurasi perilaku perutean berikut:
- Permintaan ke
/west
dirutekan ke Podstore
di clustergke-west-1
, karena Pod yang dipilih oleh ServiceExportstore-west-1
hanya ada di clustergke-west-1
. - Permintaan ke
/east
dirutekan ke Podstore
di clustergke-east-1
, karena Pod yang dipilih oleh ServiceExportstore-east-1
hanya ada di clustergke-east-1
. - Permintaan ke jalur lain akan diarahkan ke Pod
store
di salah satu cluster, sesuai dengan kondisi, kapasitas, dan jaraknya dengan klien yang meminta. - Permintaan ke GATEWAY_IP:80 akan menghasilkan halaman default yang menampilkan pesan berikut:
fault filter abort
.
Perlu diperhatikan bahwa jika semua Pod di cluster tertentu tidak responsif (atau tidak ada), traffic ke Service
store
hanya akan dikirim ke cluster yang benar-benar memiliki Podstore
. Keberadaan ServiceExport dan Service di cluster tertentu tidak menjamin bahwa traffic akan dikirim ke cluster tersebut. Pod harus ada dan merespons dengan jelas health check load balancer. Jika tidak, load balancer hanya akan mengirimkan traffic ke Podstore
yang responsif di cluster lain.Resource baru dibuat dengan konfigurasi ini:
- 3 layanan backend:
- Layanan backend
store
:gkemcg1-store-store-8080-HASH
- Layanan backend
store-east-1
:gkemcg1-store-store-east-1-8080-HASH
- Layanan backend
store-west-1
:gkemcg1-store-store-west-1-8080-HASH
- Layanan backend
- 3 Health check:
- Health check
store
:gkemcg1-store-store-8080-HASH
- Health check
store-east-1
:gkemcg1-store-store-east-1-8080-HASH
- Health check
store-west-1
:gkemcg1-store-store-west-1-8080-HASH
- Health check
- 1 aturan pemilihan rute di URLmap:
- Aturan pemilihan rute
store.example.com
: - 1 Host:
store.example.com
- Beberapa
matchRules
untuk dirutekan ke layanan backend baru
- Aturan pemilihan rute
- Permintaan ke
Diagram berikut menunjukkan resource yang telah Anda deploy di kedua cluster.
Karena gke-west-1
adalah cluster konfigurasi Gateway, cluster ini
adalah cluster tempat Gateway, HTTPRoute, dan ServiceImport dipantau
oleh pengontrol Gateway. Setiap cluster memiliki ServiceImport store
dan ServiceImport lain yang
khusus untuk cluster tersebut. Kedua titik berada di Pod yang sama. Kondisi ini memungkinkan
HTTPRoute untuk menentukan secara tepat lokasi traffic yang seharusnya, yaitu ke Pod store
di cluster tertentu atau ke Pod store
di semua cluster.
Perhatikan bahwa ini adalah model resource logis, bukan penggambaran alur traffic. Jalur traffic mengarah langsung dari load balancer ke Pod backend dan tidak memiliki hubungan langsung dengan cluster mana pun yang merupakan cluster konfigurasi.
Memvalidasi deployment
Kini, Anda dapat mengeluarkan permintaan ke Gateway multi-cluster kami dan mendistribusikan traffic di kedua cluster GKE.
Validasi bahwa Gateway dan HTTPRoute telah berhasil di-deploy dengan memeriksa status dan peristiwa Gateway.
kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
Output Anda akan terlihat seperti berikut:
Name: external-http Namespace: store Labels: <none> Annotations: networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4 networking.gke.io/backend-services: /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke... networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv networking.gke.io/health-checks: /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s... networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz networking.gke.io/target-https-proxies: networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz API Version: gateway.networking.k8s.io/v1beta1 Kind: Gateway Metadata: Creation Timestamp: 2023-10-12T06:59:32Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 467057 UID: 1dcb188e-2917-404f-9945-5f3c2e907b4c Spec: Gateway Class Name: gke-l7-global-external-managed-mc Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 34.36.127.249 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 35m (x4 over 10h) mc-gateway-controller store/external-http Normal SYNC 4m22s (x216 over 10h) mc-gateway-controller SYNC on store/external-http was a success
Setelah Gateway berhasil di-deploy, ambil alamat IP eksternal dari Gateway
external-http
.kubectl get gateways.gateway.networking.k8s.io external-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.Mengirim traffic ke jalur root domain. Load balancing ini menyeimbangkan traffic ke ServiceImport
store
yang ada di seluruh clustergke-west-1
dangke-east-1
. Load balancer mengirimkan traffic ke region terdekat dan Anda mungkin tidak melihat respons dari region lain.curl -H "host: store.example.com" http://VIP
Output mengonfirmasi bahwa permintaan dilayani oleh Pod dari cluster
gke-east-1
:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-dg22z", "pod_name_emoji": "⏭", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:32:51" }
Selanjutnya, kirim traffic ke jalur
/west
. Tindakan ini akan merutekan traffic ke ServiceImportstore-west-1
yang hanya memiliki Pod yang berjalan di clustergke-west-1
. ServiceImport khusus cluster, sepertistore-west-1
, memungkinkan pemilik aplikasi mengirim traffic ke cluster tertentu secara eksplisit, bukan membiarkan load balancer membuat keputusan.curl -H "host: store.example.com" http://VIP/west
Output mengonfirmasi bahwa permintaan dilayani oleh Pod dari cluster
gke-west-1
:{ "cluster_name": "gke-west-1", "zone": "us-west1-a", "host_header": "store.example.com", "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-d25m5", "pod_name_emoji": "🍾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:39:15", }
Terakhir, kirim traffic ke jalur
/east
.curl -H "host: store.example.com" http://VIP/east
Output mengonfirmasi bahwa permintaan dilayani oleh Pod dari cluster
gke-east-1
:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-hz6mw", "pod_name_emoji": "🧜🏾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:40:48" }
Men-deploy Gateway multi-cluster internal di seluruh region
Anda dapat men-deploy Gateway multi-cluster yang menyediakan load balancing Lapisan 7 internal di seluruh cluster GKE di beberapa region. Gateway ini menggunakan GatewayClass gke-l7-cross-regional-internal-managed-mc
. GatewayClass ini menyediakan Load Balancer Aplikasi internal lintas region yang dikelola oleh Google Cloud dan memungkinkan VIP internal yang dapat diakses oleh klien dalam jaringan VPC Anda. Gateway ini dapat diekspos oleh frontend di region pilihan Anda, cukup dengan menggunakan Gateway untuk meminta alamat di region tersebut. VIP internal dapat berupa satu alamat IP, atau dapat berupa alamat IP di beberapa wilayah, dengan satu alamat IP per wilayah yang ditentukan di Gateway. Traffic diarahkan ke cluster GKE backend responsif terdekat yang dapat melayani permintaan.
Sebelum memulai
Siapkan project dan shell dengan mengonfigurasi lingkungan
gcloud
dengan project ID Anda:export PROJECT_ID="YOUR_PROJECT_ID" gcloud config set project ${PROJECT_ID}
Membuat cluster GKE di berbagai region.
Contoh ini menggunakan dua cluster,
gke-west-1
dius-west1
dangke-east-1
dius-east1
. Pastikan Gateway API diaktifkan (--gateway-api=standard
) dan cluster terdaftar ke fleet.gcloud container clusters create gke-west-1 \ --location=us-west1-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standard gcloud container clusters create gke-east-1 \ --location=us-east1-c \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standard
Ganti nama konteks untuk memudahkan akses:
gcloud container clusters get-credentials gke-west-1 \ --location=us-west1-a \ --project=${PROJECT_ID} gcloud container clusters get-credentials gke-east-1 \ --location=us-east1-c \ --project=${PROJECT_ID} kubectl config rename-context gke_${PROJECT_ID}_us-west1-a_gke-west-1 gke-west1 kubectl config rename-context gke_${PROJECT_ID}_us-east1-c_gke-east-1 gke-east1
Aktifkan Multi-Cluster Services (MCS) dan Multi-Cluster Ingress (MCI/Gateway):
gcloud container fleet multi-cluster-services enable --project=${PROJECT_ID} # Set the config membership to one of your clusters (e.g., gke-west-1) # This cluster will be the source of truth for multi-cluster Gateway and Route resources. gcloud container fleet ingress enable \ --config-membership=projects/${PROJECT_ID}/locations/us-west1/memberships/gke-west-1 \ --project=${PROJECT_ID}
Konfigurasikan subnet khusus proxy. Subnet khusus proxy diperlukan di setiap region tempat cluster GKE Anda berada dan tempat load balancer akan beroperasi. Load Balancer Aplikasi internal Lintas-Region mewajibkan tujuan subnet ini ditetapkan ke
GLOBAL_MANAGED_PROXY
.# Proxy-only subnet for us-west1 gcloud compute networks subnets create us-west1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-west1 \ --network=default \ --range=10.129.0.0/23 # Choose an appropriate unused CIDR range # Proxy-only subnet for us-east1 gcloud compute networks subnets create us-east1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-east1 \ --network=default \ --range=10.130.0.0/23 # Choose an appropriate unused CIDR range
Jika Anda tidak menggunakan jaringan default, ganti
default
dengan nama jaringan VPC Anda. Pastikan rentang CIDR unik dan tidak tumpang-tindih.Deploy aplikasi demo Anda, seperti
store
, ke kedua cluster. Contoh filestore.yaml
darigke-networking-recipes
membuat namespacestore
dan deployment.kubectl apply --context gke-west1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-east1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
Mengekspor Layanan dari setiap cluster dengan membuat resource
Service
dan resourceServiceExport
Kubernetes di setiap cluster, yang membuat layanan dapat ditemukan di seluruh fleet. Contoh berikut mengekspor layananstore
generik dan layanan khusus region (store-west-1
,store-east-1
) dari setiap cluster, semuanya dalam namespacestore
.Berlaku untuk
gke-west1
:cat << EOF | kubectl apply --context gke-west1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 # Exporting the region-specific service namespace: store EOF
Berlaku untuk
gke-east1
:cat << EOF | kubectl apply --context gke-east1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 # Exporting the region-specific service namespace: store EOF
Periksa ServiceImports: Pastikan resource
ServiceImport
dibuat di setiap cluster dalam namespacestore
. Mungkin diperlukan waktu beberapa menit untuk membuat instance.bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store
Anda akan melihatstore
,store-west-1
, danstore-east-1
tercantum (atau entri yang relevan berdasarkan penyebaran).
Mengonfigurasi Gateway multi-region internal
Tentukan resource Gateway
yang mereferensikan GatewayClass gke-l7-cross-regional-internal-managed-mc
. Anda menerapkan manifes ini ke cluster konfigurasi yang ditetapkan, seperti gke-west-1
.
Kolom spec.addresses
memungkinkan Anda meminta alamat IP sementara di wilayah tertentu atau menggunakan alamat IP statis yang dialokasikan sebelumnya.
Untuk menggunakan alamat IP sementara, simpan manifes
Gateway
berikut sebagaicross-regional-gateway.yaml
:# cross-regional-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-cross-region-gateway namespace: store # Namespace for the Gateway resource spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: # Addresses across regions. Address value is allowed to be empty or matching # the region name. - type: networking.gke.io/ephemeral-ipv4-address/us-west1 value: "us-west1" - type: networking.gke.io/ephemeral-ipv4-address/us-east1 value: "us-east1" listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute # Only allow HTTPRoute to attach
Daftar berikut menentukan beberapa kolom dalam file YAML sebelumnya:
metadata.namespace
: namespace tempat resource Gateway dibuat, misalnya,store
.spec.gatewayClassName
: nama GatewayClass. Harus berupagke-l7-cross-regional-internal-managed-mc
.spec.listeners.allowedRoutes.kinds
: jenis objek Route yang dapat dilampirkan, misalnya,HTTPRoute
.spec.addresses
:type: networking.gke.io/ephemeral-ipv4-address/REGION
: meminta alamat IP sementara.value
: menentukan region untuk alamat, misalnya,"us-west1"
atau"us-east1"
.
Terapkan manifes ke cluster konfigurasi Anda, misalnya,
gke-west1
:kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Melampirkan HTTPRoute ke Gateway
Tentukan resource HTTPRoute
untuk mengelola pemilihan rute traffic dan terapkan ke cluster konfigurasi Anda.
Simpan manifes
HTTPRoute
berikut sebagaistore-route.yaml
:# store-route.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-route namespace: store labels: gateway: cross-regional-internal spec: parentRefs: - name: internal-cross-region-gateway namespace: store # Namespace where the Gateway is deployed hostnames: - "store.example.internal" # Hostname clients will use rules: - matches: # Rule for traffic to /west - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io # Indicates a multi-cluster ServiceImport kind: ServiceImport name: store-west-1 # Targets the ServiceImport for the west cluster port: 8080 - matches: # Rule for traffic to /east - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 # Targets the ServiceImport for the east cluster port: 8080 - backendRefs: # Default rule for other paths (e.g., /) - group: net.gke.io kind: ServiceImport name: store # Targets the generic 'store' ServiceImport (any region) port: 8080
Daftar berikut menentukan beberapa kolom dalam file YAML sebelumnya:
spec.parentRefs
: melampirkan rute ini kecross-region-gateway
di namespacestore
.spec.hostnames
: mewakili nama host yang digunakan klien untuk mengakses layanan.spec.rules
: menentukan logika perutean. Contoh ini menggunakan perutean berbasis jalur:- Traffic
/west
dirutekan ke ServiceImportstore-west-1
. - Traffic
/east
dirutekan ke ServiceImportstore-east-1
. - Semua traffic lainnya, seperti
/
, akan diarahkan ke ServiceImportstore
generik.
- Traffic
backendRefs
:group: net.gke.io
dankind: ServiceImport
menargetkan layanan multi-cluster.
Terapkan manifes
HTTPRoute
ke cluster konfigurasi Anda:kubectl apply --context gke-west1 -f store-route.yaml
Memverifikasi status Gateway dan Route
Periksa status Gateway:
kubectl get gateway cross-region-gateway -n store -o yaml --context gke-west1
Cari kondisi dengan status
type:
Programmedand
: "True". You should see IP addresses assigned in the
status.addressesfield, corresponding to the regions you specified (e.g., one for
us-west1and one for
us-east1`).Periksa status HTTPRoute:
kubectl get httproute store-route -n store -o yaml --context gke-west1
Cari kondisi di
status.parents[].conditions
dengantype: Accepted
(atauResolvedRefs
) danstatus: "True"
.
Mengonfirmasi traffic
Setelah menetapkan alamat IP ke Gateway, Anda dapat menguji traffic dari VM klien yang berada dalam jaringan VPC dan di salah satu region, atau di region yang dapat terhubung ke alamat IP Gateway.
Ambil alamat IP Gateway.
Perintah berikut mencoba mengurai output JSON. Anda mungkin perlu menyesuaikan
jsonpath
berdasarkan struktur yang tepat.kubectl get gateway cross-region-gateway -n store --context gke-west1 -o=jsonpath="{.status.addresses[*].value}".
Output perintah ini harus menyertakan VIP, seperti
VIP1_WEST
, atauVIP2_EAST
.Kirim permintaan pengujian: Dari VM klien di VPC Anda:
# Assuming VIP_WEST is an IP in us-west1 and VIP_EAST is an IP in us-east1 # Traffic to /west should ideally be served by gke-west-1 curl -H "host: store.example.internal" http://VIP_WEST/west curl -H "host: store.example.internal" http://VIP_EAST/west # Still targets store-west-1 due to path # Traffic to /east should ideally be served by gke-east-1 curl -H "host: store.example.internal" http://VIP_WEST/east # Still targets store-east-1 due to path curl -H "host: store.example.internal" http://VIP_EAST/east # Traffic to / (default) could be served by either cluster curl -H "host: store.example.internal" http://VIP_WEST/ curl -H "host: store.example.internal" http://VIP_EAST/
Respons harus menyertakan detail dari aplikasi
store
yang menunjukkan pod backend mana yang menyalurkan permintaan, seperticluster_name
atauzone
.
Menggunakan Alamat IP Statis
Sebagai ganti alamat IP sementara, Anda dapat menggunakan alamat IP internal statis yang dialokasikan sebelumnya.
Buat alamat IP statis di region yang ingin Anda gunakan:
gcloud compute addresses create cross-region-gw-ip-west --region us-west1 --subnet default --project=${PROJECT_ID} gcloud compute addresses create cross-region-gw-ip-east --region us-east1 --subnet default --project=${PROJECT_ID}
Jika Anda tidak menggunakan subnet default, ganti
default
dengan nama subnet yang memiliki alamat IP yang ingin dialokasikan. Subnet ini adalah subnet reguler, bukan subnet khusus proxy.Perbarui manifes Gateway dengan mengubah bagian
spec.addresses
dalam filecross-regional-gateway.yaml
Anda:# cross-regional-gateway-static-ip.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-cross-region-gateway # Or a new name if deploying alongside namespace: store spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/named-address-with-region # Use for named static IP value: "regions/us-west1/addresses/cross-region-gw-ip-west" - type: networking.gke.io/named-address-with-region value: "regions/us-west1/addresses/cross-region-gw-ip-east" listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute
Terapkan manifes Gateway yang telah diperbarui.
kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Pertimbangan khusus untuk subnet non-default
Perhatikan pertimbangan berikut saat Anda menggunakan subnet non-default:
Jaringan VPC yang sama: semua resource yang dibuat pengguna—seperti alamat IP statis, subnet khusus proxy, dan cluster GKE—harus berada dalam jaringan VPC yang sama.
Subnet alamat: saat Anda membuat alamat IP statis untuk Gateway, alamat tersebut dialokasikan dari subnet reguler di region yang ditentukan.
Pemberian nama subnet cluster: Setiap region harus memiliki subnet yang memiliki nama yang sama dengan subnet tempat cluster konfigurasi MCG berada.
- Misalnya, jika cluster konfigurasi
gke-west-1
Anda berada diprojects/YOUR_PROJECT/regions/us-west1/subnetworks/my-custom-subnet
, region yang alamatnya Anda minta juga harus memiliki subnetmy-custom-subnet
. Jika Anda meminta alamat di regionus-east1
danus-centra1
, subnet bernamamy-custom-subnet
juga harus ada di region tersebut.
- Misalnya, jika cluster konfigurasi
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:
- 100%-Canary berbasis header: Gunakan pemilihan rute header HTTP untuk hanya mengirim traffic pengujian atau sintetis ke cluster baru.
- 100%-Menduplikasi traffic: Menduplikasi traffic pengguna ke cluster canary. Tahap ini akan menguji kapasitas cluster canary dengan menyalin 100% traffic pengguna ke cluster ini.
- 90%-10%: Pemisahan traffic Canary sebesar 10% untuk perlahan-lahan mengekspos cluster baru ke traffic langsung.
- 0%-100%: Migrasi sistem sepenuhnya ke cluster baru dengan opsi untuk beralih kembali jika setiap error teramati.
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:
-
Contoh ini menggunakan cluster
gke-west-1
dangke-west-2
yang sudah Anda siapkan. Cluster ini berada di region yang sama karena GatewayClassgke-l7-rilb-mc
bersifat regional dan hanya mendukung backend cluster di region yang sama. Deploy Service dan ServiceExport yang diperlukan di setiap cluster. Jika Anda men-deploy Services dan ServiceExports 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.
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/v1beta1 metadata: name: internal-http namespace: store spec: gatewayClassName: gke-l7-rilb-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
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.
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/v1beta1 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 HTTPenv: canary
dirutekan ke Podstore
di clustergke-west-1
- Permintaan internal ke
store.example.internal
dengan header HTTPenv: canary
dirutekan ke Podstore
di clustergke-west-2
Validasi bahwa HTTPRoute berfungsi baik dengan mengirimkan traffic ke alamat IP Gateway.
- Permintaan internal ke
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.
Kirim permintaan ke Gateway menggunakan header HTTP
env: canary
. Tindakan ini akan mengonfirmasi bahwa traffic dirutekan kegke-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.
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/v1beta1 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
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 di langkah berikutnya.curl -H "host: store.example.internal" http://VIP/mirror
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.
Periksa log aplikasi untuk Pod
store
di clustergke-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
Output ini mengonfirmasi bahwa Pod di cluster
gke-west-2
juga menerima permintaan yang sama, tetapi responsnya terhadap permintaan tersebut tidak dikirim kembali ke 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.
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/v1beta1 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
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.
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/v1beta1 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
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.
Men-deploy load balancing berbasis kapasitas
Latihan di bagian ini menunjukkan konsep load balancing dan kapasitas Service secara global dengan men-deploy aplikasi di dua cluster GKE di region berbeda. Traffic yang dihasilkan dikirim di berbagai tingkat permintaan per detik (RPS) untuk menunjukkan cara menyeimbangkan traffic di seluruh cluster dan region.
Diagram berikut menunjukkan topologi yang akan Anda deploy dan bagaimana traffic melakukan overflow antara cluster dan region ketika traffic telah melebihi kapasitas Service:
Untuk mempelajari pengelolaan traffic lebih lanjut, baca artikel Pengelolaan traffic GKE.
Menyiapkan lingkungan Anda
Ikuti Mengaktifkan Gateway multi-cluster untuk menyiapkan lingkungan Anda.
Pastikan resource GatewayClass sudah diinstal di cluster konfigurasi:
kubectl get gatewayclasses --context=gke-west-1
Output-nya mirip dengan berikut ini:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-global-external-managed-mc networking.gke.io/gateway True 14h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-gxlb-mc networking.gke.io/gateway True 14h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed-mc networking.gke.io/gateway True 14h gke-l7-rilb networking.gke.io/gateway True 16h gke-l7-rilb-mc networking.gke.io/gateway True 14h
Men-deploy aplikasi
Deploy contoh server aplikasi web ke kedua cluster:
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
Output-nya mirip dengan berikut ini:
namespace/store created
deployment.apps/store created
Men-deploy Service, Gateway, dan HTTPRoute
Terapkan manifes
Service
berikut ke clustergke-west-1
dangke-east-1
:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
Layanan dianotasi dengan
max-rate-per-endpoint
yang ditetapkan ke 10 permintaan per detik. Dengan 2 replika per cluster, setiap Layanan memiliki kapasitas 20 RPS per cluster.Untuk mengetahui informasi selengkapnya tentang cara memilih tingkat kapasitas Service untuk Service Anda, lihat Menentukan kapasitas Service.
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/v1beta1 metadata: name: store namespace: traffic-test spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Manifes menjelaskan Gateway eksternal multi-cluster yang men-deploy Load Balancer Aplikasi eksternal dengan alamat IP yang dapat diakses publik.
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/v1beta1 metadata: name: store namespace: traffic-test labels: gateway: store spec: parentRefs: - kind: Gateway namespace: traffic-test name: store rules: - backendRefs: - name: store group: net.gke.io kind: ServiceImport port: 8080 EOF
Manifes menjelaskan HTTPRoute yang mengonfigurasi Gateway dengan aturan perutean yang mengarahkan semua traffic ke ServiceImport penyimpanan. ServiceImport
store
mengelompokkan Pod Servicestore
di kedua cluster dan memungkinkannya ditangani oleh load balancer sebagai satu Service.Anda dapat memeriksa peristiwa Gateway setelah beberapa menit untuk melihat apakah peristiwa sudah selesai di-deploy:
kubectl describe gateway store -n traffic-test --context gke-west-1
Outputnya mirip dengan hal berikut ini:
... Status: Addresses: Type: IPAddress Value: 34.102.159.147 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 12m mc-gateway-controller traffic-test/store Normal SYNC 6m43s mc-gateway-controller traffic-test/store Normal UPDATE 5m40s (x4 over 12m) mc-gateway-controller traffic-test/store Normal SYNC 118s (x6 over 10m) mc-gateway-controller SYNC on traffic-test/store was a success
Output ini menunjukkan bahwa Gateway berhasil di-deploy. Mungkin masih perlu waktu beberapa menit hingga traffic mulai diteruskan setelah Gateway di-deploy. Catat alamat IP di output ini karena akan digunakan pada langkah berikut.
Mengonfirmasi traffic
Pastikan traffic meneruskan ke aplikasi dengan menguji alamat IP Gateway menggunakan perintah curl:
curl GATEWAY_IP_ADDRESS
Output-nya mirip dengan berikut ini:
{
"cluster_name": "gke-west-1",
"host_header": "34.117.182.69",
"pod_name": "store-54785664b5-mxstv",
"pod_name_emoji": "👳🏿",
"project_id": "project",
"timestamp": "2021-11-01T14:06:38",
"zone": "us-west1-a"
}
Output ini menampilkan metadata Pod yang menunjukkan region tempat permintaan disalurkan.
Memverifikasi traffic menggunakan pengujian beban
Untuk memastikan bahwa load balancer berfungsi, Anda dapat men-deploy generator traffic di
cluster gke-west-1
. Generator traffic akan menghasilkan traffic di berbagai
level beban untuk menunjukkan kapasitas dan kemampuan tambahan dari load
balancer. Langkah-langkah berikut menunjukkan tiga tingkat beban:
- 10 RPS, yang berada di bawah kapasitas untuk Service penyimpanan di
gke-west-1
. - 30 RPS, yang melebihi kapasitas untuk Service penyimpanan
gke-west-1
dan menyebabkan traffic mengalami overflow kegke-east-1
. - 60 RPS, yang melebihi kapasitas untuk Service di kedua cluster.
Mengonfigurasi dasbor
Dapatkan nama URLmap dasar untuk Gateway Anda:
kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
Outputnya mirip dengan hal berikut ini:
/projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
Di konsol Google Cloud , buka halaman Metrics Explorer.
Di bagian Select a metric, klik CODE: MQL.
Masukkan kueri berikut untuk mengamati metrik traffic untuk Service penyimpanan di kedua cluster Anda:
fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/backend_request_count' | filter (resource.url_map_name == 'GATEWAY_URL_MAP') | align rate(1m) | every 1m | group_by [resource.backend_scope], [value_backend_request_count_aggregate: aggregate(value.backend_request_count)]
Ganti
GATEWAY_URL_MAP
dengan nama peta URL dari langkah sebelumnya.Klik Jalankan kueri. Tunggu minimal 5 menit setelah men-deploy generator beban di bagian berikutnya agar metrik ditampilkan dalam diagram.
Menguji dengan 10 RPS
Deploy Pod ke cluster
gke-west-1
Anda:kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 10'
Ganti
GATEWAY_IP_ADDRESS
dengan alamat IP Gateway dari langkah sebelumnya.Output-nya mirip dengan yang berikut ini, dan menunjukkan bahwa generator traffic sedang mengirimkan traffic:
If you don't see a command prompt, try pressing enter.
Generator beban terus mengirimkan 10 RPS ke Gateway. Meskipun traffic berasal dari dalam region Google Cloud , load balancer memperlakukannya sebagai traffic klien yang berasal dari Pantai Barat AS. Untuk menyimulasikan keberagaman klien yang realistis, generator beban akan mengirimkan setiap permintaan HTTP sebagai koneksi TCP baru, yang berarti traffic didistribusikan di seluruh Pod backend secara lebih merata.
Generator memerlukan waktu hingga 5 menit agar dapat menghasilkan traffic untuk dasbor.
Lihat dasbor Metrics Explorer Anda. Dua baris muncul, yang menunjukkan jumlah traffic yang di-load balancing ke setiap cluster:
Anda akan melihat bahwa
us-west1-a
menerima traffic sekitar 10 RPS, sedangkanus-east1-b
tidak menerima traffic apa pun. Karena generator traffic berjalan dius-west1
, semua traffic dikirim ke Service di clustergke-west-1
.Hentikan generator beban menggunakan Ctrl+C, lalu hapus pod:
kubectl delete pod loadgen --context gke-west-1
Menguji dengan 30 RPS
Deploy generator beban lagi, tetapi kali ini dikonfigurasi untuk mengirim 30 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 30'
Generator memerlukan waktu hingga 5 menit agar dapat menghasilkan traffic untuk dasbor.
Melihat dasbor Cloud Ops Anda.
Anda akan melihat bahwa sekitar 20 RPS dikirim ke
us-west1-a
dan 10 RPS keus-east1-b
. Hal ini menunjukkan bahwa Service digke-west-1
telah digunakan sepenuhnya dan mengalami overflow 10 RPS traffic ke Service digke-east-1
.Hentikan generator beban menggunakan Ctrl+C, lalu hapus Pod:
kubectl delete pod loadgen --context gke-west-1
Menguji dengan 60 RPS
Deploy generator beban yang dikonfigurasi untuk mengirim 60 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 60'
Tunggu 5 menit, lalu lihat dasbor Cloud Ops Anda. Sekarang, dasbor seharusnya sudah menunjukkan bahwa kedua cluster menerima sekitar 30 RPS. Karena semua Service digunakan berlebihan secara global, tidak ada spillover traffic dan Service akan menyerap semua traffic semaksimal mungkin.
Hentikan generator beban menggunakan Ctrl+C, lalu hapus Pod:
kubectl delete pod loadgen --context gke-west-1
Pembersihan
Setelah menyelesaikan latihan di halaman ini, ikuti langkah berikut untuk menghapus resource dan mencegah timbulnya biaya yang tidak diinginkan pada akun Anda:
Batalkan pendaftaran cluster dari fleet jika tidak perlu didaftarkan untuk tujuan lain.
Nonaktifkan fitur
multiclusterservicediscovery
:gcloud container fleet multi-cluster-services disable
Nonaktifkan Multi Cluster Ingress:
gcloud container fleet ingress disable
Nonaktifkan API:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
Menggunakan Gateway multi-cluster dengan VPC Bersama
Gateway multi-cluster juga dapat di-deploy di lingkungan VPC Bersama, dengan topologi yang berbeda, bergantung pada kasus penggunaan.
Tabel berikut menjelaskan topologi Gateway multi-cluster yang didukung dalam lingkungan VPC Bersama:
Skenario | Project host fleet | Cluster konfigurasi | Cluster beban kerja |
---|---|---|---|
1 | Project host VPC Bersama | Project host VPC Bersama | Project host VPC Bersama |
2 | Project layanan VPC Bersama | Project layanan VPC Bersama (Sama seperti project layanan fleet) |
Project layanan VPC Bersama (Sama seperti project layanan fleet) |
Untuk membuat Gateway multi-cluster di lingkungan VPC Bersama, gunakan langkah-langkah berikut:
Ikuti langkah-langkah untuk menyiapkan Layanan multi-cluster dengan VPC Bersama
Membuat layanan dan mengekspornya ke cluster konfigurasi
Jika Anda berencana menggunakan Gateway internal multi-cluster, buat subnet khusus proxy
Membuat Gateway dan HTTPRoute eksternal atau internal multi-cluster
Setelah menyelesaikan langkah-langkah ini, Anda dapat memvalidasi deployment, bergantung pada topologi Anda.
Pemecahan masalah
Subnet khusus proxy untuk Gateway internal tidak ada
Jika peristiwa berikut muncul di Gateway internal, berarti subnet khusus proxy tidak ada untuk region tersebut. Untuk mengatasi masalah ini, deploy subnet khusus proxy.
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.
Tidak ada upstream yang sehat
Gejala:
Masalah berikut mungkin 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 berfungsi. Mungkin layanan backend Anda dalam kondisi baik, tetapi Anda mungkin perlu menyesuaikan health check.
Solusi:
Untuk mengatasi masalah ini, sesuaikan health check berdasarkan persyaratan aplikasi Anda (misalnya, /health
) menggunakan HealthCheckPolicy
.
Langkah berikutnya
- Pelajari Pengontrol gateway lebih lanjut.