All Products
Search
Document Center

Alibaba Cloud Service Mesh:Perutean subset dinamis

Last Updated:Mar 11, 2026

Dengan perutean subset statis, setiap DestinationRule harus mencantumkan tiap subset secara eksplisit. Ketika versi baru dirilis atau versi lama dihentikan, aturan tersebut harus diperbarui secara manual. Perutean subset dinamis menghilangkan beban ini: Service Mesh (ASM) memantau label workload dan mengelompokkan endpoint ke dalam subset secara otomatis, sehingga aturan perutean tetap mutakhir tanpa perubahan manual.

Contoh end-to-end berikut men-deploy aplikasi multi-versi, mengarahkan permintaan ke versi dan lingkungan tertentu berdasarkan Header HTTP, serta mengonfigurasi perilaku fallback ketika subset target tidak tersedia.

Cara kerja subset dinamis

Pada perutean Istio standar, DestinationRule mencantumkan tiap subset dengan kumpulan label tetap. Saat versi berubah, aturan tersebut harus diperbarui agar sesuai.

Subset dinamis menggunakan pendekatan yang berbeda. Alih-alih mencantumkan tiap subset, Anda menentukan satu atau beberapa kunci pengelompokan (misalnya, version dan stage). ASM memeriksa label pada setiap endpoint di balik suatu layanan dan mengelompokkan endpoint yang memiliki kombinasi kunci-nilai yang sama ke dalam subset yang sama—secara otomatis.

VirtualService kemudian memetakan header permintaan masuk ke kunci pengelompokan tersebut. Misalnya, permintaan yang membawa x-version: v2 dan x-stage: prod akan diarahkan ke subset tempat version=v2 dan stage=prod.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Langkah 1: Deploy aplikasi contoh

Contoh ini menggunakan hashicorp/http-echo untuk mensimulasikan deployment multi-lingkungan dan multi-versi:

  • Lingkungan dev: versi v1, v2, v3

  • Lingkungan prod: versi v2, v3

Tiap Pod merespons dengan informasi lingkungan, versi, dan alamat IP-nya. Layanan helloworld pada Port 8000 melayani semua Pod, dan Deployment sleep menyediakan client untuk pengujian.

Deployment topology

Deploy semua resource dengan kubectl. Untuk informasi selengkapnya, lihat Deploy aplikasi di kluster ACK yang ditambahkan ke instans ASM.

dev environment

# Komentar YAML tetap dalam bahasa Inggris
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-dev-v1
  labels:
    app: helloworld
    version: v1
    stage: dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
      version: v1
      stage: dev
  template:
    metadata:
      labels:
        app: helloworld
        version: v1
        stage: dev
    spec:
      containers:
      - name: helloworld
        image: hashicorp/http-echo:0.2.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5678
        env:
        - name: PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STAGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['stage']
        - name: VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        command: ["/http-echo"]
        args:
          - "-text"
          - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-dev-v2
  labels:
    app: helloworld
    version: v2
    stage: dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
      version: v2
      stage: dev
  template:
    metadata:
      labels:
        app: helloworld
        version: v2
        stage: dev
    spec:
      containers:
      - name: helloworld
        image: hashicorp/http-echo:0.2.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5678
        env:
        - name: PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STAGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['stage']
        - name: VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        command: ["/http-echo"]
        args:
          - "-text"
          - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-dev-v3
  labels:
    app: helloworld
    version: v3
    stage: dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
      version: v3
      stage: dev
  template:
    metadata:
      labels:
        app: helloworld
        version: v3
        stage: dev
    spec:
      containers:
      - name: helloworld
        image: hashicorp/http-echo:0.2.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5678
        env:
        - name: PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STAGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['stage']
        - name: VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        command: ["/http-echo"]
        args:
          - "-text"
          - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"

lingkungan prod

