Con el enrutamiento por subconjuntos estáticos, cada DestinationRule debe listar explícitamente cada subconjunto. Cuando se publica una nueva versión o se retira una antigua, es necesario actualizar la regla manualmente. El enrutamiento por subconjuntos dinámicos elimina esta sobrecarga: Service Mesh (ASM) supervisa las etiquetas de las cargas de trabajo y agrupa los endpoints en subconjuntos automáticamente, lo que mantiene las reglas de enrutamiento actualizadas sin cambios manuales.
El siguiente ejemplo integral despliega una aplicación con múltiples versiones, enruta las solicitudes a versiones y entornos específicos mediante encabezados HTTP y configura un comportamiento de respaldo cuando no existe el subconjunto destino.
Funcionamiento de los subconjuntos dinámicos
En el enrutamiento estándar de Istio, una DestinationRule enumera cada subconjunto con un conjunto fijo de etiquetas. Cuando cambian las versiones, se debe actualizar la regla para que coincida.
Los subconjuntos dinámicos adoptan un enfoque diferente. En lugar de listar cada subconjunto, usted especifica una o más claves de agrupación (por ejemplo, version y stage). ASM inspecciona las etiquetas de cada endpoint detrás de un servicio y agrupa automáticamente los endpoints que comparten la misma combinación de clave-valor en el mismo subconjunto.
Luego, una VirtualService asigna los encabezados de las solicitudes entrantes a esas claves de agrupación. Por ejemplo, una solicitud que incluye x-version: v2 y x-stage: prod se enruta al subconjunto donde version=v2 y stage=prod.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una instancia de ASM versión 1.18 o posterior
Un clúster de Container Service for Kubernetes (ACK) added to the ASM instance
kubectl configurado con el kubeconfig file of the ACK cluster
Paso 1: Desplegar la aplicación de ejemplo
Este ejemplo utiliza hashicorp/http-echo para simular un despliegue con múltiples entornos y versiones:
Entorno dev: versiones v1, v2, v3
Entorno prod: versiones v2, v3
Cada pod responde con su entorno, versión y dirección IP. Un Service helloworld en el puerto 8000 actúa como frontend para todos los pods, y un Deployment sleep proporciona un cliente para realizar pruebas.

