Exercise 2: Deploy an Application into the Mesh
In this exercise, you will create a namespace that participates in the mesh and deploy two versions of a simple web application.
Task 1: Create a Mesh-Enabled Namespace
Create a namespace for the demo application and enable sidecar injection using the installed Istio revision.
kubectl create namespace istio-demo kubectl label namespace istio-demo istio.io/rev=$ISTIO_REVISIONkubectl create namespace istio-demo kubectl label namespace istio-demo istio.io/rev=$ISTIO_REVISIONWarning
With the AKS Istio add-on you must use the revision label
istio.io/rev=<revision>(for exampleistio.io/rev=asm-1-24), not the genericistio-injection=enabledlabel you may have seen in the upstream open-source Istio documentation.The add-on runs a revisioned control plane so it can manage canary upgrades between Istio versions. The plain
istio-injection=enabledlabel does not match a revisioned control plane, so the add-on skips sidecar injection for that namespace and your pods come up without a proxy. This is why the lab reads the installed revision into$ISTIO_REVISIONin Exercise 1 and uses it here.
Task 2: Deploy Two Application Versions
Deploy two versions of a simple web application and a single Kubernetes service that targets both versions.
@" apiVersion: apps/v1 kind: Deployment metadata: name: web-v1 namespace: istio-demo spec: replicas: 2 selector: matchLabels: app: web version: v1 template: metadata: labels: app: web version: v1 spec: containers: - name: web image: ghcr.io/microsoft/k8s-on-azure-workshop/hello-app:1.0 ports: - containerPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: web-v2 namespace: istio-demo spec: replicas: 2 selector: matchLabels: app: web version: v2 template: metadata: labels: app: web version: v2 spec: containers: - name: web image: ghcr.io/microsoft/k8s-on-azure-workshop/hello-app:2.0 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: web namespace: istio-demo spec: selector: app: web ports: - port: 80 targetPort: 8080 name: http "@ | kubectl apply -f -cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: web-v1 namespace: istio-demo spec: replicas: 2 selector: matchLabels: app: web version: v1 template: metadata: labels: app: web version: v1 spec: containers: - name: web image: ghcr.io/microsoft/k8s-on-azure-workshop/hello-app:1.0 ports: - containerPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: web-v2 namespace: istio-demo spec: replicas: 2 selector: matchLabels: app: web version: v2 template: metadata: labels: app: web version: v2 spec: containers: - name: web image: ghcr.io/microsoft/k8s-on-azure-workshop/hello-app:2.0 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: web namespace: istio-demo spec: selector: app: web ports: - port: 80 targetPort: 8080 name: http EOFConfirm that each application pod has an Istio sidecar.
kubectl get pods -n istio-demokubectl get pods -n istio-demoEach pod should show
2/2containers ready: the application container and the Istio sidecar proxy.List the individual containers in each pod to confirm that the Istio sidecar (
istio-proxy) has been injected alongside the application container (web).kubectl get pods -n istio-demo ` -o "custom-columns=NAME:.metadata.name,INIT-CONTAINERS:.spec.initContainers[*].name,CONTAINERS:.spec.containers[*].name"kubectl get pods -n istio-demo \ -o 'custom-columns=NAME:.metadata.name,INIT-CONTAINERS:.spec.initContainers[*].name,CONTAINERS:.spec.containers[*].name'You should see output similar to the following:
NAME INIT-CONTAINERS CONTAINERS web-v1-7f9c8b8d6f-abcde istio-validation,istio-proxy web web-v1-7f9c8b8d6f-fghij istio-validation,istio-proxy web web-v2-6d5b7c9a4e-klmno istio-validation,istio-proxy web web-v2-6d5b7c9a4e-pqrst istio-validation,istio-proxy webInfo
The AKS Istio add-on uses Kubernetes native sidecar containers (an
initContainerwithrestartPolicy: Always), which is whyistio-proxyappears underINIT-CONTAINERSrather than alongsidewebin theCONTAINERScolumn. The behaviour is otherwise identical to a classic sidecar — Envoy runs for the lifetime of the pod, intercepts all traffic, and counts toward the pod’sREADYstatus. Theistio-validationinit container runs once at startup to verify thatiptablesrules were applied correctly.