Summary: Excellent articles on AKS and traffic routing.
Ref: Multi-Stage AKS Deployment and Traffic Routing | by Amine Kaabachi | Azure Expert | Medium
Step 1: Create an AKS Cluster and push docker to AKS
NAME: single-ingress
LAST DEPLOYED: Sun Oct 4 04:22:36 2020
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
ingress.extensions/cloudapp-ingress created
Introduction:
This tutorial will help you deploy your app to an AKS Cluster with multiple environments (Dev, QA, etc) and allow to access each app instance. using a separate FQDN (dev.mycloudapp.org, qa.mycloudapp.org, etc).
In fact, your requirements are the following:
- Having the two apps in separate environments so that changes in the first do not affect the second.
- Being able to access each instance of the application separately. i.e. dev.mycloudapp.org redirects to the dev instance and similarly prod.mycloudapp.org redirects to the prod one.
- Being able to do it with only one AKS cluster.
If you can afford multiple clusters. It may be a better solution as it ensures that the apps will be separated physically. In the other case where you want to optimise your spendings, this article will will help you do it.
To solve this, we will use Kubernetes namespaces to separate and isolate stages.
Note: This article suppose. that you are familiar with the concepts of Kubernetes Service, Ingress and Ingress Controllers. If you want more basic topics, please let me know in the comments.
Lab Setup
This section describes a Lab setup for those who want to go through the use-case without having a real scenario at hand. Feel free to skip it if your AKS is already setup and your apps are deployed in separate namespaces.
Create an AKS Cluster
Let’s start by creating a new resource group for our AKS Cluster deployment:
▶ az group create --name multi-stage-aks --location northeurope
Now, we can create a new AKS Cluster, we will also disable RBAC because we don’t need it in these examples:
▶ az aks create --resource-group multi-stage-aks --name kube-cluster --node-count 2 --generate-ssh-keys -s Standard_DS4_v2 --disable-rbac
This will create another internal resource group with the required Azure components that are needed for the AKS cluster:
Notice that it contains a VM scale set and a Load balancer. There is also a Public IP that is attached to the Load balancer.
We need to set “kube-cluster” as current context in ~/.kube/config file and configure the credentials. For that we can use the following command from az-cli:
▶ az aks get-credentials -g multi-stage-aks -n kube-cluster
Here is what the AKS Cluster get’s by default:
To note that there is not ingresses setup by default and that would be something we need to do later.
Understanding the Example App
For the Lab we will use the following dummy-app. Lets have a look at the source code:
What you need to notice is mainly that it will append an env line with the value of ENV environment variable and that it listens to port 8080.
I already pushed the image to docker hub. So, you can run the two following commands and compare the result:
▶ docker run -e ENV=dev -p 8080:8080 g0d3l/dummy-app
And the if you change the ENV variable:
▶ docker run -e ENV=prod -p 8080:8080 g0d3l/dummy-app
Here is a preview of the service that will be running:
Creating Namespaces and Deploying the App Instances
For this tutorial we will create two namespaces dev and prod. We will deploy an instance of the app in each namespace while changing the ENV from dev to prod.
Note that in a real use-case these steps should be done through a pipeline and preferably using a package manager like Helm.
Let’s start by creating the namespaces:
▶ kubectl create namespace dev
namespace/dev created▶ kubectl create namespace prod
namespace/prod created
Then lets take a look at our Kubernetes objects definitions:
We have a deployment and a service that will target the created pods. The service should be accessible at port 80 and will target pods internally at port 8080.
Note that there is an ENV variable to be specified. It will allow us to easily create multiple instances of these objects per namespace:
▶ export ENV=dev && envsubst < objects.yml | kubectl apply -f -deployment.apps/app created
service/app-svc created
And finally we do the same thing with ENV=prod and you can test If everything is setup correctly by doing a local port forwarding on the two services:
▶ kubectl port-forward service/app-svc -n prod 8080:80
The prod service should be now accessible through http://localhost:8080.
We are now fully set.
AKS with Nginx Ingress Controller
As a requirement, we will need a custom domain name. I registered mycloudapp.org from Google to show you how to configure one.
But first let’s start by installing the Ingress controller. For this we need helm. If you don’t already have it installed, you can use this command:
▶ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
Installing the Ingress Controller
You need to add the Nginx ingress helm repo to the client database:
▶ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx▶ helm repo update
Now let’s install the Ingress controller:
▶ helm install single-ingress ingress-nginx/ingress-nginx --set rbac.create=false -n kube-systemNAME: single-ingress
LAST DEPLOYED: Sun Oct 4 04:22:36 2020
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: NoneNOTES:
The ingress-nginx controller has been installed.It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace kube-system get services -o wide -w single-ingress-ingress-nginx-controller'
Running the suggested command gives us the following:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORsingle-ingress-ingress-nginx-controller LoadBalancer 10.0.44.221 20.191.53.60 80:32306/TCP,443:31700/TCP 3m8s app.kubernetes.io/component=controller,app.kubernetes.io/instance=single-ingress,app.kubernetes.io/name=ingress-nginx
This confirms that our Ingress is now functional and is attached to an Azure Load Balancer with an external IP of 20.191.53.60.
As you can see in the screenshot above a new Frontend IP was added to the Load balancer with two rules (corresponding to ports 80 and 443).
Configure DNS Records
Next step is to go to the generated IP and configure a DNS name label on it. For my case, I now have http://dummy- app.northeurope.cloudapp.azure.com/ pointing to the IP that is configured in the Load balancer.
Next, I need to add to CNAME records on my custom domain name. As you can see in the screenshot below both records point to the same FQDN.
Create Ingresses in Each Namespace
Let’s take a look at the ingress definition. We will only see the dev one but changes for Prod are very clear and minimal:
We can run the following command:
▶ kubectl apply -f ingress.yml -n dev
ingress.extensions/cloudapp-ingress created
Now, our service is accessible via http://dev.mycloudapp.org ! You apply the same command on the namespace prod and by changing the host on the definition, it will be accessible on the corresponding FQDN.
(Optional) Ingress Controller with Fixed IP
The IP was automatically generated when creating installing the Ingress Controller using Helm. This presents one disadvantage is that the IP is dynamic and If any changes happen to the Ingress-controller or cluster it will likely result in the IP changing.
The solution is to create the IP beforehand. You can refer to this complete Microsoft docs which is very detailed on the Topic. Do not hesitate to ask in the comments, if you got stack or if you had some issues completing this part.
Conclusion
This tutorial shows you how to create multi-stages AKS deployment and traffic routing. I hope this can help you solve your scenarios or better understand the Kubernetes ecosystem. Feel free to comment, provide or ask for help around this topic.
No comments:
Post a Comment