This post is part of the .NET Club Valencia Meetup took place on Thursday, 23th March 2017, sponsored by everis, an NTT Data Company. You can find the presentation here: DotNet Containers with Visual Studio, Azure Container Services and Kubernetes

Time for more TECH cooking! After creating a toy Kubernetes cluster using some Raspberry Pi 3, now is time to move on to the cloud a create a serious cluster to deploy our .NET applications.

In this blog post, I’ll show you how you can easily create a Azure Container Services w/ Kubernetes. Kubernetes is now GA in Azure, so you can now safely run it for your production projects.

If you attended my latest Meetup, this is also a special gift for you 😉 Thank you for attending!

Alternatives to create the cluster

There are In Azure Container Services (ACS), including the Azure Portal, Azure PowerShell extensions, or the brand-new (PREVIEW) Azure CLI 2.0. For this recipe, we are going to use Azure CLI 2.0 (PREVIEW).


  • Azure CLI 2.0 (PREVIEW) (Aka “az”)
  • Azure Suscription (with credit)
  • kubectl
  • PC, Mac or Linux system

Setting up the environment

First of all, you should follow the step by step tutorial for installing the Azure CLI in your favourite OS. In my case, I just had to run this simple command:

$ curl -L | bash

If you have never used Kubernetes before, kubectl is the other ingredient you need to prepare. With Homebrew, kubectl is one command away from you:

$ brew install kubectl

Once Azure CLI and kubectl is installed, all the commands are (almost) the same for all platforms.

Why Azure CLI?

I just wanted to find how hard would be to create the cluster from the command line. I have tried the Azure Portal to do it, but it was a bit difficult to complete all the required fields, but the Azure CLI documentation was really nice, so I got straight to the point.

Login to Azure with Azure CLI (az)

When you are trying to login to Azure with the az, the tool asks you to open a URL with your browser and type a code. Once introduced, you get immediately a response to your terminal:

$ az login To sign in, use a web browser to open the page and enter the code XXXXXXXXX to authenticate.

