Automate deployments with Kubernetes using Kubeadm, LetsEncrypt and Traefik
Introduction
I'm wanted to have a functional Kubernetes cluster since I first heard about Kubernetes, but I never really had the prerequisities to start (server, domain).
But two days ago I bought a domain, wiped my server and started!
Goals
- Access the kubernetes dashboard easily with a browser
- Metrics
- Creating new services should be easy, I don't want to change configurations everywhere just to be able to reach it.
- Let's Encrypt certificates should be acquired automatically, I don't want to do that for every subdomain.
- It should be secure
Spoiler: All Goals will be satisfied
Prerequisites
I used the following setup:
- a server:
- 2 cores
- 6 GB memory
- 500GB hdd
- Ubuntu 16.04
- a domain
Obviously you could use multiple servers to get a real cluster, but I'm sure you need to adapt this guide in order to be successful.
Altough I only used one server I will call the kubernetes setup a cluster from now on.
Setup Kubernetes
Note: The setup of the cluster is based on this
Install docker
At the time of writing the docker version which is supported by kubeadm
is luckily in the standard ubuntu repositories, so a
sudo apt-get update && sudo apt-get install -y docker.io
did the job pretty well.
Okay cool, Docker installed. Half of the work done.
Set the DNS server for your kubernetes host
This is something I'm not sure everyone needs to do, but in my case my server provider set up a custom dns for it's dns server, which lead to some issues later on.
So you may wan't to save one or two hours debugging and replace the dns server now by editing /etc/network/interfaces
.
Search for the line dns-nameservers
, delete the IPs and replace it e.g. with 8.8.8.8
.
A server restart is a good idea to see if the network still operates properly.
Install kubeadm
Switch to the root user.
First we need to add a custom repo to apt by executing the following
apt-get update && apt-get install -y apt-transport-https curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet kubeadm kubectl
After that succeeded, we're ready to deploy Kubernetes
Deciding which network to use
We need a CNI(Container Network Interface) network solution for the cluster, for example to be able to view your cluster as one big cluster, independent from how many nodes there are.
I decided to use flannel, because I've read about the project multiple times and just wanted to try it out.
I did a Google search why I should use one network provider over the other, but I didn't really find a useful ressource.
Since flannel works really good for me, I'll use it in this tutorial.
If you want to use another provider, check the description here(at section 3/4).
Deploy the cluster with kubeadm
Now the moment which we all waited for, deploy the cluster.
It's important that you decided for a network provider before deploy it, because for some networks you need to pass an IP range to kubeadm
For flannel that's the case, so we need to invoke (as root):
kubeadm init --pod-network-cidr=10.244.0.0/16
Wait a few seconds until it's deployed.
Good. Now deploy a network so you're able to start using your cluster.
Deploy a network
Use kubectl
(pronounced cube cuddle) to deploy flannel.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel-rbac.yml
The commands apply the configurations defined at the URLs to the cluster. The first configuration creates the flannel deployment itself, the second creates roles so the deployment is able to access everything it needs.
This access configuration is called rbac
in kubernetes, make sure you use the rbac version of configurations (if available) if you apply custom deployment to your cluster.
You could now check if everything works as intended by executing
kubectl get pods --all-namespaces
After a few minutes everything should be in a running state, if thats the case:
Congratulations, your cluster is ready to use.
Now what
Your cluster works and you're able to interact with it via kubectl
.
Things we will do next:
- Import user certificate to Firefox/Chrome
- Deploy the Kubernetes Dashboard
- Deploy Heapster for metrics (Nice Graphs for the dashboard, yay!)
- Deploy Traefik to be able to do basically everything automagically
- Deploy a Jupyter Notebook server as an example application (Optional)
Let's begin
Import user certificate to Firefox/Chrome
This is not needed, but I'd recommend it to you, because it will make sure that you're able to reach your kubernetes dashboard without kubectl proxy
and will even work if traefik stops working.
Now, log into your server and change to the directory /etc/kubernetes/pki/
There you'll find two files called apiserver-kubelet-client.crt
and apiserver-kubelet-client.key
Copy these files to your home directory
sudo cp /etc/kubernetes/pki/apiserver-kubelet-client.* ~/
Own these files to you
sudo chown $USER:$USER ~/apiserver-kubelet-client.*
so you don't need root access from now on.
Firefox and Chrome need .p12
files, which could be generated using .crt
and key
files, so let's do that:
openssl pkcs12 -export -in apiserver-kubelet-client.crt -inkey apiserver-kubelet-client.key -out kubernetes.p12
Copy this file to all of your devices which you wan't to use to access kubernetes.
You could import these files by
Chrome:
- Settings->Manage Certificates->Import
Firefox:
- Tools->Tools > Options > Advanced > Certificates: View Certificates->Your Certificates
Try if you're able to reach your cluster by heading to https://SERVER_IP:6443
If everything worked out, you should be asked by your Browser which certificate you would wan't to use, select the one we just imported.
And you should get a JSON with a bunch of API paths.
Deploy the Kubernetes Dashboard
As you might already know, deployment is easy.
Execute
kubectl create -f https://raw.githubusercontent.com/sauercrowd/kube-configs/master/kubernetes-dashboard/kubernetes-dashboard.yaml
This will use the configuration on my repo, but I did that so it won't disappear, you might wan't to use the latest/official configuration from here
Wait a few seconds, and you should be able to see a kubernetes dashboard pod in the running state when you execute
kubectl get pods --all-namespaces
Now head over to your browser and go to the url
https://SERVER_IP:6443/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/
and you should see the dashboard!
As of the time of writing, the path which should lead you there, namely https://SERVER_IP:6443/ui/
, does not work, it does a redirect to the wrong URL.
It might be because of the fact that kubernetes 1.7 is not fully supported by the latest stable dashboard version, but I'm sure that will change in the future.
Deploy Heapster for metrics
A Dashboard needs graphs, obviously, so we need Heapster. Heapster will collect these metrics and the Kubernetes Dashboard will collect these and integrate some nice graphs, based on these metrics.
The configuration from the Heapster repository didn't work for me (probably also due to the new Kubernetes version 1.7), but the standalone version from the kops repository worked pretty well for me, so just use this. (Again, I mirrored it in my own repo)
kubectl create -f https://raw.githubusercontent.com/sauercrowd/kube-configs/master/monitoring/heapster-standalone.yaml
It will take some time before the metrics appear, but you should able to see nice graphs soon.
For some reason sometimes there is nothing, sometimes just CPU metrics, sometimes just memory metrics,…
No idea why, but it's okay for me.
Deploy Traefik as a load balancer
Now we will deploy Traefik as a load balancer. It will make sure that the correct subdomains or paths will be routed to the correct deployments, and it will automatically create letsEncrypt SSL certificates for you, so you really don't need to do anything anoying when deploying new applications to your cluster.
Download the configuration
First download the configuration:
wget 'https://raw.githubusercontent.com/sauercrowd/kube-configs/master/traefik/traefik-deployment.yaml'
and replace the following lines according to your setup.
email = "myemail@example.com" main = "mydomain.org" - 10.11.12.13
So, setup the email which you wan't to use for Letsencrypt, set the domain for which letsEncrypt should sign the certificates for, and replace 10.11.12.13
with the IP of your server.
Deploy the RBAC configuration
Before we deploy traefik itself, deploy the roles so everything will work as intended (original)
kubectl create -f https://raw.githubusercontent.com/sauercrowd/kube-configs/master/traefik/traefik-rbac.yaml
Deploy Traefik
kubectl create -f ./traefik-deployment.yaml