Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Important
AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:
The Istio service mesh add-on supports both Istio's own ingress traffic management API and the Kubernetes Gateway API for ingress traffic management. You can use the Istio Gateway API automated deployment model or the manual deployment model. This article describes how to configure ingress traffic management for the Istio service mesh add-on using the Kubernetes Gateway API with the automated deployment model.
Limitations and considerations
- Using the Kubernetes Gateway API for egress traffic management with the Istio service mesh add-on is only supported for the manual deployment model.
- ConfigMap customizations for
Gatewayresources must fall within the Resource customization allow list. Fields not on the allow list are disallowed and blocked via add-on managed webhooks. For more information, see the Istio service mesh add-on support policy.
Prerequisites
- Enable the Managed Gateway API on your AKS cluster.
- Install the Istio service mesh add-on revision
asm-1-26or higher. Follow the installation guide if you don't have the Istio service mesh add-on installed yet, or the upgrade guide if you're on a lower minor revision.
Set environment variables
Set the following environment variables to use throughout this article:
| Variable | Description |
|---|---|
RESOURCE_GROUP |
The name of the resource group containing your AKS cluster. |
CLUSTER_NAME |
The name of your AKS cluster. |
LOCATION |
The Azure region where your AKS cluster is deployed. |
KEY_VAULT_NAME |
The name of the Azure Key Vault resource to be created for storing TLS secrets. If you have an existing resource, use that name. |
Deploy sample application
Deploy the sample
httpbinapplication in thedefaultnamespace using thekubectl applycommand.kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/httpbin/httpbin.yaml
Create Kubernetes Gateway and HTTPRoute
The example manifest creates an external ingress load balancer service that's accessible from outside the cluster. You can add annotations to create an internal load balancer and customize other load balancer settings.
Deploy a Gateway API configuration in the
defaultnamespace with thegatewayClassNameset toistioand anHTTPRoutethat routes traffic to thehttpbinservice using the following manifest:kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http namespace: default spec: parentRefs: - name: httpbin-gateway hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /get backendRefs: - name: httpbin port: 8000 EOFNote
If you're performing a minor revision upgrade and have two Istio service mesh add-on revisions installed on your cluster simultaneously, the control plane for the higher minor revision takes ownership of the
Gatewaysby default. You can add theistio.io/revlabel to theGatewayto control which control plane revision owns it. If you add the revision label, make sure that you update it accordingly to the appropriate control plane revision before rolling back or completing the upgrade operation.
Verify resource creation
Verify the
Deployment,Service,HorizontalPodAutoscaler, andPodDisruptionBudgetresources were created using the followingkubectl getcommands:kubectl get deployment httpbin-gateway-istio kubectl get service httpbin-gateway-istio kubectl get hpa httpbin-gateway-istio kubectl get pdb httpbin-gateway-istioExample output:
# Deployment resource NAME READY UP-TO-DATE AVAILABLE AGE httpbin-gateway-istio 2/2 2 2 31m # Service resource NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpbin-gateway-istio LoadBalancer 10.0.65.45 <external-ip> 15021:32053/TCP,80:31587/TCP 33m # HPA resource NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 2 5 3 34m # PDB resource NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE httpbin-gateway-istio 1 N/A 2 36m
Send request to sample application
Try sending a
curlrequest to thehttpbinapplication. First, set theINGRESS_HOSTenvironment variable:kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -ojsonpath='{.status.addresses[0].value}')Try sending an HTTP request to
httpbin.curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"In the output, you should see an
HTTP 200response.
Secure Istio ingress traffic with the Kubernetes Gateway API
The Istio service mesh add-on supports syncing secrets from Azure Key Vault for securing Gateway API-based ingress traffic with Transport Layer Security (TLS) termination or Server Name Indication (SNI) passthrough. In the following sections, you sync secrets from Azure Key Vault onto your AKS cluster using the Azure Key Vault provider for Secrets Store Container Storage Interface (CSI) Driver add-on and terminate TLS at the ingress gateway.
Create client/server certificates and keys
Create a root certificate and private key for signing the certificates for sample services:
mkdir httpbin_certs openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout httpbin_certs/example.com.key -out httpbin_certs/example.com.crtGenerate a certificate and a private key for
httpbin.example.com:openssl req -out httpbin_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization" openssl x509 -req -sha256 -days 365 -CA httpbin_certs/example.com.crt -CAkey httpbin_certs/example.com.key -set_serial 0 -in httpbin_certs/httpbin.example.com.csr -out httpbin_certs/httpbin.example.com.crt
Set up Azure Key Vault and create secrets
Create an Azure Key Vault instance to supply the certificate and key inputs to the Istio service mesh add-on using the
az keyvault createcommand. If you already have an Azure Key Vault instance, you can skip this step.az keyvault create --name $KEY_VAULT_NAME --resource-group $RESOURCE_GROUP --location $LOCATIONEnable the Azure Key Vault provider for Secrets Store (CSI) Driver add-on on your cluster using the
az aks enable-addonscommand.az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER_NAMEIf your key vault uses Azure role-based access control (RBAC) for the permissions model, follow the instructions in Provide access to Azure Key Vault keys, certificates, and secrets with Azure role-based access control to assign an Azure role of Key Vault Secrets User for the add-on's user-assigned managed identity. Alternatively, if your key vault uses the vault access policy permissions model, authorize the user-assigned managed identity of the add-on to access Azure Key Vault resource using access policy using the
az keyvault set-policycommand.OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $KEY_VAULT_NAME --query 'properties.tenantId') az keyvault set-policy --name $KEY_VAULT_NAME --object-id $OBJECT_ID --secret-permissions get listCreate secrets in Azure Key Vault using the certificates and keys using the following
az keyvault secret setcommands:az keyvault secret set --vault-name $KEY_VAULT_NAME --name test-httpbin-key --file httpbin_certs/httpbin.example.com.key az keyvault secret set --vault-name $KEY_VAULT_NAME --name test-httpbin-crt --file httpbin_certs/httpbin.example.com.crt
Deploy SecretProviderClass and sample pod
Deploy the SecretProviderClass to provide Azure Key Vault specific parameters to the CSI driver using the following manifest. In this example,
test-httpbin-keyandtest-httpbin-crtare the names of the secret objects in Azure Key Vault.cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $KEY_VAULT_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-key objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-crt objectType: secret objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOFNote
Alternatively, to reference a certificate object type directly from Azure Key Vault, use the following manifest to deploy SecretProviderClass. In this example,
test-httpbin-cert-pxfis the name of the certificate object in Azure Key Vault.cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $KEY_VAULT_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: cert objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOFDeploy a sample pod using the following manifest. The Azure Key Vault provider for Secrets Store (CSI) Driver add-on requires a pod to reference the SecretProviderClass resource to ensure secrets sync from Azure Key Vault to the cluster.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-httpbin spec: containers: - name: busybox image: mcr.microsoft.com/oss/busybox/busybox:1.33.1 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "httpbin-credential-spc" EOF
Verify TLS secret creation
Verify the
httpbin-credentialsecret was created in thedefaultnamespace as defined in the SecretProviderClass resource using thekubectl describe secretcommand.kubectl describe secret/httpbin-credentialExample output:
Name: httpbin-credential Namespace: default Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: kubernetes.io/tls Data ==== tls.crt: 1180 bytes tls.key: 1675 bytes
Deploy TLS Gateway
Create a Kubernetes Gateway that references the
httpbin-credentialsecret under the TLS configuration using the following manifest:cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: istio listeners: - name: https hostname: "httpbin.example.com" port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: httpbin-credential allowedRoutes: namespaces: from: Selector selector: matchLabels: kubernetes.io/metadata.name: default EOFNote
In the gateway definition,
tls.certificateRefs.namemust match thesecretNamein SecretProviderClass resource.Create a corresponding
HTTPRouteto configure ingress traffic routing to thehttpbinservice over HTTPS using the following manifest:cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin spec: parentRefs: - name: httpbin-gateway hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /status - path: type: PathPrefix value: /delay backendRefs: - name: httpbin port: 8000 EOFGet the ingress gateway's external IP address and secure port using the following commands:
kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.status.addresses[0].value}') export SECURE_INGRESS_PORT=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')Send an HTTPS request to access the
httpbinservice:curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \ --cacert httpbin_certs/example.com.crt "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"The output should show the
httpbinservice return the 418 I’m a Teapot code.Note
To configure HTTPS ingress access to an HTTPS service, update the TLS mode in the gateway definition to
Passthrough. This configuration instructs the gateway to pass the ingress traffic as is, without terminating TLS.
Annotation customizations
You can add annotations under spec.infrastructure.annotations to configure load balancer settings for the Gateway. For instance, to create an internal load balancer attached to a specific subnet, you can create a Gateway with the following annotations:
spec:
# ... existing spec content ...
infrastructure:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "my-subnet"
ConfigMap customizations
The Istio service mesh add-on supports customizations of the resources generated for the Gateways, including:
- Service
- Deployment
- Horizontal Pod Autoscaler (HPA)
- Pod Disruption Budget (PDB)
The default settings for these resources are set in the istio-gateway-class-defaults ConfigMap in the aks-istio-system namespace. This ConfigMap must have the gateway.istio.io/defaults-for-class label set to istio for the customizations to take effect for all Gateways with spec.gatewayClassName: istio. The GatewayClass-level ConfigMap is installed by default in the aks-istio-system namespace when the Managed Gateway API installation is enabled. It could take up to five minutes for the istio-gateway-class-defaults ConfigMap to get deployed after installing the Managed Gateway API CRDs.
kubectl get configmap istio-gateway-class-defaults -n aks-istio-system -o yaml
...
data:
horizontalPodAutoscaler: |
spec:
minReplicas: 2
maxReplicas: 5
podDisruptionBudget: |
spec:
minAvailable: 1
...
You can modify these settings for all Istio Gateways at a GatewayClass level by updating the istio-gateway-class-defaults ConfigMap, or you can set them for individual Gateway resources. For both the GatewayClass-level and Gateway-level ConfigMaps, you must add fields to the allow list for the given resource. If there are customizations both for the GatewayClass and an individual Gateway, the Gateway-level configuration takes precedence.
Deployment customization allow list fields
| Field path | Description |
|---|---|
metadata.labels |
Deployment labels |
metadata.annotations |
Deployment annotations |
spec.replicas |
Deployment replica count |
spec.template.metadata.labels |
Pod labels |
spec.template.metadata.annotations |
Pod annotations |
spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms |
Node affinity |
spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution |
Node affinity |
spec.template.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution |
Pod affinity |
spec.template.spec.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution |
Pod affinity |
spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution |
Pod anti-affinity |
spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution |
Pod anti-affinity |
spec.template.spec.containers.resizePolicy |
Container resource utilization |
spec.template.spec.containers.resources.limits |
Container resource utilization |
spec.template.spec.containers.resources.requests |
Container resource utilization |
spec.template.spec.containers.stdin |
Container debugging |
spec.template.spec.containers.stdinOnce |
Container debugging |
spec.template.spec.nodeSelector |
Pod scheduling |
spec.template.spec.nodeName |
Pod scheduling |
spec.template.spec.tolerations |
Pod scheduling |
spec.template.spec.topologySpreadConstraints |
Pod scheduling |
Service customization allow list fields
| Field path | Description |
|---|---|
metadata.labels |
Service labels |
metadata.annotations |
Service annotations |
spec.type |
Service type |
spec.loadBalancerSourceRanges |
Service load balancer settings |
spec.loadBalancerClass |
Service load balancer settings |
spec.externalTrafficPolicy |
Service traffic policy |
spec.internalTrafficPolicy |
Service traffic policy |
HorizontalPodAutoscaler (HPA) customization allow list fields
| Field path | Description |
|---|---|
metadata.labels |
HPA labels |
metadata.annotations |
HPA annotations |
spec.behavior.scaleUp.stabilizationWindowSeconds |
HPA scale-up behavior |
spec.behavior.scaleUp.selectPolicy |
HPA scale-up behavior |
spec.behavior.scaleUp.policies |
HPA scale-up behavior |
spec.behavior.scaleDown.stabilizationWindowSeconds |
HPA scale-down behavior |
spec.behavior.scaleDown.selectPolicy |
HPA scale-down behavior |
spec.behavior.scaleDown.policies |
HPA scale-down behavior |
spec.metrics |
HPA scaling resource metrics |
spec.minReplicas |
HPA minimum replica count. Must not be below 2. |
spec.maxReplicas |
HPA maximum replica count |
PodDisruptionBudget (PDB) customization allow list fields
| Field path | Description |
|---|---|
metadata.labels |
PDB labels |
metadata.annotations |
PDB annotations |
spec.minAvailable |
PDB minimum availability |
spec.unhealthyPodEvictionPolicy |
PDB eviction policy |
Note
Modifying the PDB minimum availability and eviction policy can lead to potential errors during cluster/node upgrade and deletion operations. Follow the PDB troubleshooting guide to address UpgradeFailed errors due to PDB eviction failures.
Configure GatewayClass-level settings
Update the
GatewayClass-level ConfigMap in theaks-istio-systemnamespace using thekubectl edit configmapcommand:kubectl edit cm istio-gateway-class-defaults -n aks-istio-systemEdit the resource settings in the
datasection as needed. For example, to update the HPA min/max replicas and add a label to theDeployment, modify the ConfigMap as follows:... data: deployment: | metadata: labels: test.azureservicemesh.io/deployment-config: "updated" horizontalPodAutoscaler: | spec: minReplicas: 3 maxReplicas: 6 podDisruptionBudget: | spec: minAvailable: 1 ...Note
Only one ConfigMap per
GatewayClassis allowed.Now, you should see the
HPAforhttpbin-gatewaythat you created earlier get updated with the new min/max values. Verify theHPAsettings using thekubectl get hpacommand.kubectl get hpa httpbin-gateway-istioExample output:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 3 6 3 36mVerify the
Deploymentis updated with the new label using thekubectl get deploymentcommand.kubectl get deployment httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'Example output:
updated
Configure settings for a specific gateway
Create a ConfigMap with resource customizations for the
httpbinGateway using the following manifest:kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: gw-options data: horizontalPodAutoscaler: | spec: minReplicas: 2 maxReplicas: 4 deployment: | metadata: labels: test.azureservicemesh.io/deployment-config: "updated-per-gateway" EOFUpdate the
httpbinGatewayto reference the ConfigMap:spec: # ... existing spec content ... infrastructure: parametersRef: group: "" kind: ConfigMap name: gw-optionsApply the update using the
kubectl applycommand.kubectl apply -f httpbin-gateway-updated.yamlVerify the
HPAis updated with the new min/max values using thekubectl get hpacommand. If you also configured theGatewayClass-level ConfigMap, theGateway-level settings should take precedence.kubectl get hpa httpbin-gateway-istioExample output:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 2 4 2 4h14mInspect the
Deploymentlabels to ensure that thetest.azureservicemesh.io/deployment-configis updated to the new value using thekubectl get deploymentcommand.kubectl get deployment httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'Example output:
updated-per-gateway
Clean up resources
If you no longer need the resources created in this article, you can delete them to avoid incurring any charges.
Delete the Gateway and HTTPRoute resources using the following
kubectl deletecommands:kubectl delete gateways.gateway.networking.k8s.io httpbin-gateway kubectl delete httproute httpbinIf you created a ConfigMap to customize your Gateway resources, delete it using the
kubectl delete configmapcommand.kubectl delete configmap gw-optionsIf you created a SecretProviderClass and secret to use for TLS termination delete the resources using the following
kubectl deletecommands:kubectl delete secret httpbin-credential kubectl delete pod secrets-store-sync-httpbin kubectl delete secretproviderclass httpbin-credential-spc