Dari edge ke mesh multi-cluster: Men-deploy aplikasi yang didistribusikan secara global melalui GKE Gateway dan Cloud Service Mesh

Last reviewed 2024-06-30 UTC

Dokumen ini menunjukkan cara menyelesaikan tugas berikut:

Panduan deployment ini ditujukan untuk administrator platform. Panduan ini juga ditujukan untuk praktisi tingkat lanjut yang menjalankan Cloud Service Mesh. Petunjuk ini juga berfungsi untuk Istio di GKE.

Arsitektur

Diagram berikut menunjukkan topologi traffic masuk default mesh layanan— load balancer TCP/UDP eksternal yang mengekspos proxy gateway traffic masuk di satu cluster:

Load balancer eksternal mengarahkan klien eksternal ke mesh melalui proxy gateway traffic masuk.

Panduan deployment ini menggunakan resource Gateway Google Kubernetes Engine (GKE). Secara khusus, solusi ini menggunakan gateway multi-cluster untuk mengonfigurasi load balancing multi-region di depan beberapa cluster Autopilot yang didistribusikan di dua region.

Enkripsi TLS dari klien, load balancer, dan dari mesh.

Diagram sebelumnya menunjukkan cara data mengalir melalui skenario traffic masuk cloud dan traffic masuk mesh. Untuk informasi selengkapnya, lihat penjelasan tentang diagram arsitektur dalam dokumen arsitektur referensi terkait.

Tujuan

  • Deploy sepasang cluster GKE Autopilot di Google Cloud ke fleet yang sama.
  • Deploy Cloud Service Mesh berbasis Istio ke fleet yang sama.
  • Konfigurasikan load balancer menggunakan GKE Gateway untuk menghentikan traffic HTTPS publik.
  • Arahkan traffic HTTPS publik ke aplikasi yang dihosting oleh Cloud Service Mesh yang di-deploy di beberapa cluster dan region.
  • Deploy aplikasi contoh whereami ke kedua cluster Autopilot.

Pengoptimalan biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

  1. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Di konsol Google Cloud, aktifkan Cloud Shell.

    Aktifkan Cloud Shell

    Anda menjalankan semua perintah terminal untuk deployment ini dari Cloud Shell.

  4. Setel project Google Cloud default Anda:

    export PROJECT=YOUR_PROJECT
    export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
    gcloud config set project PROJECT_ID
    

    Ganti PROJECT_ID dengan ID project yang ingin Anda gunakan untuk deployment ini.

  5. Buat direktori kerja:

    mkdir -p ${HOME}/edge-to-mesh-multi-region
    cd ${HOME}/edge-to-mesh-multi-region
    export WORKDIR=`pwd`
    

Membuat cluster GKE

Di bagian ini, Anda akan membuat cluster GKE untuk menghosting aplikasi dan infrastruktur pendukung, yang akan Anda buat nanti dalam panduan deployment ini.

  1. Di Cloud Shell, buat file kubeconfig baru. Langkah ini memastikan Anda tidak membuat konflik dengan file kubeconfig yang sudah ada (default).

    touch edge2mesh_mr_kubeconfig
    export KUBECONFIG=${WORKDIR}/edge2mesh_mr_kubeconfig
    
  2. Tentukan variabel lingkungan yang digunakan saat membuat cluster GKE dan resource di dalamnya. Ubah pilihan region default agar sesuai dengan tujuan Anda.

    export CLUSTER_1_NAME=edge-to-mesh-01
    export CLUSTER_2_NAME=edge-to-mesh-02
    export CLUSTER_1_REGION=us-central1
    export CLUSTER_2_REGION=us-east4
    export PUBLIC_ENDPOINT=frontend.endpoints.PROJECT_ID.cloud.goog
    
  3. Aktifkan Google Cloud API yang digunakan di seluruh panduan ini:

    gcloud services enable \
      container.googleapis.com \
      mesh.googleapis.com \
      gkehub.googleapis.com \
      multiclusterservicediscovery.googleapis.com \
      multiclusteringress.googleapis.com \
      trafficdirector.googleapis.com \
      certificatemanager.googleapis.com
    
  4. Buat cluster GKE Autopilot dengan node pribadi di CLUSTER_1_REGION. Gunakan flag --async untuk menghindari menunggu cluster pertama disediakan dan terdaftar ke fleet:

    gcloud container clusters create-auto --async \
    ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} \
    --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \
    --enable-private-nodes --enable-fleet
    
  5. Buat dan daftarkan cluster Autopilot kedua di CLUSTER_2_REGION:

    gcloud container clusters create-auto \
    ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} \
    --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \
    --enable-private-nodes --enable-fleet
    
  6. Pastikan cluster berjalan. Mungkin perlu waktu hingga 20 menit hingga semua cluster berjalan:

    gcloud container clusters list
    

    Outputnya mirip dengan hal berikut ini:

    NAME             LOCATION     MASTER_VERSION  MASTER_IP       MACHINE_TYPE  NODE_VERSION    NUM_NODES  STATUS
    edge-to-mesh-01  us-central1  1.27.5-gke.200  34.27.171.241   e2-small      1.27.5-gke.200             RUNNING
    edge-to-mesh-02  us-east4     1.27.5-gke.200  35.236.204.156  e2-small      1.27.5-gke.200             RUNNING
    
  7. Kumpulkan kredensial untuk CLUSTER_1_NAME.Anda membuat CLUSTER_1_NAME secara asinkron sehingga dapat menjalankan perintah tambahan saat cluster disediakan.

    gcloud container clusters get-credentials ${CLUSTER_1_NAME} \
        --region ${CLUSTER_1_REGION}
    
  8. Untuk memperjelas nama konteks Kubernetes, ganti namanya menjadi nama cluster:

    kubectl config rename-context gke_PROJECT_ID_${CLUSTER_1_REGION}_${CLUSTER_1_NAME} ${CLUSTER_1_NAME}
    kubectl config rename-context gke_PROJECT_ID_${CLUSTER_2_REGION}_${CLUSTER_2_NAME} ${CLUSTER_2_NAME}
    

