Deploy the microservices of the Spring Petclinic app to the AKS cluster
You now have an AKS cluster deployed and a container registry holding all the microservices docker images. As a next step you will deploy these images from the container registry to your AKS cluster.
To do this you will first need to login to your container registry to push the container images and connect to your AKS cluster to be able to issue kubectl statements. Next you will need to provide YAML deployments and execute these on your cluster. The below links can help you get started on this.
Deploy all the microservices to the cluster in a dedicated spring-petclinic namespace and make sure they can connect to the database.
Make sure the api-gateway and admin-server microservices have public IP addresses available to them. Also make sure the spring-cloud-config-server is discoverable at the config-server DNS name within the cluster.
You also want to make sure the config-server is deployed first and up and running, followed by the discovery-server. Only once these 2 are properly up and running, start deploying the other microservices. The order of the other services doesn’t matter and can be done in any order.
You can use the below YAML file as a basis for your deployments on AKS:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: #appname#
name: #appname#
spec:
replicas: 1
selector:
matchLabels:
app: #appname#
template:
metadata:
labels:
app: #appname#
spec:
containers:
- image: #image#
name: #appname#
env:
- name: "CONFIG_SERVER_URL"
valueFrom:
configMapKeyRef:
name: config-server
key: CONFIG_SERVER_URL
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /actuator/health
port: #appport#
scheme: HTTP
initialDelaySeconds: 180
successThreshold: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /actuator/health
port: #appport#
scheme: HTTP
initialDelaySeconds: 10
successThreshold: 1
ports:
- containerPort: #appport#
name: http
protocol: TCP
- containerPort: 9779
name: prometheus
protocol: TCP
- containerPort: 8778
name: jolokia
protocol: TCP
securityContext:
privileged: false
---
apiVersion: v1
kind: Service
metadata:
labels:
app: #appname#
name: #service_name#
spec:
ports:
- port: #appport#
protocol: TCP
targetPort: #appport#
selector:
app: #appname#
type: #service_type#
Step by step guidance
-
As a first step, make sure you can log in to the AKS cluster. The az aks get-credentials command will populate your kubeconfig file.
az aks get-credentials -n $AKSCLUSTER -g $RESOURCE_GROUP
-
To verify that you can successfully connect to the cluster, try out a kubectl statement.
kubectl get pods --all-namespaces
This should output pods in the kube-system namespace.
In case the kubectl statement isn’t available for you, you can install it with sudo az aks install-cli.
-
You will now create a namespace in the cluster for your spring petclinic microservices.
NAMESPACE=spring-petclinic kubectl create ns $NAMESPACE
-
On your local filesystem create a
kubernetes
directory in the root of the project and navigate to it.cd ~/workspaces/java-microservices-aks-lab/src mkdir kubernetes cd kubernetes
-
In this directory create a file named config-map.yml with the below code and save the file.
apiVersion: v1 kind: ConfigMap metadata: name: config-server data: # property-like keys; each key maps to a simple value CONFIG_SERVER_URL: "http://config-server:8888"
This YAML file describes a kubernetes ConfigMap object. In the ConfigMap you define 1 configuration setting CONFIG_SERVER_URL. This will be picked up by the pods you’ll deploy in one of the next steps. Spring boot will use these values to find the config server in your cluster.
-
In the folder where you created the config-map.yml file, issue the below bash statement to apply the ConfigMap in the AKS cluster.
kubectl create -f config-map.yml --namespace spring-petclinic
-
You can list your configmaps with the below statement.
kubectl get configmap -n spring-petclinic
-
And you can describe the contents of your
config-server
configmap.kubectl describe configmap config-server -n spring-petclinic
-
In the kubernetes folder copy the contents of the spring-petclinic-api-gateway.yml file.
curl -o spring-petclinic-api-gateway.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-api-gateway.yml
Inspect the contents of this file. It has the following settings:
- It has the label
api-gateway
. - It uses the
CONFIG_SERVER_URL
value from the config map you just created. - It exposes port 8080.
- It has a service definition with a type of
LoadBalancer
. This will expose the api-gateway externally with a public IP address.
- It has the label
-
This file uses a replacement value for the
image
. This will be different for your specific container registry. Usesed
to replace this value.IMAGE=${MYACR}.azurecr.io/spring-petclinic-api-gateway:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-api-gateway.yml
-
In the same way, copy the contents of the spring-petclinic-admin-server.yml file.
curl -o spring-petclinic-admin-server.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-admin-server.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-admin-server:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-admin-server.yml
Inspect here as well the differences and similarities between the
admin-server
and theapi-gateway
. -
In the same way, copy the contents of the spring-petclinic-customers-service.yml file.
curl -o spring-petclinic-customers-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-customers-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-customers-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-customers-service.yml
For the
customer-service
and all of the next microservices, you will notice these will be create withSERVICE_TYPE
ClusterIP
. This will create a private IP address for each microservice within the AKS cluster. -
In the same way, copy the contents of the spring-petclinic-visits-service.yml file.
curl -o spring-petclinic-visits-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-visits-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-visits-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-visits-service.yml
-
In the same way, copy the contents of the spring-petclinic-vets-service.yml file.
curl -o spring-petclinic-vets-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-vets-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-vets-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-vets-service.yml
-
In the same way, copy the contents of the spring-petclinic-config-server.yml file.
curl -o spring-petclinic-config-server.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-config-server.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-config-server:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-config-server.yml
Notice that the
config-server
gets exposed over port8888
. This is the default Spring Cloud setting. -
In the same way, copy the contents of the spring-petclinic-discovery-server.yml file.
curl -o spring-petclinic-discovery-server.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/02_lab_migrate/spring-petclinic-discovery-server.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-discovery-server:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-discovery-server.yml
Notice that the
discovery-server
gets exposed over port8761
. This is the default Spring Cloud setting. -
Double check that all the different yaml files got created correctly. Inspect one of the yaml files, for instance the one for the
api-gateway
should look like this:apiVersion: apps/v1 kind: Deployment metadata: labels: app: api-gateway name: api-gateway spec: replicas: 1 selector: matchLabels: app: api-gateway template: metadata: labels: app: api-gateway spec: containers: - image: <your-acr-repo>.azurecr.io/spring-petclinic-api-gateway:3.0.2 name: api-gateway env: - name: "CONFIG_SERVER_URL" valueFrom: configMapKeyRef: name: config-server key: CONFIG_SERVER_URL imagePullPolicy: Always livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 180 successThreshold: 1 readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 10 successThreshold: 1 ports: - containerPort: 8080 name: http protocol: TCP - containerPort: 9779 name: prometheus protocol: TCP - containerPort: 8778 name: jolokia protocol: TCP securityContext: privileged: false --- apiVersion: v1 kind: Service metadata: labels: app: api-gateway name: api-gateway spec: ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: api-gateway type: LoadBalancer
-
You can now use each of the yaml files to deploy your microservices to your AKS cluster. You can set the default namespace you will be using as a first step, so you don’t need to repeat the namespace you want to deploy in in each
kubectl apply
statement. Start with deploying theconfig-server
and wait for it to be properly up and running.kubectl config set-context --current --namespace=$NAMESPACE kubectl apply -f spring-petclinic-config-server.yml kubectl get pods -w
This should output info similar to this.
NAME READY STATUS RESTARTS AGE spring-petclinic-config-server-6f9ffd8949-zz4nt 1/1 Running 0 160m
Mind the
READY
column that indicates1/1
. In case your output after a while still shows0/1
, or you see aCrashLoopBackoff
status for your pod, double check your previous steps on errors. You can also check your pods logs withkubectl logs <name-of-your-pod>
to troubleshoot any issues. The LabTips section also contains steps you can try for troubleshooting. -
Once the config-server is properly up and running, escape out of the pod watch statement with
Ctrl+Q
. Now in the same way deploy thediscovery-server
.kubectl apply -f spring-petclinic-discovery-server.yml kubectl get pods -w
-
Once the discovery-server is properly up and running, escape out of the pod watch statement with
Ctrl+Q
. Now in the same way deploy the rest of the microservices.kubectl apply -f spring-petclinic-customers-service.yml kubectl apply -f spring-petclinic-visits-service.yml kubectl apply -f spring-petclinic-vets-service.yml kubectl apply -f spring-petclinic-api-gateway.yml kubectl apply -f spring-petclinic-admin-server.yml
-
You can now double check whether all pods got created correctly.
kubectl get pods
This should output info similar to this.
NAME READY STATUS RESTARTS AGE spring-petclinic-admin-server-6484789c8-cppvv 1/1 Running 0 169m spring-petclinic-api-gateway-d487ddcbf-cg82f 1/1 Running 0 3h2m spring-petclinic-config-server-6f9ffd8949-zz4nt 1/1 Running 0 160m spring-petclinic-customers-service-56b56b994b-wqnlh 1/1 Running 0 169m spring-petclinic-discovery-server-7f7f7447f6-zzj7k 1/1 Running 0 160m spring-petclinic-vets-service-7d97bf99c6-2rc6b 1/1 Running 0 168m spring-petclinic-visits-service-57c56db5fb-gzsbh 1/1 Running 0 168m
Mind the
READY
column that indicates1/1
. In case your output still shows0/1
for some of the microservices, run thekubectl get pods
statement again until all microservices indicate a properREADY
state. -
In case any of the pods are not reporting a
Running
status, you can inspect their configuration and events with a describe.kubectl describe pod <name-of-the-pod> -n spring-petclinic
-
In case of errors, you can also inspect the pods logs.
kubectl logs <name-of-the-pod> -n spring-petclinic
-
In case you need to restart one of the pods, you can delete it and it will start up again automatically.
kubectl delete pod <name-of-the-pod>
A full overview of how to recover from errors in the lab can be found in the LabTips.