Mengonfigurasi pembatasan frekuensi Google Cloud Armor dengan Envoy

Halaman ini menunjukkan cara mengonfigurasi pembatasan frekuensi sisi server global untuk mesh layanan Anda menggunakan Cloud Armor. Anda dapat menggunakan fitur ini untuk menerapkan pembatasan laju pembagian yang adil ke semua traffic yang masuk ke layanan Anda, sehingga membantu Anda membagikan kapasitas layanan yang tersedia secara adil dan memitigasi risiko klien yang berbahaya atau berperilaku buruk membebani layanan Anda secara berlebihan. Untuk mengetahui informasi selengkapnya tentang pembatasan kecepatan, baca ringkasan pembatasan kecepatan.

Mengonfigurasi Google Kubernetes Engine (GKE) untuk Envoy

Sebelum memulai

Sebelum memulai, Anda harus mengaktifkan API berikut:

  • container.googleapis.com
  • compute.googleapis.com
  • trafficdirector.googleapis.com
  • networkservices.googleapis.com
  • meshconfig.googleapis.com
  • monitoring.googleapis.com

Anda dapat mengaktifkan semua API menggunakan perintah Google Cloud CLI berikut:

gcloud services enable \
    container.googleapis.com \
    compute.googleapis.com \
    trafficdirector.googleapis.com \
    networkservices.googleapis.com \
    meshconfig.googleapis.com \
    monitoring.googleapis.com

Kemudian, buat variabel lingkungan yang digunakan dalam dokumen ini:

export PROJECT_ID=PROJECT_ID
export PROJECT_NUMBER="$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")"
export CLUSTER=CLUSTER
export ZONE=ZONE
export MESH_NAME=MESH_NAME
export MESH_URI=projects/${PROJECT_NUMBER}/locations/global/meshes/${MESH_NAME}

Ganti variabel berikut dengan informasi dari project Anda:

  • Ganti PROJECT_ID dengan project ID Anda
  • Ganti ZONE dengan zona tempat Anda ingin membuat cluster GKE
  • Ganti CLUSTER dengan nama cluster
  • Ganti MESH_NAME dengan nama mesh

Membuat cluster GKE

  1. Gunakan perintah berikut untuk membuat cluster GKE di zona yang Anda tentukan di bagian sebelumnya:

     gcloud container clusters create "CLUSTER" \
         --zone="ZONE" \
         --scopes="cloud-platform" \
         --tags="allow-envoy-health-checks" \
         --enable-ip-alias
    
  2. Dapatkan kredensial cluster baru Anda:

     gcloud container clusters get-credentials "CLUSTER" \
         --zone="ZONE"
    