Menginstal mesh layanan

Di bagian ini, Anda akan mengonfigurasi Cloud Service Mesh terkelola dengan fleet API. Menggunakan fleet API untuk mengaktifkan Cloud Service Mesh memberikan pendekatan deklaratif untuk menyediakan mesh layanan.

  1. Di Cloud Shell, aktifkan Cloud Service Mesh di fleet:

    gcloud container fleet mesh enable
    
  2. Mengaktifkan pengelolaan bidang kontrol dan bidang data otomatis:

    gcloud container fleet mesh update \
      --management automatic \
      --memberships ${CLUSTER_1_NAME},${CLUSTER_2_NAME}
    
  3. Tunggu sekitar 20 menit. Kemudian, verifikasi bahwa status bidang kontrol adalah ACTIVE:

    gcloud container fleet mesh describe
    

    Outputnya mirip dengan hal berikut ini:

    createTime: '2023-11-30T19:23:21.713028916Z'
    membershipSpecs:
      projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01:
        mesh:
          management: MANAGEMENT_AUTOMATIC
      projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02:
        mesh:
          management: MANAGEMENT_AUTOMATIC
    membershipStates:
      projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01:
        servicemesh:
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed-rapid'
            implementation: ISTIOD
            state: ACTIVE
          dataPlaneManagement:
            details:
            - code: OK
              details: Service is running.
            state: ACTIVE
        state:
         code: OK
          description: |-
            Revision ready for use: asm-managed-rapid.
            All Canonical Services have been reconciled successfully.
          updateTime: '2024-06-27T09:00:21.333579005Z'
      projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02:
        servicemesh:
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed-rapid'
            implementation: ISTIOD
            state: ACTIVE
          dataPlaneManagement:
            details:
            - code: OK
              details: Service is running.
            state: ACTIVE
        state:
          code: OK
          description: |-
            Revision ready for use: asm-managed-rapid.
            All Canonical Services have been reconciled successfully.
          updateTime: '2024-06-27T09:00:24.674852751Z'
    name: projects/e2m-private-test-01/locations/global/features/servicemesh
    resourceState:
      state: ACTIVE
    spec: {}
    updateTime: '2024-06-04T17:16:28.730429993Z'
    

Men-deploy Load Balancer Aplikasi eksternal dan membuat gateway ingress

Di bagian ini, Anda akan men-deploy Load Balancer Aplikasi eksternal melalui pengontrol GKE Gateway dan membuat gateway ingress untuk kedua cluster. Resource gateway dan gatewayClass mengotomatiskan penyediaan load balancer dan pemeriksaan kondisi backend. Untuk menyediakan penghentian TLS di load balancer, Anda membuat resource Certificate Manager dan melampirkan resource tersebut ke load balancer. Selain itu, Anda menggunakan Endpoints untuk menyediakan nama DNS publik untuk aplikasi secara otomatis.

Menginstal gateway traffic masuk di kedua cluster