[ { "cloudName": "AzureCloud", "id": “xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "isDefault": true, "name": "Visual Studio Enterprise 2013 MPN", "state": "Enabled", "tenantId": “xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "user": { "name": "”, "type": "user" } } ]

Once logged, the final step is to set the subscription where the commands will be ran against:

$ az account set --subscription "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx”

Where the subscription is the property “Id” you got in the previous JSON response, immediately after login. You can print again this information using the following command:

$ az account list [ { "cloudName": "AzureCloud", "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "isDefault": true, "name": "Visual Studio Enterprise 2013 MPN", "state": "Enabled", "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "user": { "name": "", "type": "user" } } ]

Setting up a user for the Kubernetes cluster

You are logged in with your main Azure Account (Second warning ;), now is time to create the cluster. For convenience I have created some ENV variables:

$ DNS_PREFIX=everis-k8s $ SERVICE_NAME=everis-acs-k8s $ RESOURCE_GROUP=everis-k8s-resources $ VM_SIZE=Standard_A2_v2

Basically, I set some information required by ACS, along with my node Kubernetes VM size. I have limited credits on Azure, so I decided to run 2 Standard_A2_V2 machines, instead the default one (Standard_A8_V2).

Very important to note: As the time I wrote the blog post, the AZ client only allows you to set the size of the NODES. Kubernetes master will be setup with Standard_A2_v8, and there is no way to change it during creating time. The only way is to change the VM size once the cluster is created.

And here goes the magic:

$ sudo az acs create --orchestrator-type=kubernetes --resource-group $RESOURCE_GROUP --name=$SERVICE_NAME --dns-prefix=$DNS_PREFIX --agent-vm-size $VM_SIZE --master-count=1 --agent-count=2 waiting for AAD role to propagate.done { "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/everis-k8s-resources/providers/Microsoft.Resources/deployments/azurecli1488022758.4954921", "name": "azurecliXXXXXXXXX.XXXXX", "properties": { "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "debugSetting": null, "dependencies": [], "mode": "Incremental", "outputs": null, "parameters": { "clientSecret": { "type": "SecureString" } }, "parametersLink": null, "providers": [ { "id": null, "namespace": "Microsoft.ContainerService", "registrationState": null, "resourceTypes": [ { "aliases": null, "apiVersions": null, "locations": [ "westeurope" ], "properties": null, "resourceType": "containerServices" } ] } ], "provisioningState": "Succeeded", "template": null, "templateLink": null, "timestamp": "2017-02-25T11:47:56.569806+00:00" }, "resourceGroup": "everis-k8s-resources" }

Note that I have manually reduced the master nodes count to “1” and nodes to “2”, as I do not intend to create a production, redundant cluster.

Now, login to the Azure Portal, and in few minutes your cluster will be ready to go:

Optional, don’t forget to change your master VM size: Just look for your “xxx-master-xxxxx-x” VM in the Resource Group:

And go to the “Size” tab. A list with all VM sizes will be displayed, alongside with the estimate monthly cost. A2_V2 is enough for toy projects:

Remember, nodes are already set to A2_V2 during creation.

**Optional: **Want to save money? Schedule the automatic VMs shutdown!

Getting the Kubernetes cluster credentials

Getting back to the terminal, and logged in with you main, az also helps you getting your Kuberentes credentials, required to run connect with kubectl.

$ az acs kubernetes get-credentials --resource-group=$RESOURCE_GROUP --name=$SERVICE_NAME

NOTE: We are still using the ENV variables we set before.

And… Magic again, az has copied all the kubernetes configuration, certificates etc to you ~/.kube/config folder. Is important to note here that, if you are running another Kubernetes cluster (like the toy Pi Cluster), all the configuration is overwritten and kubectl will point to the Azure cluster. Don’t forget to backup the current credentials located at ~/.kube/config before executing the command!

Checking everything is working

Cluster created, credentials downloaded. Is kubectl time. kubectl version and kubectl get nodes will do the work checking everything is up and running:

$ kubectl version Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.3", GitCommit:"029c3a408176b55c30846f0faedf56aae5992e9b", GitTreeState:"clean", BuildDate:"2017-02-15T06:40:50Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.1", GitCommit:"82450d03cb057bab0950214ef122b67c83fb11df", GitTreeState:"clean", BuildDate:"2016-12-14T00:52:01Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"} $ kubectl get nodes NAME                    STATUS                     AGE k8s-agent-7ae05276-0    Ready                      9m k8s-agent-7ae05276-1    Ready                      8m k8s-master-7ae05276-0   Ready,SchedulingDisabled   9m
Congratulations! You Azure Container Services cluster is ready to go!

Deploying your first container

As bonus, just let me help you deploying your first container in the ACS Kubernetes Cluster:

Just ask Kubernetes to deploy the default nginx image, and to expose this deployment using a LoadBalancer:

$kubectl run nginx --image nginx deployment "nginx" created $ kubectl expose deployments nginx --port=80 --type=LoadBalancer

It will take a while, so keep executing the following command until you get your External IP. The “External IP” is the IP of the Load Balancer Kubernetes as created in Azure for you, because Kubernetes is deeply integrated with the Azure stack thanks to Azure Container Services.

watch 'kubectl get svc' (Using MacOS and don’t have watch? brew install watch very 2.0s: kubectl get svc Sergios-MacBook-Pro.local: Sat Feb 25 13:02:11 2017 NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 443/TCP 13m nginx 80:32176/TCP 3m ... NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 443/TCP 13m nginx 80:32176/TCP 3m

In this case, the IP of the Deployment’s Load Balancer is

Now, just go to the browser and open this IP address:


In this blog post, you have learned how you can easily create a Kubernetes cluster, deeply integrated with the Azure stack thanks to Azure Container Services, using the Azure CLI 2.0 (PREVIEW). With few commands, you have asked to create a cluster of machines running Kubernetes, alongside with all the required resources Kubernetes needs to run in the cloud.