DotNet Core in kubernetes (Azure Container Registry)

mkokabi

Mohsen Kokabi

Posted on February 4, 2020

DotNet Core in kubernetes (Azure Container Registry)

Here in simplest form we are going to run an Asp.Net core application in local Kubernetes.

Step 1: Creating a container registry

First you need to login to your azure account:

az login

if you don't know the id of the location you can get it with

az account list-locations

I am going to use australiaeast. So I am going to put it in a variable.

bash:

location='australiaeast'

powershell:

$location='australiaeast'

The other parameter I am going to need is a name for resource group
bash:

resource_group_name='ContainerRegistryRG'

powershell:

$resource_group_name='ContainerRegistryRG'

In case you are not using an existing resource group:

az group create --location $location --name $resource_group_name

Next parameter is a name for the container registry. As it needs to be unique I am adding the seconds from Unix Epoch.

bash:

crName=TestCR$(date +'%s')

powershell:

$crName='TestCR' + [int][double]::Parse((get-date -UFormat +%s))

Finally, we create the container registry:

az acr create -g $resource_group_name -n $crName --sku Basic --admin-enabled -l $location

I am going to (manually) store the value of loginServer from the json response in crServerName.

The next parameters we need are credentials.

az acr credential show -g $resource_group_name -n $crName 

Take a note of "username" and password value

Step 2: Creating the docker image

Now we are going to create a dotnet core web application and build a docker image. The complete list is also here

dotnet new webapp -o KTestDotNetCoreWebApp

cd .\KTestDotNetCoreWebApp\

dotnet publish -c Release -o out

new-item -path "Dockerfile" -ItemType "file" -Value 'FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS runtime
WORKDIR /app 
COPY out ./ 
ENTRYPOINT ["dotnet", "KTestDotNetCoreWebApp.dll"]' 


docker build . -t ktest-dotnetcore-webapp-docker-image

We need to tag our docker image with the name of the container registry server.

docker tag ktest-dotnetcore-webapp-docker-image "$crServerName/ktest-dotnetcore-webapp-docker-image"

To be able to push to the registry you first need to login. You can login using either of following ways:

az acr login --name $crName --username $crName

or

docker login "$crServerName"

both of them will use the username and password you got using az acr credential show.

Now we can push our image:

docker push "$crServerName/ktest-dotnetcore-webapp-docker-image"

Step 3: using our docker image in Kubernetes

To allow kubernetes pull down our image, we need to define a image pull policy.
K8s would get the information it needs in a secret object. The type of this secret should be docker-registry. Here I am going to name it myregistrykey. It would be used while defining the container template either for the pod or for the deployment.

ref

kubectl create secret docker-registry myregistrykey --docker-server="https://$crServerName" --docker-username="$crName" --docker-password={replace the password} --docker-email=my@email.com
  • The password is what you get while running the az acr credential show
  • The email can be anything.

Now we are going to create a deployment object using kubectl run. As imagePullSecrets can not be added in the command line of creating the deployment object (or pod object), I would use --dry-run option with -o yaml to only generate the yaml.

kubectl run g5 --image="$crServerName/ktest-dotnetcore-webapp-docker-image:latest" --replicas=2 --port=80 --dry-run -o yaml >g5.yaml

Now, we need to add the imagePullSecrets at the same level of containers.

The final yaml would be like:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    run: g5
  name: g5
spec:
  replicas: 1
  selector:
    matchLabels: 
      run: g5
  template:
    metadata:
      labels:
        run: g5
    spec:
      containers:
      - image: testcr{some numbers}.azurecr.io/ktest-dotnetcore-webapp-docker-image:latest
        name: g5
        ports:
          - containerPort: 80
      imagePullSecrets:
        - name: myregistrykey

And now we can create the deployment object using our yaml file.

kubectl apply -f g5.yaml

The last step is exposing the port 8080 using a load balancer service.

kubectl expose deployment g2 --type=LoadBalancer --name=glb --port=8080 --target-port=80

That's it. You can now browse the application on http://localhost:8080.


You might prefer to only create a pod. The only difference is add --restart=Never in kubectl run command and remove the --replicas:

kubectl run g3 --image="$crServerName/ktest-dotnetcore-webapp-docker-image:latest" --restart=Never --port=80 --dry-run -o yaml >g3.yaml

Similarly, edit the yaml file and add under spec add

      imagePullSecrets:
        - name: myregistrykey

and then create the object.

kubectl apply -f g3.yaml

The exposing step would be the same just saying pod instead of deployment.

kubectl expose pod g3 --type=LoadBalancer --name=glb --port=8080 --target-port=80
💖 💪 🙅 🚩
mkokabi
Mohsen Kokabi

Posted on February 4, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related