Sebagai praktik terbaik keamanan, sebaiknya Anda men-deploy gateway traffic masuk di namespace yang berbeda dari bidang kontrol mesh.

  1. Di Cloud Shell, buat namespace asm-ingress khusus di setiap cluster:

    kubectl --context=${CLUSTER_1_NAME} create namespace asm-ingress
    kubectl --context=${CLUSTER_2_NAME} create namespace asm-ingress
    
  2. Tambahkan label namespace ke namespace asm-ingress:

    kubectl --context=${CLUSTER_1_NAME} label namespace asm-ingress istio-injection=enabled
    kubectl --context=${CLUSTER_2_NAME} label namespace asm-ingress istio-injection=enabled
    

    Outputnya mirip dengan hal berikut ini:

    namespace/asm-ingress labeled
    

    Pelabelan namespace asm-ingress dengan istio-injection=enabled akan memerintahkan Cloud Service Mesh untuk otomatis memasukkan proxy sidecar Envoy saat pod di-deploy.

  3. Buat sertifikat yang ditandatangani sendiri untuk penggunaan mendatang:

    openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
     -subj "/CN=frontend.endpoints.PROJECT_ID.cloud.goog/O=Edge2Mesh Inc" \
     -keyout ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \
     -out ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
    

    Sertifikat ini memberikan lapisan enkripsi tambahan antara load balancer dan gateway ingress mesh layanan. Hal ini juga memungkinkan dukungan untuk protokol berbasis HTTP/2 seperti gRPC. Petunjuk tentang cara melampirkan sertifikat yang ditandatangani sendiri ke gateway ingress akan diberikan nanti di Membuat resource alamat IP eksternal, data DNS, dan sertifikat TLS.

    Untuk mengetahui informasi selengkapnya tentang persyaratan sertifikat gateway traffic masuk, lihat Enkripsi dari load balancer ke backend.

  4. Buat secret Kubernetes di setiap cluster untuk menyimpan sertifikat yang ditandatangani sendiri:

    kubectl --context ${CLUSTER_1_NAME} -n asm-ingress create secret tls \
     edge2mesh-credential \
     --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \
     --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
    kubectl --context ${CLUSTER_2_NAME} -n asm-ingress create secret tls \
     edge2mesh-credential \
     --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \
     --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
    
  5. Untuk berintegrasi dengan Load Balancer Aplikasi eksternal, buat varian kustomize untuk mengonfigurasi resource gateway traffic masuk:

    mkdir -p ${WORKDIR}/asm-ig/base
    
    cat <<EOF > ${WORKDIR}/asm-ig/base/kustomization.yaml
    resources:
      - github.com/GoogleCloudPlatform/anthos-service-mesh-samples/docs/ingress-gateway-asm-manifests/base
    EOF
    
    mkdir ${WORKDIR}/asm-ig/variant
    
    cat <<EOF > ${WORKDIR}/asm-ig/variant/role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    EOF
    
    cat <<EOF > ${WORKDIR}/asm-ig/variant/rolebinding.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: asm-ingressgateway
    subjects:
      - kind: ServiceAccount
        name: asm-ingressgateway
    EOF
    
    cat <<EOF > ${WORKDIR}/asm-ig/variant/service-proto-type.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      ports:
      - name: status-port
        port: 15021
        protocol: TCP
        targetPort: 15021
      - name: http
        port: 80
        targetPort: 8080
        appProtocol: HTTP
      - name: https
        port: 443
        targetPort: 8443
        appProtocol: HTTP2
      type: ClusterIP
    EOF
    
    cat <<EOF > ${WORKDIR}/asm-ig/variant/gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
     servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        hosts:
        - "*" # IMPORTANT: Must use wildcard here when using SSL, as SNI isn't passed from GFE
        tls:
          mode: SIMPLE
          credentialName: edge2mesh-credential
    EOF
    
    cat <<EOF > ${WORKDIR}/asm-ig/variant/kustomization.yaml
    namespace: asm-ingress
    resources:
    - ../base
    - role.yaml
    - rolebinding.yaml
    patches:
    - path: service-proto-type.yaml
      target:
        kind: Service
    - path: gateway.yaml
      target:
        kind: Gateway
    EOF
    
  6. Terapkan konfigurasi gateway ingress ke kedua cluster:

    kubectl --context ${CLUSTER_1_NAME} apply -k ${WORKDIR}/asm-ig/variant
    kubectl --context ${CLUSTER_2_NAME} apply -k ${WORKDIR}/asm-ig/variant
    

Mengekspos pod gateway ingress ke load balancer menggunakan layanan multi-cluster