Despliegue todos los recursos con kubectl. Para obtener más información, consulte Deploy an application in an ACK cluster that is added to an ASM instance.
Paso 2: Enrutar solicitudes a una versión y entorno específicos
Tras el despliegue, Kubernetes distribuye las solicitudes entre todos los pods de helloworld sin importar la versión ni el entorno. Para dirigirse a una combinación específica, cree una DestinationRule que defina las claves de agrupación y una VirtualService que asigne los encabezados de las solicitudes a dichas claves.
Crear la DestinationRule
Aplique la siguiente DestinationRule para agrupar los endpoints por stage y version. Para obtener más información, consulte 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:
- keys:
- stage
- version
ASM lee las etiquetas stage y version de cada endpoint y genera los siguientes subconjuntos:
|
Subconjunto |
Pod |
Dirección IP |
|
stage=dev, version=v1 |
helloworld-dev-v1-67b6876778-nf7pz |
192.168.0.5 |
|
stage=dev, version=v2 |
helloworld-dev-v2-68f65bbc99-v957l |
192.168.0.1 |
|
stage=dev, version=v3 |
helloworld-dev-v3-7f6978bc56-hqzgg |
192.168.0.252 |
|
stage=prod, version=v2 |
helloworld-prod-v2-b5745b949-p8rc4 |
192.168.0.103 |
|
stage=prod, version=v3 |
helloworld-prod-v3-6768bf56f8-6bd6h |
192.168.0.104, 192.168.0.6 |
Crear la VirtualService
Aplique la siguiente VirtualService para asignar los encabezados HTTP a las claves de subconjuntos dinámicos. Para obtener más información, consulte 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-version # Map the x-version header to the "version" grouping key
key: version
defaultValue: v3 # Fall back to v3 if the header is absent
- header: x-stage # Map the x-stage header to the "stage" grouping key
key: stage
defaultValue: prod # Fall back to prod if the header is absent
name: default
route:
- destination:
host: helloworld.default.svc.cluster.local
port:
number: 8000
Esta VirtualService establece dos asignaciones:
Encabezado
x-versiona la clave de agrupaciónversion. Valor predeterminado:v3cuando el encabezado está ausente.Encabezado
x-stagea la clave de agrupaciónstage. Valor predeterminado:prodcuando el encabezado está ausente.
Comprobar el enrutamiento
Envíe una solicitud dirigida al entorno dev, versión v1:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: dev' -H 'x-version: v1' helloworld:8000
Salida esperada:
Welcome to helloworld stage: dev, version: v1, ip: 192.168.0.5
La solicitud llega al pod donde stage=dev y version=v1, lo que confirma que el enrutamiento por subconjuntos dinámicos funciona correctamente.
Paso 3: Configurar directivas de respaldo
La versión v1 no existe en el entorno prod. Una solicitud dirigida a stage=prod, version=v1 no coincide con ningún subconjunto:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
# Output: no healthy upstream
Para gestionar los subconjuntos sin coincidencias, establezca una fallbackPolicy en la DestinationRule. ASM admite tres directivas:
|
Directiva |
Comportamiento |
Recomendada para |
|
|
Devuelve un error |
Enrutamiento estricto donde las solicitudes mal enrutadas deben fallar rápidamente |
|
|
Enruta a cualquier endpoint disponible en todos los subconjuntos |
Desarrollo o pruebas donde la disponibilidad es más importante que la precisión |
|
|
Enruta a un subconjunto predeterminado preconfigurado |
Cargas de trabajo de producción, donde las solicitudes sin coincidencia deben dirigirse a una versión estable conocida |
NO_FALLBACK
NO_FALLBACK es el comportamiento predeterminado. Las solicitudes que no coinciden con ningún subconjunto devuelven un error. Establézcala explícitamente para dejar clara la intención de fallo rápido.
Aplique la siguiente DestinationRule. Para obtener más información, consulte 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
Compruebe el resultado:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Salida esperada:
no healthy upstream
ANY_ENDPOINT
Cuando ningún subconjunto coincide, las solicitudes se enrutan a cualquier endpoint disponible sin importar las etiquetas.
Aplique la siguiente DestinationRule. Para obtener más información, consulte 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
Compruébelo mediante el envío de dos solicitudes. Cada una puede llegar a un pod diferente:
# First request
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' helloworld:8000
Ejemplo de salida:
Welcome to helloworld stage: prod, version: v2, ip: 192.168.0.103
# Second request -- targets a non-existent subset
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Ejemplo de salida:
Welcome to helloworld stage: dev, version: v2, ip: 192.168.0.1
Dado que no existe el subconjunto prod/v1, la solicitud recurre a un endpoint aleatorio.
DEFAULT_SUBSET
Cuando ningún subconjunto coincide, las solicitudes se enrutan al subconjunto definido en defaultSubset. Esta es la directiva recomendada para cargas de trabajo de producción, ya que las solicitudes sin coincidencia se dirigen a una versión estable conocida en lugar de fallar o dispersarse aleatoriamente.
Aplique la siguiente DestinationRule. En este ejemplo, defaultSubset apunta a stage=prod, version=v3. Para obtener más información, consulte 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
Compruébelo mediante el envío de dos solicitudes al subconjunto inexistente prod/v1:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
Salida esperada:
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
Salida esperada:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.104
Ambas solicitudes llegan al subconjunto predeterminado prod/v3. Las dos direcciones IP diferentes (192.168.0.6 y 192.168.0.104) reflejan el balanceo de carga entre las dos réplicas prod-v3.
Paso 4: Enrutar a un pod específico por dirección IP
Para fijar las solicitudes a un pod individual, utilice el atributo integrado %ip% como clave de agrupación. Cada pod se convierte en su propio subconjunto de un solo miembro.
Crear la DestinationRule
Aplique la siguiente DestinationRule para agrupar los pods por dirección IP. Para obtener más información, consulte 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%'
Crear la VirtualService
Asigne el encabezado x-ip a la clave %ip% para que el valor del encabezado especifique la IP del pod destino. Para obtener más información, consulte 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
Comprobar el enrutamiento
Envíe varias solicitudes dirigidas a la IP del pod 192.168.0.6:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000
Salida esperada (consistente en llamadas repetidas):
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6
Cada solicitud llega al mismo pod, lo que confirma la fijación basada en IP.
Referencia de campos CRD
VirtualService
HTTPRoute
ASM extiende el recurso HTTPRoute con el campo headerToDynamicSubsetKey.
|
Campo |
Tipo |
Descripción |
|
|
HeaderToMetadataSubsetKey[] |
Asigna encabezados de solicitud a claves de agrupación de subconjuntos dinámicos. Cada elemento define una asignación de encabezado a clave. |
HeaderToMetadataSubsetKey
|
Campo |
Tipo |
Descripción |
|
|
string |
Nombre del encabezado de la solicitud. |
|
|
string |
Nombre de la clave de agrupación del subconjunto dinámico. Un valor encerrado entre signos de porcentaje (por ejemplo, |
|
|
string |
Valor utilizado cuando la solicitud no incluye el encabezado especificado. Si se omite y el encabezado está ausente, la clave queda sin establecer y se excluye de la coincidencia de subconjuntos. |
DestinationRule
ASM extiende la estructura trafficPolicy con el campo dynamicSubset.
TrafficPolicy
|
Campo |
Tipo |
Descripción |
|
|
DynamicSubsetLB |
Configura las reglas de agrupación de subconjuntos dinámicos. |
DynamicSubsetLB
|
Campo |
Tipo |
Descripción |
|
|
map[string]string |
Subconjunto predeterminado que se utiliza cuando |
|
|
SubsetSelector[] |
Lista de reglas de agrupación. Cada elemento define una dimensión de agrupación independiente. |
|
|
DynamicSubsetLB_FallbackPolicy |
Directiva de respaldo global cuando ningún subconjunto coincide. El valor predeterminado es |
SubsetSelector
|
Campo |
Tipo |
Descripción |
|
|
string[] |
Dimensiones de agrupación asignadas a etiquetas de carga de trabajo. Por ejemplo, |
|
|
DynamicSubsetLB_FallbackPolicy |
Directiva de respaldo para esta regla de agrupación específica. Anula la directiva establecida en DynamicSubsetLB. |
DynamicSubsetLB_FallbackPolicy
|
Valor |
Descripción |
|
|
Devuelve un error cuando ningún subconjunto coincide. Este es el valor predeterminado. |
|
|
Enruta a cualquier endpoint del servicio cuando ningún subconjunto coincide. |
|
|
Enruta al subconjunto definido en |
Atributos integrados de carga de trabajo
|
Atributo |
Tipo |
Descripción |
|
|
string |
Dirección IP del pod donde se ejecuta la carga de trabajo. |