Mengaktifkan penyisipan otomatis

  1. Gunakan perintah berikut untuk menerapkan resource MutatingWebhookConfiguration ke cluster Anda. Saat Pod dibuat, pengontrol penerimaan dalam cluster dipanggil, dan pengontrol tersebut menginstruksikan injector sidecar terkelola untuk menambahkan penampung Envoy ke Pod.

    cat <<EOF | kubectl apply -f -
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
     labels:
       app: sidecar-injector
     name: td-mutating-webhook
    webhooks:
    - admissionReviewVersions:
      - v1beta1
      - v1
      clientConfig:
        url: https://meshconfig.googleapis.com/v1internal/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER/channels/rapid/targets/${MESH_URI}:tdInject
      failurePolicy: Fail
      matchPolicy: Exact
      name: namespace.sidecar-injector.csm.io
      namespaceSelector:
        matchExpressions:
        - key: td-injection
          operator: Exists
      reinvocationPolicy: Never
      rules:
      - apiGroups:
        - ""
        apiVersions:
        - v1
        operations:
        - CREATE
        resources:
        - pods
        scope: '*'
      sideEffects: None
      timeoutSeconds: 30
    EOF
    
  2. Aktifkan injeksi sidecar untuk namespace default. Penyuntik sidecar menyuntikkan container sidecar untuk pod yang dibuat di namespace default.

    kubectl label namespace default td-injection=enabled
    
  3. Simpan konfigurasi GKE berikut untuk layanan Anda sebagai service_sample.yaml.

    apiVersion: v1
    kind: Service
    metadata:
     name: service-test
     annotations:
       cloud.google.com/neg: '{"exposed_ports":{"80":{"name": "rate-limit-demo-neg"}}}'
    spec:
     ports:
     - port: 80
       name: service-test
       targetPort: 8000
     selector:
       run: app1
     type: ClusterIP
    
    ---
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: app1
     labels:
       run: app1
    spec:
     replicas: 1
     selector:
       matchLabels:
         run: app1
     template:
       metadata:
         labels:
           run: app1
         annotations:
           cloud.google.com/proxyMetadata: '{"app": "rate-limit-demo"}'
           cloud.google.com/includeInboundPorts: "8000"
           cloud.google.com/sidecarProxyVersion: "1.34.1-gke.1"
       spec:
         containers:
         - image: mendhak/http-https-echo:37
           name: app1
           ports:
           - containerPort: 8000
           env:
           - name: VALIDATION_NONCE
             value: "http"
           - name: HTTP_PORT
             value: "8000"
         securityContext:
           fsGroup: 1337
    
  4. Terapkan sampel layanan yang Anda buat pada langkah sebelumnya:

    kubectl apply -f service_sample.yaml
    
  5. Simpan konfigurasi GKE berikut untuk klien Anda sebagai client_sample.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
     labels:
       run: client
     name: load-generator
    spec:
     replicas: 1
     selector:
       matchLabels:
         run: client
     template:
       metadata:
         labels:
           run: client
       spec:
         containers:
         - name: load-generator
           image: envoyproxy/nighthawk-dev
           command: ["/bin/sh", "-c"]
           args: ["echo 'Nighthawk client pod is running' && sleep infinity"]
           resources:
             requests:
               cpu: 200m
               memory: 256Mi
             limits:
               cpu: 1
               memory: 512Mi
         securityContext:
           fsGroup: 1337
    
  6. Terapkan sampel klien yang Anda buat pada langkah sebelumnya:

    kubectl apply -f client_sample.yaml
    

Menyiapkan Cloud Service Mesh untuk pembatasan kapasitas

Gunakan langkah-langkah di bagian ini untuk menyiapkan Cloud Service Mesh untuk pembatasan kecepatan.

  1. Buat spesifikasi resource Mesh dan simpan dalam file bernama mesh.yaml:

    name: MESH_NAME
    interceptionPort: 15001
    
  2. Buat resource Mesh menggunakan spesifikasi mesh.yaml.

      gcloud network-services meshes import "MESH_NAME" \
          --source=mesh.yaml \
          --location=global
    
  3. Membuat health check:

      gcloud compute health-checks create http rate-limit-demo-hc \
          --use-serving-port
    
  4. Buat aturan firewall untuk mengizinkan koneksi health check masuk ke instance di jaringan Anda.

      gcloud compute firewall-rules create rate-limit-demo-fw-allow-hc \
          --action ALLOW \
          --direction INGRESS \
          --source-ranges 35.191.0.0/16,130.211.0.0/22 \
          --target-tags allow-envoy-health-checks \
          --rules tcp
    
  5. Buat layanan backend global dengan skema load balancing INTERNAL_SELF_MANAGED dan tambahkan health check.

      gcloud compute backend-services create rate-limit-demo-service \
          --global \
          --health-checks rate-limit-demo-hc \
          --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  6. Tambahkan NEG rate-limit-demo-neg ke layanan backend.

      gcloud compute backend-services add-backend rate-limit-demo-service \
          --global \
          --network-endpoint-group rate-limit-demo-neg \
          --network-endpoint-group-zone "ZONE" \
          --balancing-mode RATE \
          --max-rate-per-endpoint 5
    
  7. Buat spesifikasi HTTPRoute dan simpan ke file bernama http_route.yaml:

    name: rate-limit-demo-http-route
    hostnames:
    - service-test
    - service-test:80
    meshes:
    - projects/PROJECT_ID/locations/global/meshes/MESH_NAME
    rules:
    - action:
       destinations:
       - serviceName: "projects/PROJECT_ID/locations/global/backendServices/rate-limit-demo-service"
    
  8. Buat resource HTTPRoute menggunakan spesifikasi dalam file http_route.yaml.

      gcloud network-services http-routes import rate-limit-demo-http-route \
          --source=http_route.yaml \
          --location=global
    

Mengonfigurasi pembatasan kapasitas dengan Envoy