Di bagian ini, Anda akan mengekspor pod gateway ingress melalui resource kustom ServiceExport. Anda harus mengekspor pod gateway masuk melalui resource kustom ServiceExport karena alasan berikut:

  1. Di Cloud Shell, aktifkan Layanan multi-cluster (MCS) untuk fleet:

    gcloud container fleet multi-cluster-services enable
    
  2. Berikan izin IAM yang diperlukan ke project atau fleet MCS:

    gcloud projects add-iam-policy-binding PROJECT_ID \
     --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer]" \
     --role "roles/compute.networkViewer"
    
  3. Buat file YAML ServiceExport:

    cat <<EOF > ${WORKDIR}/svc_export.yaml
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    EOF
    
  4. Terapkan file YAML ServiceExport ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/svc_export.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/svc_export.yaml
    

    Jika Anda menerima pesan error berikut, tunggu beberapa saat hingga definisi resource kustom (CRD) MCS diinstal. Kemudian, jalankan kembali perintah untuk menerapkan file YAML ServiceExport ke kedua cluster.

    error: resource mapping not found for name: "asm-ingressgateway" namespace: "asm-ingress" from "svc_export.yaml": no matches for kind "ServiceExport" in version "net.gke.io/v1"
    ensure CRDs are installed first
    

Membuat resource alamat IP eksternal, data DNS, dan sertifikat TLS

Di bagian ini, Anda akan membuat resource jaringan yang mendukung resource load balancing yang akan Anda buat nanti dalam deployment ini.

  1. Di Cloud Shell, cadangkan alamat IP eksternal statis:

    gcloud compute addresses create mcg-ip --global
    

    Alamat IP statis digunakan oleh resource GKE Gateway. Hal ini memungkinkan alamat IP tetap sama, meskipun load balancer eksternal dibuat ulang.

  2. Dapatkan alamat IP statis dan simpan sebagai variabel lingkungan:

    export MCG_IP=$(gcloud compute addresses describe mcg-ip --global --format "value(address)")
    echo ${MCG_IP}
    

    Untuk membuat pemetaan yang stabil dan mudah dipahami ke alamat IP Gateway, Anda harus memiliki data DNS publik.

    Anda dapat menggunakan penyedia DNS dan skema otomatisasi yang Anda inginkan. Deployment ini menggunakan Endpoint, bukan membuat zona DNS terkelola. Endpoint menyediakan data DNS yang dikelola Google gratis untuk alamat IP eksternal.

  3. Jalankan perintah berikut untuk membuat file YAML bernama dns-spec.yaml:

    cat <<EOF > ${WORKDIR}/dns-spec.yaml
    swagger: "2.0"
    info:
      description: "Cloud Endpoints DNS"
      title: "Cloud Endpoints DNS"
      version: "1.0.0"
    paths: {}
    host: "frontend.endpoints.PROJECT_ID.cloud.goog"
    x-google-endpoints:
    - name: "frontend.endpoints.PROJECT_ID.cloud.goog"
      target: "${MCG_IP}"
    EOF
    

    File dns-spec.yaml menentukan data DNS publik dalam bentuk frontend.endpoints.PROJECT_ID.cloud.goog, dengan PROJECT_ID sebagai ID project unik Anda.

  4. Deploy file dns-spec.yaml untuk membuat entri DNS. Proses ini memerlukan waktu beberapa menit.

    gcloud endpoints services deploy ${WORKDIR}/dns-spec.yaml
    
  5. Buat sertifikat menggunakan Pengelola Sertifikat untuk nama entri DNS yang Anda buat di langkah sebelumnya:

    gcloud certificate-manager certificates create mcg-cert \
        --domains="frontend.endpoints.PROJECT_ID.cloud.goog"
    

    Sertifikat TLS yang dikelola Google digunakan untuk menghentikan permintaan klien masuk di load balancer.

  6. Buat peta sertifikat:

    gcloud certificate-manager maps create mcg-cert-map
    

    Load balancer mereferensikan sertifikat melalui entri peta sertifikat yang Anda buat di langkah berikutnya.

  7. Buat entri peta sertifikat untuk sertifikat yang Anda buat sebelumnya di bagian ini:

    gcloud certificate-manager maps entries create mcg-cert-map-entry \
        --map="mcg-cert-map" \
        --certificates="mcg-cert" \
        --hostname="frontend.endpoints.PROJECT_ID.cloud.goog"
    

Membuat kebijakan layanan backend dan resource load balancer

Di bagian ini, Anda akan menyelesaikan tugas berikut:

  • Buat kebijakan keamanan Google Cloud Armor dengan aturan.
  • Buat kebijakan yang memungkinkan load balancer memeriksa responsivitas pod gateway masuk melalui file YAML ServiceExport yang Anda buat sebelumnya.
  • Gunakan GKE Gateway API untuk membuat resource load balancer.
  • Gunakan resource kustom GatewayClass untuk menetapkan jenis load balancer tertentu.
  • Aktifkan load balancing multi-cluster untuk fleet dan tetapkan salah satu cluster sebagai cluster konfigurasi untuk fleet.
  1. Di Cloud Shell, buat kebijakan keamanan Google Cloud Armor:

    gcloud compute security-policies create edge-fw-policy \
        --description "Block XSS attacks"
    
  2. Buat aturan untuk kebijakan keamanan:

    gcloud compute security-policies rules create 1000 \
        --security-policy edge-fw-policy \
        --expression "evaluatePreconfiguredExpr('xss-stable')" \
        --action "deny-403" \
        --description "XSS attack filtering"
    
  3. Buat file YAML untuk kebijakan keamanan, dan referensikan file YAML ServiceExport melalui file YAML ServiceImport yang sesuai:

    cat <<EOF > ${WORKDIR}/cloud-armor-backendpolicy.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPBackendPolicy
    metadata:
      name: cloud-armor-backendpolicy
      namespace: asm-ingress
    spec:
      default:
        securityPolicy: edge-fw-policy
      targetRef:
        group: net.gke.io
        kind: ServiceImport
        name: asm-ingressgateway
    EOF
    
  4. Terapkan kebijakan Google Cloud Armor ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
    
  5. Buat file YAML kustom yang memungkinkan load balancer melakukan health check terhadap endpoint kesehatan Envoy (port 15021 di jalur /healthz/ready) dari pod gateway ingress di kedua cluster:

    cat <<EOF > ${WORKDIR}/ingress-gateway-healthcheck.yaml
    apiVersion: networking.gke.io/v1
    kind: HealthCheckPolicy
    metadata:
      name: ingress-gateway-healthcheck
      namespace: asm-ingress
    spec:
      default:
        config:
          httpHealthCheck:
            port: 15021
            portSpecification: USE_FIXED_PORT
            requestPath: /healthz/ready
          type: HTTP
      targetRef:
        group: net.gke.io
        kind: ServiceImport
        name: asm-ingressgateway
    EOF
    
  6. Terapkan file YAML kustom yang Anda buat di langkah sebelumnya ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
    
  7. Aktifkan load balancing multi-cluster untuk fleet, dan tetapkan CLUSTER_1_NAME sebagai cluster konfigurasi:

    gcloud container fleet ingress enable \
      --config-membership=${CLUSTER_1_NAME} \
      --location=${CLUSTER_1_REGION}
    
  8. Berikan izin IAM untuk pengontrol Gateway di fleet:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-multiclusteringress." \
        --role "roles/container.admin"
    
  9. Buat file YAML load balancer melalui resource kustom Gateway yang mereferensikan gke-l7-global-external-managed-mc gatewayClass dan alamat IP statis yang Anda buat sebelumnya:

    cat <<EOF > ${WORKDIR}/frontend-gateway.yaml
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      namespace: asm-ingress
      annotations:
        networking.gke.io/certmap: mcg-cert-map
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http # list the port only so we can redirect any incoming http requests to https
        protocol: HTTP
        port: 80
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
      addresses:
      - type: NamedAddress
        value: mcg-ip
    EOF
    
  10. Terapkan file YAML frontend-gateway ke kedua cluster. Hanya CLUSTER_1_NAME yang kredibel, kecuali jika Anda menetapkan cluster konfigurasi yang berbeda sebagai kredibel:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml
    
  11. Buat file YAML HTTPRoute bernama default-httproute.yaml yang menginstruksikan resource Gateway untuk mengirim permintaan ke gateway ingress:

    cat << EOF > ${WORKDIR}/default-httproute.yaml
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: default-httproute
      namespace: asm-ingress
    spec:
      parentRefs:
      - name: external-http
        namespace: asm-ingress
        sectionName: https
      rules:
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: asm-ingressgateway
          port: 443
    EOF
    
  12. Terapkan file YAML HTTPRoute yang Anda buat di langkah sebelumnya ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute.yaml
    
  13. Untuk melakukan pengalihan HTTP ke HTTP(S), buat file YAML HTTPRoute tambahan yang disebut default-httproute-redirect.yaml:

    cat << EOF > ${WORKDIR}/default-httproute-redirect.yaml
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: http-to-https-redirect-httproute
      namespace: asm-ingress
    spec:
      parentRefs:
      - name: external-http
        namespace: asm-ingress
        sectionName: http
      rules:
      - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 301
    EOF
    
  14. Terapkan file YAML HTTPRoute pengalihan ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml
    
  15. Periksa resource Gateway untuk memeriksa progres deployment load balancer:

    kubectl --context=${CLUSTER_1_NAME} describe gateway external-http -n asm-ingress
    

    Output akan menampilkan informasi yang Anda masukkan di bagian ini.

Men-deploy aplikasi contoh whereami

Panduan ini menggunakan whereami sebagai aplikasi contoh untuk memberikan masukan langsung tentang cluster mana yang merespons permintaan. Bagian berikut menyiapkan dua deployment whereami terpisah di kedua cluster: deployment frontend dan deployment backend.

Deployment frontend adalah beban kerja pertama yang menerima permintaan. Kemudian, deployment backend akan dipanggil.

Model ini digunakan untuk mendemonstrasikan arsitektur aplikasi multi-layanan. Layanan frontend dan backend di-deploy ke kedua cluster.

  1. Di Cloud Shell, buat namespace untuk frontend whereami dan backend whereami di kedua cluster dan aktifkan injeksi namespace:

    kubectl --context=${CLUSTER_1_NAME} create ns frontend
    kubectl --context=${CLUSTER_1_NAME} label namespace frontend istio-injection=enabled
    kubectl --context=${CLUSTER_1_NAME} create ns backend
    kubectl --context=${CLUSTER_1_NAME} label namespace backend istio-injection=enabled
    kubectl --context=${CLUSTER_2_NAME} create ns frontend
    kubectl --context=${CLUSTER_2_NAME} label namespace frontend istio-injection=enabled
    kubectl --context=${CLUSTER_2_NAME} create ns backend
    kubectl --context=${CLUSTER_2_NAME} label namespace backend istio-injection=enabled
    
  2. Buat varian kustomisasi untuk backend whereami:

    mkdir -p ${WORKDIR}/whereami-backend/base
    
    cat <<EOF > ${WORKDIR}/whereami-backend/base/kustomization.yaml
    resources:
      - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s
    EOF
    
    mkdir ${WORKDIR}/whereami-backend/variant
    
    cat <<EOF > ${WORKDIR}/whereami-backend/variant/cm-flag.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: whereami
    data:
      BACKEND_ENABLED: "False" # assuming you don't want a chain of backend calls
      METADATA:        "backend"
    EOF
    
    cat <<EOF > ${WORKDIR}/whereami-backend/variant/service-type.yaml
    apiVersion: "v1"
    kind: "Service"
    metadata:
      name: "whereami"
    spec:
      type: ClusterIP
    EOF
    
    cat <<EOF > ${WORKDIR}/whereami-backend/variant/kustomization.yaml
    nameSuffix: "-backend"
    namespace: backend
    commonLabels:
      app: whereami-backend
    resources:
    - ../base
    patches:
    - path: cm-flag.yaml
      target:
        kind: ConfigMap
    - path: service-type.yaml
      target:
        kind: Service
    EOF
    
  3. Terapkan varian backend whereami ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-backend/variant
    kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-backend/variant
    
  4. Buat varian kustomisasi untuk frontend whereami:

    mkdir -p ${WORKDIR}/whereami-frontend/base
    
    cat <<EOF > ${WORKDIR}/whereami-frontend/base/kustomization.yaml
    resources:
      - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s
    EOF
    
    mkdir whereami-frontend/variant
    
    cat <<EOF > ${WORKDIR}/whereami-frontend/variant/cm-flag.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: whereami
    data:
      BACKEND_ENABLED: "True"
      BACKEND_SERVICE: "http://whereami-backend.backend.svc.cluster.local"
    EOF
    
    cat <<EOF > ${WORKDIR}/whereami-frontend/variant/service-type.yaml
    apiVersion: "v1"
    kind: "Service"
    metadata:
      name: "whereami"
    spec:
      type: ClusterIP
    EOF
    
    cat <<EOF > ${WORKDIR}/whereami-frontend/variant/kustomization.yaml
    nameSuffix: "-frontend"
    namespace: frontend
    commonLabels:
      app: whereami-frontend
    resources:
    - ../base
    patches:
    - path: cm-flag.yaml
      target:
        kind: ConfigMap
    - path: service-type.yaml
      target:
        kind: Service
    EOF
    
  5. Terapkan varian frontend whereami ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-frontend/variant
    kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-frontend/variant
    
  6. Buat file YAML VirtualService untuk merutekan permintaan ke frontend whereami:

    cat << EOF > ${WORKDIR}/frontend-vs.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: whereami-vs
      namespace: frontend
    spec:
      gateways:
      - asm-ingress/asm-ingressgateway
      hosts:
      - 'frontend.endpoints.PROJECT_ID.cloud.goog'
      http:
      - route:
        - destination:
            host: whereami-frontend
            port:
              number: 80
    EOF
    
  7. Terapkan file YAML frontend-vs ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-vs.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-vs.yaml
    
  8. Setelah men-deploy frontend-vs.yaml ke kedua cluster, coba panggil endpoint publik untuk cluster Anda:

    curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq
    

    Outputnya mirip dengan hal berikut ini:

    {
      "backend_result": {
        "cluster_name": "edge-to-mesh-02",
        "gce_instance_id": "8396338201253702608",
        "gce_service_account": "e2m-mcg-01.svc.id.goog",
        "host_header": "whereami-backend.backend.svc.cluster.local",
        "metadata": "backend",
        "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-645h",
        "pod_ip": "10.124.0.199",
        "pod_name": "whereami-backend-7cbdfd788-8mmnq",
        "pod_name_emoji": "📸",
        "pod_namespace": "backend",
        "pod_service_account": "whereami-backend",
        "project_id": "e2m-mcg-01",
        "timestamp": "2023-12-01T03:46:24",
        "zone": "us-east4-b"
      },
      "cluster_name": "edge-to-mesh-01",
      "gce_instance_id": "1047264075324910451",
      "gce_service_account": "e2m-mcg-01.svc.id.goog",
      "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog",
      "metadata": "frontend",
      "node_name": "gk3-edge-to-mesh-01-pool-2-d687e3c0-5kf2",
      "pod_ip": "10.54.1.71",
      "pod_name": "whereami-frontend-69c4c867cb-dgg8t",
      "pod_name_emoji": "🪴",
      "pod_namespace": "frontend",
      "pod_service_account": "whereami-frontend",
      "project_id": "e2m-mcg-01",
      "timestamp": "2023-12-01T03:46:24",
      "zone": "us-central1-c"
    }
    

Jika menjalankan perintah curl beberapa kali, Anda akan melihat bahwa respons (baik dari frontend maupun backend) berasal dari region yang berbeda. Dalam responsnya, load balancer menyediakan perutean geografis. Artinya, load balancer merutekan permintaan dari klien ke cluster aktif terdekat, tetapi permintaan masih diarahkan secara acak. Jika permintaan terkadang berpindah dari satu region ke region lain, hal ini akan meningkatkan latensi dan biaya.

Di bagian berikutnya, Anda akan menerapkan load balancing lokalitas di mesh layanan agar permintaan tetap bersifat lokal.

Mengaktifkan dan menguji load balancing lokalitas untuk whereami

Di bagian ini, Anda akan menerapkan load balancing lokalitas di mesh layanan agar permintaan tetap bersifat lokal. Anda juga melakukan beberapa pengujian untuk melihat cara whereami menangani berbagai skenario kegagalan.

Saat Anda membuat permintaan ke layanan frontend whereami, load balancer akan mengirim permintaan ke cluster dengan latensi terendah dibandingkan dengan klien. Artinya, pod gateway ingress dalam permintaan load balance mesh ke pod frontend whereami di kedua cluster. Bagian ini akan mengatasi masalah tersebut dengan mengaktifkan load balancing lokalitas dalam mesh.

  1. Di Cloud Shell, buat file YAML DestinationRule yang mengaktifkan failover regional load balancing lokalitas ke layanan frontend:

    cat << EOF > ${WORKDIR}/frontend-dr.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: frontend
      namespace: frontend
    spec:
      host: whereami-frontend.frontend.svc.cluster.local
      trafficPolicy:
        connectionPool:
          http:
            maxRequestsPerConnection: 0
        loadBalancer:
          simple: LEAST_REQUEST
          localityLbSetting:
            enabled: true
        outlierDetection:
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 1m
    EOF
    

    Contoh kode sebelumnya hanya mengaktifkan pemilihan rute lokal untuk layanan frontend. Anda juga memerlukan konfigurasi tambahan yang menangani backend.

  2. Terapkan file YAML frontend-dr ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-dr.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-dr.yaml
    
  3. Buat file YAML DestinationRule yang memungkinkan load balancing lokalitas untuk failover regional ke layanan backend:

    cat << EOF > ${WORKDIR}/backend-dr.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
    n    ame: backend
      namespace: backend
    spec:
      host: whereami-backend.backend.svc.cluster.local
      trafficPolicy:
        connectionPool:
          http:
            maxRequestsPerConnection: 0
        loadBalancer:
          simple: LEAST_REQUEST
          localityLbSetting:
            enabled: true
        outlierDetection:
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 1m
    EOF
    
  4. Terapkan file YAML backend-dr ke kedua cluster:

    kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/backend-dr.yaml
    kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/backend-dr.yaml
    

    Dengan kedua kumpulan file YAML DestinationRule yang diterapkan ke kedua cluster, permintaan tetap bersifat lokal untuk cluster tempat permintaan dirutekan.

    Untuk menguji failover layanan frontend, kurangi jumlah replika untuk gateway masuk di cluster utama Anda.

    Dari perspektif load balancer multi-regional, tindakan ini menyimulasikan kegagalan cluster. Hal ini menyebabkan cluster tersebut gagal dalam health check load balancer. Contoh ini menggunakan cluster di CLUSTER_1_REGION. Anda hanya akan melihat respons dari cluster di CLUSTER_2_REGION.

  5. Kurangi jumlah replika untuk gateway ingress di cluster utama Anda menjadi nol dan panggil endpoint publik untuk memverifikasi bahwa permintaan telah gagal ditransfer ke cluster lain:

    kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=0 deployment/asm-ingressgateway
    

    Output akan terlihat seperti berikut:

    $ curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq
    {
      "backend_result": {
        "cluster_name": "edge-to-mesh-02",
        "gce_instance_id": "2717459599837162415",
        "gce_service_account": "e2m-mcg-01.svc.id.goog",
        "host_header": "whereami-backend.backend.svc.cluster.local",
        "metadata": "backend",
        "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-dxs2",
        "pod_ip": "10.124.1.7",
        "pod_name": "whereami-backend-7cbdfd788-mp8zv",
        "pod_name_emoji": "🏌🏽‍♀",
        "pod_namespace": "backend",
        "pod_service_account": "whereami-backend",
        "project_id": "e2m-mcg-01",
        "timestamp": "2023-12-01T05:41:18",
        "zone": "us-east4-b"
      },
      "cluster_name": "edge-to-mesh-02",
      "gce_instance_id": "6983018919754001204",
      "gce_service_account": "e2m-mcg-01.svc.id.goog",
      "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog",
      "metadata": "frontend",
      "node_name": "gk3-edge-to-mesh-02-pool-3-d42ddfbf-qmkn",
      "pod_ip": "10.124.1.142",
      "pod_name": "whereami-frontend-69c4c867cb-xf8db",
      "pod_name_emoji": "🏴",
      "pod_namespace": "frontend",
      "pod_service_account": "whereami-frontend",
      "project_id": "e2m-mcg-01",
      "timestamp": "2023-12-01T05:41:18",
      "zone": "us-east4-b"
    }
    
  6. Untuk melanjutkan pemilihan rute traffic standar, pulihkan replika gateway masuk ke nilai asli di cluster:

    kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=3 deployment/asm-ingressgateway
    
  7. Simulasikan kegagalan untuk layanan backend, dengan mengurangi jumlah replika di region utama menjadi 0:

    kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=0 deployment/whereami-backend
    

    Verifikasi bahwa respons dari layanan frontend berasal dari region utama us-central1 melalui load balancer, dan respons dari layanan backend berasal dari region sekunder us-east4.

    Output juga harus menyertakan respons untuk layanan frontend dari region utama (us-central1), dan respons untuk layanan backend dari region sekunder (us-east4), seperti yang diharapkan.

  8. Pulihkan replika layanan backend ke nilai asli untuk melanjutkan rute traffic standar:

    kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=3 deployment/whereami-backend
    

Sekarang Anda memiliki load balancer HTTP(S) global yang berfungsi sebagai frontend untuk aplikasi multi-region yang dihosting di mesh layanan.

Pembersihan

Agar tidak dikenai biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam deployment ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus resource satu per satu

Jika ingin mempertahankan project Google Cloud yang Anda gunakan dalam deployment ini, hapus masing-masing resource:

  1. Di Cloud Shell, hapus resource HTTPRoute:

    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml
    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute.yaml
    
  2. Hapus resource GKE Gateway:

    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml
    
  3. Hapus kebijakan:

    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
    
  4. Hapus ekspor layanan:

    kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/svc_export.yaml
    kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/svc_export.yaml
    
  5. Hapus resource Google Cloud Armor:

    gcloud --project=PROJECT_ID compute security-policies rules delete 1000 --security-policy edge-fw-policy --quiet
    gcloud --project=PROJECT_ID compute security-policies delete edge-fw-policy --quiet
    
  6. Hapus resource Pengelola Sertifikat:

    gcloud --project=PROJECT_ID certificate-manager maps entries delete mcg-cert-map-entry --map="mcg-cert-map" --quiet
    gcloud --project=PROJECT_ID certificate-manager maps delete mcg-cert-map --quiet
    gcloud --project=PROJECT_ID certificate-manager certificates delete mcg-cert --quiet
    
  7. Hapus entri DNS Endpoint:

    gcloud --project=PROJECT_ID endpoints services delete "frontend.endpoints.PROJECT_ID.cloud.goog" --quiet
    
  8. Hapus alamat IP statis:

    gcloud --project=PROJECT_ID compute addresses delete mcg-ip --global --quiet
    
  9. Hapus cluster GKE Autopilot. Langkah ini memerlukan waktu beberapa menit.

    gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} --quiet
    gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} --quiet
    

Langkah selanjutnya

Kontributor

Penulis:

Kontributor lainnya: