项目作者: cloudacademy

项目描述 :
Azure AKS VoteApp Demo
高级语言:
项目地址: git://github.com/cloudacademy/aks-voteapp-demo.git
创建时间: 2020-04-28T01:19:48Z
项目社区:https://github.com/cloudacademy/aks-voteapp-demo

开源协议:

下载


AKS VoteApp Deployment Instructions

The following instructions are used to demonstrate how to provision an AKS cluster on Azure and deploy a cloud native application into it.

:metal:

The cloud native application is architected using microservices and is presented to the user as a web application. The application frontend provides the end-user with the ability to vote on one of 6 programming languages: C#, Python, JavaScript, Go, Java, and/or NodeJS. Voting results in AJAX calls being made from the browser to an API which in turn then saves the results into a MongoDB database.

AKSDeployment

Updates/Changelog

Thu 15 Feb 2024

  • Removed --docker-bridge-address option on az aks create as this has been deprecated
  • Corrected name of nginx svc from aks-nginx-ingress-nginx-ingress to aks-nginx-ingress-controller
  • Increased Kubernetes version to 1.27.7 to align with current Azure default
  • Updated network policy selectors to use correct podSelector labels for nginx
  • Added commands to delete the service principle

Mon 16 Jan 2023 11:57:20 NZDT

  • Updated instructions and retested end-to-end
  • Added instruction to create resource group
  • Added --location parameter to commands that use it
  • Removed deprecated --skip-assignment parameter
  • Upgraded cluster version to 1.25.2
  • Updated DNS testing to use the container image cloudacademydevops/networkutils:v2
  • Updated the Ingress resources to networking.k8s.io/v1
  • Updated networkpolicy curl commands to include --max-time 5 to control connection timeout

Tue 3 Nov 2020 20:51:59 NZDT

  • Updated instructions and retested end-to-end
  • Upgraded cluster version to 1.18.8
  • Mongo deployment now pinned down to use 4.2 to ensure replication setup initiates
  • Helm nginx-ingress deployment updated
  • Minor fixes to various kubectl commands

Client Tools

Tested with the following client tool versions

  • az 2.44.1
  • kubectl 1.27.7
  • helm 3.10.3

VoteApp

Along the way, you’ll get to see how to work with the following AKS cluster resources:

  • Namespace
  • Secret
  • Deployment
  • Service
  • StatefulSet
  • PersistentVolume
  • PersistentVolumeClaim
  • IngressController (Nginx)
  • Ingress
  • NetworkPolicy

STEP 1:

Create a new AKS cluster

STEP 1.1:

Authenticate the Azure CLI. In the terminal execute the following command:

  1. az login

STEP 1.2:

Define the variables used during the setup and installation:

  1. {
  2. CLUSTER_NAME=akstest
  3. RESOURCE_GROUP=aks
  4. LOCATION=westus
  5. VNET_NAME=cloudacademy-aks-vnet
  6. K8S_VERSION=1.27.7
  7. }

STEP 1.3:

Create new resource group.

  1. az group create --location $LOCATION --resource-group $RESOURCE_GROUP

STEP 1.4:

Create a new service principal. The AKS cluster will later be created with this.

  1. SP=$(az ad sp create-for-rbac --name spdemocluster)
  2. APPID=$(echo $SP | jq -r .appId)
  3. PASSWD=$(echo $SP | jq -r .password)
  4. echo APPID: $APPID
  5. echo PASSWD: $PASSWD

STEP 1.5:

Create a new vnet and subnet for the AKS cluster

  1. az network vnet create \
  2. --name $VNET_NAME \
  3. --resource-group $RESOURCE_GROUP \
  4. --location $LOCATION \
  5. --address-prefixes 10.0.0.0/8 \
  6. --subnet-name aks-subnet \
  7. --subnet-prefix 10.240.0.0/16

STEP 1.6:

Assign the contributor role to the service principal scoped on the vnet previously created

  1. VNETID=$(az network vnet show \
  2. --name $VNET_NAME \
  3. --resource-group $RESOURCE_GROUP \
  4. --query id \
  5. -o tsv)
  6. echo VNETID: $VNETID
  7. az role assignment create \
  8. --assignee $APPID \
  9. --scope $VNETID \
  10. --role Contributor

STEP 1.7:

Create the AKS cluster and place it in the vnet subnet previously created

Standard_B2ms
1.15.10

  1. SUBNETID=$(az network vnet subnet show \
  2. --name aks-subnet \
  3. --resource-group $RESOURCE_GROUP \
  4. --vnet-name $VNET_NAME \
  5. --query id \
  6. -o tsv)
  7. echo SUBNETID: $SUBNETID
  8. az aks create \
  9. --name $CLUSTER_NAME \
  10. --resource-group $RESOURCE_GROUP \
  11. --location $LOCATION \
  12. --node-count 2 \
  13. --node-vm-size Standard_D4s_v3 \
  14. --vm-set-type VirtualMachineScaleSets \
  15. --kubernetes-version $K8S_VERSION \
  16. --network-plugin azure \
  17. --service-cidr 10.0.0.0/16 \
  18. --dns-service-ip 10.0.0.10 \
  19. --vnet-subnet-id $SUBNETID \
  20. --generate-ssh-keys \
  21. --network-policy azure \
  22. --service-principal $APPID \
  23. --client-secret $PASSWD

This takes between 5-10 minutes to complete so sit back and relax, its major chill time :+1:

Congrats!!
You’ve just baked yourself a fresh AKS Kubernetes cluster!!

STEP 2:

Test the kubectl client cluster authencation

  1. az aks get-credentials -g $RESOURCE_GROUP --name $CLUSTER_NAME --admin
  2. kubectl get nodes
  1. kubectl config view
  2. kubectl config get-contexts
  3. kubectl config current-context

STEP 3:

Install the Nginx Ingress Controller. This will allow us to direct inbound exteranl HTTP calls to the Frontend and API services that will be deployed into the AKS cluster.

STEP 3.1:

Create the nginx-ingress namespace - holds the Nginx Ingress Controller components.

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Namespace
  4. metadata:
  5. name: nginx-ingress
  6. labels:
  7. name: nginx-ingress
  8. EOF

STEP 3.2:

Use Helm to install the Nginx Ingress Controller.

Notes:

  1. The helm client needs to be installed locally
  2. This has beem successfully tested with helm version v3.10.3
  3. The helm client authenticates to the AKS cluster using the same ~/.kube/config credentials established earlier
  4. This has beem successfully tested with the helm chart nginx-stable/nginx-ingress version 0.16.0 and app version 3.0.0
  1. helm version
  2. helm repo add nginx-stable https://helm.nginx.com/stable
  3. helm repo update
  4. helm search repo nginx-ingress
  5. helm install aks-nginx-ingress nginx-stable/nginx-ingress --namespace nginx-ingress

STEP 3.3:

Query the Nginx Ingress Controller and determine the public ip address that has been assigned to it.

Wait until the Nginx Ingress Controller has been allocated a public IP address

  1. kubectl get svc aks-nginx-ingress-controller -n nginx-ingress --watch

Use Ctrl-C key sequence to exit the watch

Notes:

  1. The public IP address will be used to create both the API and Frontend service FQDNs used later on
  2. The API FQDN will be used to within the API’s Ingress resource for host based path routing
  3. The Frontend FQDN will be used to within the Frontend’s Ingress resource for host based path routing
  4. The https://nip.io/ dynamic DNS service is being used to provide wildcard DNS
  1. kubectl get svc aks-nginx-ingress-controller -n nginx-ingress -o json
  2. INGRESS_PUBLIC_IP=$(kubectl get svc aks-nginx-ingress-controller -n nginx-ingress -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
  3. echo INGRESS_PUBLIC_IP: $INGRESS_PUBLIC_IP
  4. API_PUBLIC_FQDN=api.$INGRESS_PUBLIC_IP.nip.io
  5. FRONTEND_PUBLIC_FQDN=frontend.$INGRESS_PUBLIC_IP.nip.io
  6. echo API_PUBLIC_FQDN: $API_PUBLIC_FQDN
  7. echo FRONTEND_PUBLIC_FQDN: $FRONTEND_PUBLIC_FQDN

STEP 4:

Create the cloudacademy namespace - holds the main sample cloud native application components

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Namespace
  4. metadata:
  5. name: cloudacademy
  6. labels:
  7. name: cloudacademy
  8. EOF

Configure the cloudacademy namespace to be the default

  1. kubectl config set-context --current --namespace cloudacademy

STEP 5:

Deploy MongoDB 3 x ReplicaSet

AKSDeployment

STEP 5.1:

Display the available AKS storage classes. We use the default storage class in the following MongoDb deployment.

  1. kubectl get storageclass

STEP 5.2:

Create a new Mongo StatefulSet name mongo

Note: security (—auth flag) hasn’t been enabled on the MongoDb database - done to make the demonstration quicker.

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: apps/v1
  3. kind: StatefulSet
  4. metadata:
  5. name: mongo
  6. namespace: cloudacademy
  7. spec:
  8. serviceName: mongo
  9. replicas: 3
  10. selector:
  11. matchLabels:
  12. role: db
  13. template:
  14. metadata:
  15. labels:
  16. role: db
  17. env: demo
  18. replicaset: rs0.main
  19. spec:
  20. affinity:
  21. podAntiAffinity:
  22. preferredDuringSchedulingIgnoredDuringExecution:
  23. - weight: 100
  24. podAffinityTerm:
  25. labelSelector:
  26. matchExpressions:
  27. - key: replicaset
  28. operator: In
  29. values:
  30. - rs0.main
  31. topologyKey: kubernetes.io/hostname
  32. terminationGracePeriodSeconds: 10
  33. containers:
  34. - name: mongo
  35. image: mongo:4.2
  36. command:
  37. - "numactl"
  38. - "--interleave=all"
  39. - "mongod"
  40. - "--wiredTigerCacheSizeGB"
  41. - "0.1"
  42. - "--bind_ip"
  43. - "0.0.0.0"
  44. - "--replSet"
  45. - "rs0"
  46. ports:
  47. - containerPort: 27017
  48. volumeMounts:
  49. - name: mongodb-persistent-storage-claim
  50. mountPath: /data/db
  51. volumeClaimTemplates:
  52. - metadata:
  53. name: mongodb-persistent-storage-claim
  54. spec:
  55. accessModes:
  56. - ReadWriteOnce
  57. storageClassName: default
  58. resources:
  59. requests:
  60. storage: 0.5Gi
  61. EOF

STEP 5.3:

Examine the Mongo Pods launch ordered sequence

  1. kubectl get pods --watch
  2. kubectl get pods
  3. kubectl get pods --show-labels
  4. kubectl get pods -l role=db

Use Ctrl-C key sequence to exit the watch

Display the MongoDB Pods, Persistent Volumes and Persistent Volume Claims

  1. kubectl get pod,pv,pvc

STEP 5.4:

Create a new Headless Service for Mongo named mongo

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: mongo
  6. namespace: cloudacademy
  7. labels:
  8. role: db
  9. env: demo
  10. spec:
  11. ports:
  12. - port: 27017
  13. targetPort: 27017
  14. clusterIP: None
  15. selector:
  16. role: db
  17. EOF

STEP 5.5:

Examine the Mongo Headless Service

  1. kubectl get svc

Examine the DNS records for the Mongo Headless Service

  1. kubectl run -i --tty --restart=Never --rm utils --image cloudacademydevops/networkutils:v2 -- host mongo

Examine the individual DNS records for the Mongo Headless Service

  1. kubectl run -i --tty --restart=Never --rm utils --image cloudacademydevops/networkutils:v2 -- bash -c 'for i in {0..2}; do host mongo-$i.mongo; done'

STEP 5.6:

Confirm that the mongo shell can resolve each of the 3 mongo headless service assigned dns names:

  1. for i in {0..2}; do kubectl exec -it mongo-0 -- mongo mongo-$i.mongo --eval "print('mongo-$i.mongo succeeded')" && echo; done

On the mongo-0 pod, initialise the mongo database replica set:

  1. cat << EOF | kubectl exec -it mongo-0 -- mongo
  2. rs.initiate();
  3. sleep(2000);
  4. rs.add("mongo-1.mongo:27017");
  5. sleep(2000);
  6. rs.add("mongo-2.mongo:27017");
  7. sleep(2000);
  8. cfg = rs.conf();
  9. cfg.members[0].host = "mongo-0.mongo:27017";
  10. rs.reconfig(cfg, {force: true});
  11. sleep(5000);
  12. EOF

Confirm the mongo database replication status:

  1. kubectl exec -it mongo-0 -- mongo --eval "rs.status()" | grep "PRIMARY\|SECONDARY"

STEP 5.7:

Load the initial voting app data into the Mongo database

  1. cat << EOF | kubectl exec -it mongo-0 -- mongo
  2. use langdb;
  3. db.languages.insert({"name" : "csharp", "codedetail" : { "usecase" : "system, web, server-side", "rank" : 5, "compiled" : false, "homepage" : "https://dotnet.microsoft.com/learn/csharp", "download" : "https://dotnet.microsoft.com/download/", "votes" : 0}});
  4. db.languages.insert({"name" : "python", "codedetail" : { "usecase" : "system, web, server-side", "rank" : 3, "script" : false, "homepage" : "https://www.python.org/", "download" : "https://www.python.org/downloads/", "votes" : 0}});
  5. db.languages.insert({"name" : "javascript", "codedetail" : { "usecase" : "web, client-side", "rank" : 7, "script" : false, "homepage" : "https://en.wikipedia.org/wiki/JavaScript", "download" : "n/a", "votes" : 0}});
  6. db.languages.insert({"name" : "go", "codedetail" : { "usecase" : "system, web, server-side", "rank" : 12, "compiled" : true, "homepage" : "https://golang.org", "download" : "https://golang.org/dl/", "votes" : 0}});
  7. db.languages.insert({"name" : "java", "codedetail" : { "usecase" : "system, web, server-side", "rank" : 1, "compiled" : true, "homepage" : "https://www.java.com/en/", "download" : "https://www.java.com/en/download/", "votes" : 0}});
  8. db.languages.insert({"name" : "nodejs", "codedetail" : { "usecase" : "system, web, server-side", "rank" : 20, "script" : false, "homepage" : "https://nodejs.org/en/", "download" : "https://nodejs.org/en/download/", "votes" : 0}});
  9. EOF

STEP 5.8:

Confirm data has been loaded correctly

  1. kubectl exec -it mongo-0 -- mongo langdb --eval "db.languages.find().pretty()"

STEP 6:

AKSDeployment - API

Deploy the API consisting of a Deployment, Service, and Ingress:

STEP 6.1:

Create a secret to store the mongodb connection credentials

Note: this is for demonstration purposes only - security (auth) hasn’t been enabled on the MongoDb database.

The username and password values need to be base64 encode first like so

  1. echo -n 'admin' | base64
  2. echo -n 'password' | base64
  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: mongodb-secret
  6. namespace: cloudacademy
  7. data:
  8. username: YWRtaW4=
  9. password: cGFzc3dvcmQ=
  10. EOF

API: create deployment resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: api
  6. namespace: cloudacademy
  7. labels:
  8. role: api
  9. env: demo
  10. spec:
  11. replicas: 4
  12. strategy:
  13. type: RollingUpdate
  14. rollingUpdate:
  15. maxSurge: 1
  16. maxUnavailable: 25%
  17. selector:
  18. matchLabels:
  19. role: api
  20. template:
  21. metadata:
  22. labels:
  23. role: api
  24. spec:
  25. containers:
  26. - name: api
  27. image: cloudacademydevops/api:v2
  28. imagePullPolicy: Always
  29. env:
  30. - name: MONGO_CONN_STR
  31. value: mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo:27017/langdb?replicaSet=rs0
  32. - name: MONGO_USERNAME
  33. valueFrom:
  34. secretKeyRef:
  35. name: mongodb-secret
  36. key: username
  37. - name: MONGO_PASSWORD
  38. valueFrom:
  39. secretKeyRef:
  40. name: mongodb-secret
  41. key: password
  42. ports:
  43. - containerPort: 8080
  44. livenessProbe:
  45. httpGet:
  46. path: /ok
  47. port: 8080
  48. initialDelaySeconds: 2
  49. periodSeconds: 5
  50. readinessProbe:
  51. httpGet:
  52. path: /ok
  53. port: 8080
  54. initialDelaySeconds: 5
  55. periodSeconds: 5
  56. successThreshold: 1
  57. EOF

STEP 6.2:

API: create service resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: api
  6. namespace: cloudacademy
  7. labels:
  8. role: api
  9. env: demo
  10. spec:
  11. ports:
  12. - protocol: TCP
  13. port: 8080
  14. selector:
  15. role: api
  16. EOF

STEP 6.3:

API: create ingress resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: networking.k8s.io/v1
  3. kind: Ingress
  4. metadata:
  5. name: api
  6. namespace: cloudacademy
  7. annotations:
  8. nginx.ingress.kubernetes.io/rewrite-target: /
  9. spec:
  10. ingressClassName: nginx
  11. rules:
  12. - host: $API_PUBLIC_FQDN
  13. http:
  14. paths:
  15. - path: /
  16. pathType: Prefix
  17. backend:
  18. service:
  19. name: api
  20. port:
  21. number: 8080
  22. EOF

STEP 6.4:

  • Examine the rollout of the API deployment
  • Examine the pods to confirm that they are up and running
  • Examine the API pod log to see that it has successfully connected to the MongoDB replicaset
  • Examine the API service details
  1. kubectl rollout status deployment api
  2. kubectl get pods
  3. kubectl get pods -l role=api
  4. kubectl logs <API_POD_NAME_HERE>
  5. kubectl get svc

STEP 6.5:

Test the API route url - test the /ok, /languages, and /languages/{name} endpoints

  1. curl -s $API_PUBLIC_FQDN/ok

Note: The following commands leverage the jq utility to format the json data responses

  1. curl -s $API_PUBLIC_FQDN/languages | jq .
  2. curl -s $API_PUBLIC_FQDN/languages/go | jq .
  3. curl -s $API_PUBLIC_FQDN/languages/java | jq .
  4. curl -s $API_PUBLIC_FQDN/languages/nodejs | jq .

STEP 7:

AKSDeployment

Create a new frontend Deployment

Notes:

  1. The value stored in the $API_PUBLIC_FQDN variable is injected into the frontend container’s REACT_APP_APIHOSTPORT environment var - this tells the frontend where to send browser initiated API AJAX calls

STEP 7.1:

Frontend: create deployment resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: frontend
  6. namespace: cloudacademy
  7. labels:
  8. role: frontend
  9. env: demo
  10. spec:
  11. replicas: 4
  12. strategy:
  13. type: RollingUpdate
  14. rollingUpdate:
  15. maxSurge: 1
  16. maxUnavailable: 25%
  17. selector:
  18. matchLabels:
  19. role: frontend
  20. template:
  21. metadata:
  22. labels:
  23. role: frontend
  24. spec:
  25. containers:
  26. - name: frontend
  27. image: cloudacademydevops/frontend:v10
  28. imagePullPolicy: Always
  29. env:
  30. - name: REACT_APP_APIHOSTPORT
  31. value: $API_PUBLIC_FQDN
  32. ports:
  33. - containerPort: 8080
  34. livenessProbe:
  35. httpGet:
  36. path: /ok
  37. port: 8080
  38. initialDelaySeconds: 2
  39. periodSeconds: 5
  40. readinessProbe:
  41. httpGet:
  42. path: /ok
  43. port: 8080
  44. initialDelaySeconds: 5
  45. periodSeconds: 5
  46. successThreshold: 1
  47. EOF

STEP 7.2:

Frontend: create service resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: frontend
  6. namespace: cloudacademy
  7. labels:
  8. role: frontend
  9. env: demo
  10. spec:
  11. ports:
  12. - protocol: TCP
  13. port: 8080
  14. selector:
  15. role: frontend
  16. EOF

STEP 7.3:

Frontend: create ingress resource

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: networking.k8s.io/v1
  3. kind: Ingress
  4. metadata:
  5. name: frontend
  6. namespace: cloudacademy
  7. annotations:
  8. nginx.ingress.kubernetes.io/rewrite-target: /
  9. spec:
  10. ingressClassName: nginx
  11. rules:
  12. - host: $FRONTEND_PUBLIC_FQDN
  13. http:
  14. paths:
  15. - path: /
  16. pathType: Prefix
  17. backend:
  18. service:
  19. name: frontend
  20. port:
  21. number: 8080
  22. EOF

STEP 7.4:

Examine the rollout of the Frontend Deployment

  1. kubectl rollout status deployment frontend
  2. kubectl get pods
  3. kubectl get pods -l role=frontend

STEP 7.5:

Use the curl command to test the application via the frontend route url

  1. curl -s -I $FRONTEND_PUBLIC_FQDN
  2. curl -s -i $FRONTEND_PUBLIC_FQDN

Generate the frontend URL

  1. echo http://$FRONTEND_PUBLIC_FQDN

Now test the full end-to-end application using the Chrome browser…

Note: Use the Developer Tools within the Chrome browser to record, filter, and observe the AJAX traffic (XHR) which is generated when any of the +1 vote buttons are clicked.

VoteApp

STEP 8

Query the MongoDb database directly to observe the updated vote data.

  1. kubectl exec -it mongo-0 -- mongo langdb --eval "db.languages.find().pretty()"

STEP 9

Setup and install Network Policies to control pod-to-pod traffic

STEP 9.1

Default deny all network policy for pod-to-pod traffic within the cloudacademy namespace

  1. cat << EOF | kubectl apply -f -
  2. apiVersion: networking.k8s.io/v1
  3. kind: NetworkPolicy
  4. metadata:
  5. name: default-deny-all
  6. namespace: cloudacademy
  7. spec:
  8. podSelector: {}
  9. policyTypes:
  10. - Ingress
  11. EOF

Test to confirm that the frontend traffic path is now blocked

  1. curl -vv -i --max-time 5 $FRONTEND_PUBLIC_FQDN

STEP 9.2

Allow mongo-to-mongo pod traffic, required for MongoDb data replication

  1. cat << EOF | kubectl apply -f -
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: allow-from-mongo-to-mongo
  6. namespace: cloudacademy
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. role: db
  11. ingress:
  12. - from:
  13. - podSelector:
  14. matchLabels:
  15. role: db
  16. EOF

STEP 9.3

Allow api-to-mongo pod traffic, required to allow the API to read/write data into the MongoDb database

  1. cat << EOF | kubectl apply -f -
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: allow-from-api-to-mongo
  6. namespace: cloudacademy
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. role: db
  11. ingress:
  12. - from:
  13. - podSelector:
  14. matchLabels:
  15. role: api
  16. EOF

STEP 9.4

Allow ingress-to-api pod traffic, required to allow API ajax calls from the browser

  1. cat << EOF | kubectl apply -f -
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: allow-from-ingress-to-api
  6. namespace: cloudacademy
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. role: api
  11. ingress:
  12. - from:
  13. - podSelector:
  14. matchLabels:
  15. app.kubernetes.io/instance: aks-nginx-ingress
  16. namespaceSelector:
  17. matchLabels:
  18. name: nginx-ingress
  19. EOF

STEP 9.5

Allow ingress-to-frontend pod traffic, required to allow the frontend (html, js, css) to be requested by the browser

  1. cat << EOF | kubectl apply -f -
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: allow-from-ingress-to-frontend
  6. namespace: cloudacademy
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. role: frontend
  11. ingress:
  12. - from:
  13. - podSelector:
  14. matchLabels:
  15. app.kubernetes.io/instance: aks-nginx-ingress
  16. namespaceSelector:
  17. matchLabels:
  18. name: nginx-ingress
  19. EOF

STEP 9.6

Allow ingress-to-kube-dns from pod traffic in cloudacademy namespace, required to allow pod dns traffic to resolve

  1. cat << EOF | kubectl apply -f -
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: allow-from-cloudacademy-ns-to-kube-dns
  6. namespace: kube-system
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. k8s-app: kube-dns
  11. ingress:
  12. - from:
  13. - namespaceSelector:
  14. matchLabels:
  15. name: cloudacademy
  16. EOF

Step 10

Test to confirm that the frontend traffic path is now repaired and working

  1. curl -vv -i --max-time 5 $FRONTEND_PUBLIC_FQDN

Test the application again within the browser and generate some voting traffic

Query the MongoDb database directly to observe the updated vote data

  1. kubectl exec -it mongo-0 -- mongo langdb --eval "db.languages.find().pretty()"

STEP 11

When you’ve finished with the AKS cluster and no longer need it tear it down to avoid ongoing charges!!

  1. az aks delete --name $CLUSTER_NAME -g $RESOURCE_GROUP

Step 12

Find the ID of the spdemocluster service principle we created earlier, and delete it:

  1. sp_id=$(az ad sp list --display-name spdemocluster --query "[0].id" -o tsv)
  2. echo sp_id=$sp_id
  3. az ad sp delete --id $sp_id
  4. app_id=$(az ad app list --display-name spdemocluster --query "[0].id" -o tsv)
  5. echo app_id=$app_id
  6. az ad app delete --id $app_id

Good luck with your AKS adventures!!

:rocket:

http://cloudacademy.com