For introduction about Kubernetes first read: What is Kubernetes?
Lets admit that installing Kubernetes for the first time is not an easy task. Because it has multiple components, there are multiple paths (options) and the documentation varies between Windows/Linux/macOS.
Let’s start by saying that Kubernetes mainly runs on Linux, so production clusters will be hosted on Linux machines or VMs. While there are ways to install a one node cluster to your development PC that relies on a virtual machine if you are running Windows or macOS.
Luckily when we install Docker on Windows, it creates a virtual machine to run Linux containers (either using Hyper-V or Virtual Box). And also luckily that Docker now supports Kubernetes out of the box. So that’s the easiest way to run Kubernetes on Windows, using Docker..
Installing Kubernetes on Windows (using Docker)
Go to Docker: Settings > Kubernetes > Enable Kubernetes
That’s it! it just takes a few minutes to download many containers and start them, then it will say Kubernetes is running in the status circle below.
Alternative way (using Minikube)
Real Production Clusters
For real production clusters you go with one of these options:
- Google Kubernetes Engine
- Azure Kubernetes Service
- Amazon Kubernetes Service
- Install your own cluster (bumpy road ahead)
- All the other options
Confirm your installation is working
Whatever was the installation method you went for, most probably you already got Kubectl (the client command line tool to connect to Kubernetes) installed on your machine. You can confirm that by running:
If everything is working fine, it should give you 2 versions, one is the client version, and the server version or error connecting to cluster.
If the command is not installed on your machine, you can download it from this link. It’s just an exe that you download and then you should add its location to your PATH environment variable. Here are the full instructions.
If you get client version, but can’t connect to server, then you need to take a look at the configuration file that tells kubectl where is the cluster and how to authenticate to it.
Look for the file: C:\Users\<username>\.kube\config
It should contain the connection to your cluster, if you installed using docker or minikube it should be already populated, otherwise you should get it from the cloud provider, from inside you cluster’s master node config at same location, or retry the whole installation.
First things to do in your cluster
First thing to do is to run the Kubernetes Dashboard. The Dashboard allow you to see what’s happening in your cluster, whats running, check logs, get console access inside pods, delete things…etc.
Run the below command to install it. This downloads the dashboard container and runs it inside the cluster:
kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
Usually anything inside the cluster is not accessible from outside, so we run a proxy on our local machine to allow us access to inside:
Then you open this url into a browser: http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview
In the dashboard you will notice that there multiple namespaces, default is an empty namespace that you can use to install your apps. Another notable namespace is kube-system, this one has the Kubernetes system containers and services (including the dashboard that we just installed).
2. NGINX Ingress Controller (skip if on cloud)
I know this is getting more complicated, but you need one more thing to save you the trouble of not knowing what to look for later. You may not need this step if you are using a cloud based cluster since it may already be handled. But if you are creating your own cluster or want to try Ingress locally on your PC, then it’s better to use this basic step to setup Ingress controller to allow later tutorials to work.
When you deploy your app as a “Pod” it gets a random local IP each time, that is only accessible from inside your cluster. Then you create a “Service” to allow other Containers/Pods to access your service by name (not knowing it’s IP). This only works for services that needs to be internally accessible, like APIs that are going to be accessed from front-ends. But what about front-ends themselves that needs to be accessed by users from outside the cluster?
Here comes the name Ingress (allowing external traffic to go inside the cluster, routing it to the correct service internally). So you can deploy as many apps as you want inside the cluster (but say only one process can gain access to the port 80 on the physical machine/cluster node). So you deploy an ingress Pod in this basic example, it’s an NGINX web server, that listen to the actual physical port 80 on the cluster nodes, and then configure it to route traffic the rest of apps. Sometimes routing work using different host names (for example foo.com goes to foo service, and bar.com goes to bar service). Or it can work using Urls (like http://cluster/foo/… goes to foo service and http://cluster/bar/… goes to bar service).
Updated: for more details on deploying NGINX Ingress, check the ingress article.
Deploy your first app
Now it’s finally time to deploy our first app. For simplicity, I’ll use the sample asp.net core website that doesn’t need a database. Create a file named mysample.yaml with the following content:
kind: Service apiVersion: v1 metadata: name: mysample-service spec: selector: app: mysample ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: mysample-deployment labels: app: mysample spec: replicas: 2 selector: matchLabels: app: mysample template: metadata: labels: app: mysample spec: containers: - name: mysample image: microsoft/dotnet-samples:aspnetapp ports: - containerPort: 80
This file describes 2 Kubernetes objects:
- Service: with the name mysample-service that direct traffic to this service to any Pod with label mysample. It’s recommended that you define services before Pods.
- Deployment: with a name and label (it’s good to use a lot of labels for your objects to be able to select them later). And it defines that we need a replica set with 2 instances of this Pod template, and define that we need to match Pods with our label. Then define the template which has a spec saying the required container image (here is an image from Docker Hub), and we define that we expose port 80.
To deploy this you need to execute the following command:
kubectl apply -f mysample.yaml
Since we are not specifying a namespace (not in yaml nor in the kubectl command) the default namespace will be used. Here is what it looks like in the dashboard:
Note that the service is currently only available from inside the cluster network, which means we will not be able to browse it directly and will have to use the proxy to test it. Here is the url to open it using the proxy (assuming “kubectl proxy” command is running). Note the namespace and service name in the url:
You have deployed your first app to Kubernetes!
To understand more details about these objects, checkout these docs: