DEV Community 👩‍💻👨‍💻

Mohsen Kokabi
Mohsen Kokabi

Posted on

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

Top comments (0)

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.