Bagian berikut menjelaskan cara mengonfigurasi pembatasan frekuensi sisi server untuk mesh layanan Anda. Bagian pertama menunjukkan cara menyiapkan batas frekuensi global sisi server untuk semua klien, dan bagian kedua menunjukkan cara menerapkan batas frekuensi yang berbeda untuk berbagai grup klien.

Mengonfigurasi pembatasan kapasitas global sisi server

Dalam contoh ini, Anda membuat satu aturan pembatasan frekuensi sisi server yang menerapkan pembatasan frekuensi pada semua klien.

  1. Di file YAML bernama rate-limit-policy.yaml, buat kebijakan keamanan Cloud Armor dengan jenis CLOUD_ARMOR_INTERNAL_SERVICE.

    name: "rate-limit-policy"
    type: CLOUD_ARMOR_INTERNAL_SERVICE
    rules:
    - priority: 2147483647
      match:
        config:
          srcIpRanges: ["*"]
        versionedExpr: SRC_IPS_V1
      action: "fairshare"
      rateLimitOptions:
        rateLimitThreshold:
          count: 10000
          intervalSec: 60
        exceedAction: "deny(429)"
        conformAction: "allow"
        enforceOnKey: "ALL"
    
  2. Buat kebijakan keamanan yang disebut rate-limit-policy:

      gcloud beta compute security-policies create rate-limit-policy \
          --global \
          --file-name=rate-limit-policy.yaml
    
  3. Dalam file YAML, buat kebijakan endpoint yang merujuk kebijakan keamanan yang Anda buat pada langkah sebelumnya. Dalam contoh ini, file ini disebut endpoints-policies.yaml.

    name: "rate-limit-ep"
    endpointMatcher:
     metadataLabelMatcher:
       metadataLabelMatchCriteria: MATCH_ALL
       metadataLabels:
       - labelName: app
         labelValue: rate-limit-demo
    type: SIDECAR_PROXY
    securityPolicy: projects/PROJECT_ID/locations/global/securityPolicies/rate-limit-policy
    
  4. Buat kebijakan endpoint bernama rate-limit-ep:

      gcloud beta network-services endpoint-policies import rate-limit-ep \
          --source=endpoints-policies.yaml \
          --location=global
    

Mengonfigurasi batas frekuensi sisi server yang berbeda untuk berbagai grup klien

Dalam contoh ini, Anda membuat aturan pembatasan frekuensi sisi server yang berbeda yang menerapkan berbagai nilai minimum pembatasan frekuensi untuk grup klien.

  1. Buat kebijakan keamanan Cloud Armor dengan jenis CLOUD_ARMOR_INTERNAL_SERVICE dengan beberapa aturan pembatasan kecepatan, seperti yang ditentukan dalam file berikut. Dalam contoh ini, file ini disebut per-client-security-policy.yaml.

    name: "per-client-security-policy"
    type: CLOUD_ARMOR_INTERNAL_SERVICE
    rules:
    - priority: 0
      match:
        expr:
          expression: "request.headers['user'] == 'demo'"
      action: "fairshare"
      rateLimitOptions:
        rateLimitThreshold:
          count: 1000
          intervalSec: 60
        exceedAction: "deny(429)"
        conformAction: "allow"
        enforceOnKey: "ALL"
    - priority: 2147483647
      match:
        config:
          srcIpRanges: ["*"]
        versionedExpr: SRC_IPS_V1
      action: "fairshare"
      rateLimitOptions:
        rateLimitThreshold:
          count: 10000
          intervalSec: 60
        exceedAction: "deny(429)"
        conformAction: "allow"
        enforceOnKey: "ALL"
    

    Kebijakan ini menerapkan pembatasan frekuensi pada permintaan yang berisi header HTTP dengan nama user dan nilai demo jika Cloud Service Mesh menerima lebih dari 1.000 permintaan tersebut dalam jangka waktu 60 detik. Permintaan yang tidak memiliki header HTTP ini akan dibatasi lajunya jika Cloud Service Mesh menerima lebih dari 10.000 permintaan semacam itu dalam jangka waktu 60 detik.

  2. Gunakan perintah berikut untuk membuat kebijakan, yang disebut per-client-security-policy:

      gcloud beta compute security-policies create per-client-security-policy \
          --global \
          --file-name=per-client-security-policy.yaml
    

    Buat kebijakan endpoint yang merujuk ke kebijakan keamanan yang Anda buat pada langkah sebelumnya, seperti yang ditentukan dalam file berikut. Dalam contoh ini, file ini disebut per-client-endpoints-policies.yaml.

    name: "rate-limit-ep"
    endpointMatcher:
     metadataLabelMatcher:
       metadataLabelMatchCriteria: MATCH_ALL
       metadataLabels:
       - labelName: app
         labelValue: rate-limit-demo
    type: SIDECAR_PROXY
    securityPolicy: projects/PROJECT_ID/locations/global/securityPolicies/per-client-security-policy
    

    Gunakan perintah berikut untuk membuat kebijakan endpoint bernama rate-limit-ep:

      gcloud beta network-services endpoint-policies import rate-limit-ep \
          --source=per-client-endpoints-policies.yaml \
          --location=global
    

Memvalidasi penyiapan Anda

Anda dapat menggunakan alat pengujian beban Nighthawk untuk menghasilkan traffic guna menguji apakah aturan pembatasan frekuensi Anda berfungsi seperti yang diharapkan. Gunakan perintah berikut untuk membuat traffic dengan Nighthawk:

kubectl exec -it deploy/load-generator -c load-generator -- \
    nighthawk_client http://service-test \
    --open-loop --no-default-failure-predicates \
    --rps 60 \
    --duration 360 \
    --connections 10 \
    --protocol http1 \
    --request-header user:demo

Selanjutnya, gunakan perintah berikut untuk mengaktifkan log debug Envoy:

kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \
    --post-data="" 'http://localhost:15000/logging?level=debug'

Untuk melihat laporan penggunaan yang dikirim Envoy ke server pengelolaan, lihat Mengakses log Anda.

Anda dapat melihat hasil pengujian berikut:

  • Diperlukan waktu sekitar lima menit sebelum pembatasan frekuensi berlaku.
  • Setelah periode pemanasan awal, Anda akan melihat sekitar 15-21 QPS dari penghitung benchmark.http_2xx output klien Nighthawk. Artinya,Cloud Armor mengizinkan sekitar 1.000 permintaan per menit.

Untuk melihat efektivitas aturan kebijakan keamanan Cloud Armor Anda, lihat Melihat dasbor pemantauan.

Menonaktifkan pembatasan kapasitas

Anda dapat menonaktifkan pembatasan kecepatan menggunakan salah satu metode berikut:

  • Anda dapat menghapus kebijakan endpoint dan kebijakan keamanan yang Anda konfigurasi dengan aturan pembatasan kecepatan.
  • Anda dapat melepaskan kebijakan keamanan dari kebijakan endpoint dengan memperbarui kebijakan endpoint untuk menghapus kolom securityPolicies.

Bagian berikut menjelaskan cara menonaktifkan pembatasan kecepatan menggunakan setiap metode.

Menghapus kebijakan endpoint dan kebijakan keamanan

Pertama, gunakan perintah gcloud berikut untuk menghapus kebijakan endpoint Anda yang bernama rate-limit-ep. Jika Anda menggunakan nama yang diberikan dalam contoh pertama atau kedua di halaman ini, kebijakan endpoint masing-masing diberi nama endpoints-policies atau per-client-endpoints-policies.

gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep

Kemudian, gunakan perintah gcloud berikut untuk menghapus kebijakan keamanan, dengan mengganti per-client-security-policy dengan nama kebijakan keamanan Anda. Jika Anda menggunakan nama yang diberikan dalam contoh pertama atau kedua di halaman ini, maka kebijakan keamanan Anda memiliki nama yang sama dengan kebijakan endpoint Anda.

gcloud beta compute security-policies delete --global per-client-security-policy

Melepaskan kebijakan keamanan dari kebijakan endpoint Anda

Pertama, perbarui file endpoint-policy.yaml untuk menghapus kolom securityPolcies:

name: "rate-limit-ep"
endpointMatcher:
  metadataLabelMatcher:
    metadataLabelMatchCriteria: MATCH_ALL
    metadataLabels:
    - labelName: app
      labelValue: rate-limit-demo
type: SIDECAR_PROXY

Kemudian, gunakan perintah berikut untuk memperbarui kebijakan endpoint bernama rate-limit-ep dengan perubahan pada file endpoint-policy.yaml:

gcloud beta network-services endpoint-policies import rate-limit-ep \
    --source=endpoints-policies.yaml \
    --location=global