# Komentar YAML tetap dalam bahasa Inggris
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-prod-v2
  labels:
    app: helloworld
    version: v2
    stage: prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
      version: v2
      stage: prod
  template:
    metadata:
      labels:
        app: helloworld
        version: v2
        stage: prod
    spec:
      containers:
      - name: helloworld
        image: hashicorp/http-echo:0.2.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5678
        env:
        - name: PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STAGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['stage']
        - name: VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        command: ["/http-echo"]
        args:
          - "-text"
          - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-prod-v3
  labels:
    app: helloworld
    version: v3
    stage: prod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: helloworld
      version: v3
      stage: prod
  template:
    metadata:
      labels:
        app: helloworld
        version: v3
        stage: prod
    spec:
      containers:
      - name: helloworld
        image: hashicorp/http-echo:0.2.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5678
        env:
        - name: PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: STAGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['stage']
        - name: VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        command: ["/http-echo"]
        args:
          - "-text"
          - "Welcome to helloworld stage: $(STAGE), version: $(VERSION), ip: $(PODIP)"

helloworld Service

apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
    service: helloworld
spec:
  ports:
  - port: 8000
    name: http
    targetPort: 5678
  selector:
    app: helloworld

sleep client

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sleep
  template:
    metadata:
      labels:
        app: sleep
    spec:
      terminationGracePeriodSeconds: 0
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: curlimages/curl
        command: ["/bin/sleep", "infinity"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true

Langkah 2: Arahkan permintaan ke versi dan lingkungan tertentu

Setelah deployment, Kubernetes melakukan load-balancing permintaan ke seluruh Pod helloworld tanpa memandang versi atau lingkungan. Untuk menargetkan kombinasi tertentu, buat DestinationRule yang menentukan kunci pengelompokan dan VirtualService yang memetakan header permintaan ke kunci tersebut.

Buat DestinationRule

Terapkan DestinationRule berikut untuk mengelompokkan endpoint berdasarkan stage dan version. Untuk informasi selengkapnya, lihat Manage destination rules.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
  host: helloworld.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      dynamicSubset:
        subsetSelectors:
          - fallbackPolicy: NO_FALLBACK
            keys:
              - stage
              - version

ASM membaca label stage dan version dari tiap endpoint dan menghasilkan subset berikut:

SubsetPodAlamat IP
stage=dev, version=v1helloworld-dev-v1-67b6876778-nf7pz192.168.0.5
stage=dev, version=v2helloworld-dev-v2-68f65bbc99-v957l192.168.0.1
stage=dev, version=v3helloworld-dev-v3-7f6978bc56-hqzgg192.168.0.252
stage=prod, version=v2helloworld-prod-v2-b5745b949-p8rc4192.168.0.103
stage=prod, version=v3helloworld-prod-v3-6768bf56f8-6bd6h192.168.0.104, 192.168.0.6

Buat VirtualService

Terapkan VirtualService berikut untuk memetakan Header HTTP ke kunci subset dinamis. Untuk informasi selengkapnya, lihat Manage virtual services.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld
  namespace: default
spec:
  hosts:
    - helloworld.default.svc.cluster.local
  http:
    - headerToDynamicSubsetKey:
        - header: x-ip
          key: '%ip%'
      name: default
      route:
        - destination:
            host: helloworld.default.svc.cluster.local
            port:
              number: 8000

VirtualService ini menetapkan dua pemetaan:

  • Header x-version ke kunci pengelompokan version. Nilai default: v3 jika header tidak ada.

  • Header x-stage ke kunci pengelompokan stage. Nilai default: prod jika header tidak ada.

Verifikasi perutean

Kirim permintaan yang menargetkan lingkungan dev, versi v1:

kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: dev' -H 'x-version: v1' helloworld:8000

Output yang diharapkan:

Welcome to helloworld stage: dev, version: v1, ip: 192.168.0.5

Permintaan mencapai Pod tempat stage=dev dan version=v1, yang mengonfirmasi bahwa perutean subset dinamis berfungsi dengan benar.

Langkah 3: Konfigurasi kebijakan fallback

Versi v1 tidak tersedia di lingkungan prod. Permintaan yang menargetkan stage=prod, version=v1 tidak cocok dengan subset apa pun:

kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000

Untuk menangani subset yang tidak cocok, tetapkan fallbackPolicy di DestinationRule. ASM mendukung tiga kebijakan:

KebijakanPerilakuDirekomendasikan untuk
NO_FALLBACKMengembalikan error no healthy upstream. Ini adalah nilai default.Perutean ketat di mana permintaan yang salah rute harus gagal secepatnya
ANY_ENDPOINTMengarahkan ke endpoint mana pun yang tersedia di seluruh subsetPengembangan atau pengujian di mana ketersediaan lebih penting daripada presisi
DEFAULT_SUBSET (direkomendasikan untuk produksi)Mengarahkan ke subset default yang telah dikonfigurasi sebelumnyaWorkload produksi, di mana permintaan yang tidak cocok harus diarahkan ke versi yang diketahui stabil

NO_FALLBACK

NO_FALLBACK adalah perilaku default. Permintaan yang tidak cocok dengan subset mana pun akan mengembalikan error. Tetapkan secara eksplisit untuk memperjelas maksud fail-fast.

Terapkan DestinationRule berikut. Untuk informasi selengkapnya, lihat Manage destination rules.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
  host: helloworld.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      dynamicSubset:
        subsetSelectors:
          - fallbackPolicy: NO_FALLBACK
            keys:
              - stage
              - version

Verifikasi:

kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000

Output yang diharapkan:

no healthy upstream

ANY_ENDPOINT

Jika tidak ada subset yang cocok, permintaan diarahkan ke endpoint mana pun yang tersedia tanpa memandang label.

Terapkan DestinationRule berikut. Untuk informasi selengkapnya, lihat Manage destination rules.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
  host: helloworld.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      dynamicSubset:
        subsetSelectors:
          - fallbackPolicy: ANY_ENDPOINT
            keys:
              - stage
              - version

Verifikasi dengan mengirim dua permintaan. Tiap permintaan mungkin mendarat di Pod yang berbeda:

# Permintaan pertama
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' helloworld:8000

Contoh output:

Welcome to helloworld stage: prod, version: v2, ip: 192.168.0.103
# Permintaan kedua -- menargetkan subset yang tidak ada
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000

Contoh output:

Welcome to helloworld stage: dev, version: v2, ip: 192.168.0.1

Karena subset prod/v1 tidak ada, permintaan tersebut menggunakan fallback ke endpoint acak.

DEFAULT_SUBSET

Jika tidak ada subset yang cocok, permintaan diarahkan ke subset yang ditentukan dalam defaultSubset. Ini adalah kebijakan yang direkomendasikan untuk workload produksi karena permintaan yang tidak cocok akan diarahkan ke versi yang diketahui stabil, bukan gagal atau tersebar secara acak.

Terapkan DestinationRule berikut. Dalam contoh ini, defaultSubset mengarah ke stage=prod, version=v3. Untuk informasi selengkapnya, lihat Manage destination rules.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
  host: helloworld.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      dynamicSubset:
        defaultSubset:
          stage: prod
          version: v3
        subsetSelectors:
          - fallbackPolicy: DEFAULT_SUBSET
            keys:
              - stage
              - version

Verifikasi dengan mengirim dua permintaan ke subset prod/v1 yang tidak ada:

kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000

Output yang diharapkan:

Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000

Output yang diharapkan:

Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.104

Kedua permintaan mendarat di subset default prod/v3. Dua alamat IP berbeda (192.168.0.6 dan 192.168.0.104) mencerminkan load balancing di antara dua replika prod-v3.

Langkah 4: Arahkan ke Pod tertentu berdasarkan alamat IP

Untuk mengunci permintaan ke Pod individual, gunakan atribut bawaan %ip% sebagai kunci pengelompokan. Setiap Pod menjadi subset anggota tunggalnya sendiri.

Buat DestinationRule

Terapkan DestinationRule berikut untuk mengelompokkan Pod berdasarkan alamat IP. Untuk informasi selengkapnya, lihat Manage destination rules.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: default
spec:
  host: helloworld.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      dynamicSubset:
        defaultSubset:
          stage: prod
          version: v3
        subsetSelectors:
          - keys:
              - '%ip%'

Buat VirtualService

Petakan header x-ip ke kunci %ip% sehingga nilai header menentukan IP Pod target. Untuk informasi selengkapnya, lihat Manage virtual services.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld
  namespace: default
spec:
  hosts:
    - helloworld.default.svc.cluster.local
  http:
    - headerToDynamicSubsetKey:
        - header: x-ip
          key: '%ip%'
      name: default
      route:
        - destination:
            host: helloworld.default.svc.cluster.local
            port:
              number: 8000

Verifikasi perutean

Kirim beberapa permintaan yang menargetkan IP Pod 192.168.0.6:

kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000

Output yang diharapkan (konsisten pada setiap panggilan berulang):

Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6

Setiap permintaan mendarat di Pod yang sama, yang mengonfirmasi penguncian berbasis IP.

Referensi bidang CRD

VirtualService

HTTPRoute

ASM memperluas resource HTTPRoute dengan bidang headerToDynamicSubsetKey.

BidangTipeDeskripsi
headerToDynamicSubsetKeyHeaderToMetadataSubsetKey[]Memetakan header permintaan ke kunci pengelompokan subset dinamis. Tiap elemen menentukan satu pemetaan header-ke-kunci.

HeaderToMetadataSubsetKey

BidangTipeDeskripsi
headerstringNama header permintaan.
keystringNama kunci pengelompokan subset dinamis. Nilai yang diapit tanda persen (misalnya, %ip%) merujuk ke atribut workload bawaan.
defaultValuestringNilai yang digunakan ketika permintaan tidak membawa header yang ditentukan. Jika diabaikan dan header tidak ada, kunci tersebut tidak diatur dan tidak termasuk dalam pencocokan subset.

DestinationRule

ASM memperluas struktur trafficPolicy dengan bidang dynamicSubset.

TrafficPolicy

BidangTipeDeskripsi
dynamicSubsetDynamicSubsetLBMengonfigurasi aturan pengelompokan subset dinamis.

DynamicSubsetLB

BidangTipeDeskripsi
defaultSubsetmap[string]stringSubset default yang digunakan ketika fallbackPolicy bernilai DEFAULT_SUBSET dan tidak ada subset yang cocok dengan permintaan.
subsetSelectorsSubsetSelector[]Daftar aturan pengelompokan. Tiap elemen menentukan dimensi pengelompokan terpisah.
fallbackPolicyDynamicSubsetLB_FallbackPolicyKebijakan fallback global ketika tidak ada subset yang cocok. Nilai default adalah NO_FALLBACK.

SubsetSelector

BidangTipeDeskripsi
keysstring[]Dimensi pengelompokan yang dipetakan ke label workload. Misalnya, version mengelompokkan endpoint berdasarkan label version. Atribut workload bawaan seperti %ip% juga didukung.
fallbackPolicyDynamicSubsetLB_FallbackPolicyKebijakan fallback untuk aturan pengelompokan spesifik ini. Menggantikan kebijakan yang ditetapkan di DynamicSubsetLB.

DynamicSubsetLB_FallbackPolicy

NilaiDeskripsi
NO_FALLBACKMengembalikan error ketika tidak ada subset yang cocok. Ini adalah nilai default.
ANY_ENDPOINTMengarahkan ke endpoint mana pun dari layanan ketika tidak ada subset yang cocok.
DEFAULT_SUBSETMengarahkan ke subset yang ditentukan dalam defaultSubset ketika tidak ada subset yang cocok.

Atribut workload bawaan

AtributTipeDeskripsi
%ip%stringAlamat IP Pod tempat workload berjalan.

Lihat juga