This article will help you setup your first service on AKS. It does not intend to provide an in-depth knowledge on the tech-stack. Idea is, that once you have it working you can play around, experiment, explore and enhance to learn the concepts in depth or to create a prototype.
We will create a simple service and talk about basics of docker and kubernetes. You need no prior experience with Docker/Kubernetes or Azure for this.
In this article we focus on just creating a simple web service. There is another article that demonstrates creating a streaming server with gRPC and websockets here https://github.com/dotnet-school/dotnet-streaming-aks.
-
Development environment
If you are using you office laptop, you can have problems because of firewall and network policies.
It is recommended that you use your personal machine so that you can freely communicate with docker hub and azure.
-
.NET 5 SDK
We will use .NET5 boileplates to create a sample service which we will run on AKS.
Download and install from https://dotnet.microsoft.com/download/dotnet/5.0
-
Docker Desktop
To build and publish images to docker registry.
Download and install from https://www.docker.com/products/docker-desktop.
-
Docker Hub Acccount
For this tutorial we will use Docker Hub as our Docker registry. You can use anything else like Azure Container Registry, but its recommended to use docker hub to help you follow along the steps in this article.
Create your account here : https://hub.docker.com/signup
-
Kubectl
To run command against kubernetes cluster on AKS.
Download and install from : https://kubernetes.io/docs/tasks/tools/
-
Azure Portal Account
Signup to create you azure account here https://signup.azure.com/signup
-
Azure CLI
To be able to connect to Azure via cli. You can skip this and use Azure cloud shell instead. But is recommended to help you follow along the steps in this article.
Download and install from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
-
CLI
Commands in this arcticle are created for bash. You can use most command in a poweshell. Its recommended to use something like
wsl
orgit bash
if you are running on windows.Download and install gitbash (if required) from : https://git-scm.com/downloads
-
Use
dotnet5
boilerplate to create a service. -
Create a
Dockerfile
for your service -
Publish Service on Docker Registry
Publish the image on docker registry so that it can be downloaded inside Azure Kubertes cluster.
-
Create a
.yaml
file to define how to run service in a kubenetes cluster -
Create a cluster on AKS, and use our manifest file with kubectl to deploy our serivce to Azure Kubernetes Service.
You can create the service using visual studio. Please ensure you keep the folder strucutre as below :
-
-
HelloWorldService
HelloWorldService.csproj
-
Kubernetes
hello-world-service.yml
-
For this article we will use the CLI to create a new service.
# Create a directory for the project
mkdir dotnet-first-aks-service
# Initialize a git repo
git init
# Create a .gitignore file
dotnet new gitignore
# Create a web api .net5 using boileplate
dotnet new webapi -o HelloWorldService
# Run your service
dotnet run --project HelloWorldService/HelloWorldService.csproj
Now open url http://localhost:5000/WeatherForecast in browser to ensure our service is up and running.
In Kubernetes world (or cloud native world in general) everything runs as a container. Be it the database, messaging broker, in-memory caches e.t.c.
A dockerfile describes how to run a program as a docker container.
Create a file dotnet-first-aks-service/HelloWorldService/Dockerfile
as follows :
#HelloWorldService/Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source
COPY ./*.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c release -o /app --no-restore
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build /app .
EXPOSE 80
ENTRYPOINT ["dotnet", "HelloWorldService.dll"]
Create another file dotnet-first-aks-service/HelloWorldService/.dockerignore
as follows :
**/.dockerignore
**/.project
**/.vs
**/.idea
**/.vscode
**/*.*proj.user
**/bin
**/Dockerfile*
**/obj
Build and run you docker file
# To to folder containing the Dockerfile
cd HelloWorldService
# Create docker image
docker build -t hello-world-service .
# Run service as a Docker container
docker run -p 5000:80 hello-world-service
Now open url http://localhost:5000/WeatherForecast in browser to ensure our service is running as a docker container.
# Log into you docker account
docker login
# Create you image name on docker registry
docker tag hello-world-service <your-docker-hub-username>/hello-world-service:v1
# e.g.
# docker tag hello-world-service nishants/hello-world-service:v1
# Push your image to docker registry
docker push <your-docker-hub-username>/hello-world-service:v1
# outptu :
# The push refers to repository [docker.io/<your-docker-hub-username>/hello-world-service]
By default, the image is marked as private. We don't want to setup authentication in AKS. So, to keep it simple, we will marke the image as public, available for anyone to use.
Steps to make your image public:
Create a file Kubernetes/hello-world-service.yml
to define manifest (say kubernetes configuration) for the service as follows :
# Kubernetes/hello-world-service.yml
# This part creates a load balancer pod that receives traffic from internet and load-balances to different instances of our service
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
spec:
selector:
app: hello-world # This makes load balancer point to hello-world deployment
ports:
- port: 80
targetPort: 80 # The port our container(in pods) listens to
type: LoadBalancer
---
# This part creates defines which docker image to use for creating instances of our service and how many instances to create
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 2 # Run two instances of our service
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: docker.io/nishants/hello-world-service:v1 # Our docker image on docker hub
ports:
- containerPort: 80 # Port that our app listens to
imagePullPolicy: Always
- Please rememer to update the username in docker image name
docker.io/<your-dockerhub-username>/hello-world-service:v1
# login using azure cli
az login
RESOURCE_GROUP=dotnet-first-aks-service
CLUSTER_NAME=dotnet-first-aks-service-cluster
REGION=westeurope
# Create resource
az group create --name $RESOURCE_GROUP --location $REGION
# Create cluster on AKS with 1 node
az aks create --resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--node-count 1 \
--enable-addons monitoring \
--generate-ssh-keys
# Allow kubectl to connect and manage our AKS clustuer
az aks get-credentials \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME
# Check if our node is up and running
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# aks-nodepool1-36600731-vmss000000 Ready agent 2m58s v1.17.10
# Deploy our app
kubectl apply -f Kubernetes/
# View the external ip address of our service
kubectl get service/hello-world-service
# NAME TYPE CLUSTER-IP EXTERNAL-IP
# hello-world-service LoadBalancer 10.0.105.141 51.105.150.87
You url will look like this http://51.105.150.87/WeatherForecast
Remember to delete your Azure resources when you are done
az group delete --name $RESOURCE_GROUP --yes --no-wait