Kubernetes on Ubuntu

I'm using Ubuntu 16.04 (in fact Xubuntu) and will show you how to install Kubernetes (current stable 1.7)


If not already installed you need to have Docker installed. Check official docker setup documentaton

Kubernetes repo

Next steps need to be done as root.
We begin by installing kubernetes repository keys.

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 -  

then we add kubernetes source list..

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list  
deb http://apt.kubernetes.io/ kubernetes-xenial main  

kubelet, kubeadm and kubernetes-cni.

  • kubelet is responsible to run pods on worker nodes.
  • kubeadm is administrative utility for kubernetes cluster.
  • kubernetes-cni - CNI is in short a specification that determines how kubernetes is using network drivers.

Let's install them

$ apt-get update
$ apt-get install -y kubelet kubeadm kubernetes-cni

Initializing the cluster

Ok we need now get specific about networking. In this tutorial i'm gona to use flannel - a layer 3 network fabric. Generally speaking it will help us to defined network as(and by) software1

We will use kubeadm init to start the cluster. The important parameters are
* --pod-network-cidr defines containers network * --apiserver-advertise-address= address where kubernetes publishes his api endpoint.

alternativel you can use more flags
* --skip-preflight-checks allows kubeadm to check the host kernel for required features, sometimes you want skip that. * --kubernetes-version this pins the version of the cluster eg. stable-1.6.

Let's do it.

kubeadm init --pod-network-cidr= --apiserver-advertise-address=  

You should see something like:

[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[init] Using Kubernetes version: v1.7.3
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks
[preflight] WARNING: docker version is greater than the most recently validated version. Docker version: 17.05.0-ce. Max validated version: 1.12
[preflight] Starting the kubelet service
[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --token-ttl 0)
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [aho-thinkpad-t520 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs []
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing key and public key.
[certificates] Generated front-proxy CA certificate and key.
[certificates] Generated front-proxy client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 66.001721 seconds
[token] Using token: 1b172f.4f364a5a37714f21
[apiconfig] Created RBAC rules
[addons] Applied essential addon: kube-proxy
[addons] Applied essential addon: kube-dns

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run (as a regular user):

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.  
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:  

You can now join any number of machines by running the following on each node  
as root:

  kubeadm join --token 1b172f.4f364a5a37714f21

Now we should try to access our cluster with non priviledged user. If you don't have one (e.g. because of fresh OS installation? ) here quick tipp:

useradd kubeuser -G sudo -m -s /bin/bash  
passwd kubeuser  

Please do following steps as not priviledged user

mkdir -p $HOME/.kube  
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config  
sudo chown $(id -u):$(id -g) $HOME/.kube/config

By default containers cannot run on master nodes in the cluster. Since we only have one node - we'll taint it so that it can run containers for us.

kubectl taint nodes --all node-role.kubernetes.io/master-  

Apply flannel config

Flannel driver maintains a mapping between allocated subnets and real host IP addresses. Flannel uses UDP to encapsulate IP datagrams to transmit them to desired host. To go furhter at this point we can just apply this configuration:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel-rbac.yml

kubectl create -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml  

Take a look on the kube-flannel.yml file if you like.

Test brand new cluster

First of all let's list all resources in the kube-system namespace

kubectl get all --namespace=kube-system  
# Prints something like:

NAME                                           READY     STATUS    RESTARTS   AGE  
po/etcd-aho-thinkpad-t520                      1/1       Running   0          1h  
po/kube-apiserver-aho-thinkpad-t520            1/1       Running   0          1h  
po/kube-controller-manager-aho-thinkpad-t520   1/1       Running   0          1h  
po/kube-dns-2425271678-jg0dm                   3/3       Running   0          1h  
po/kube-flannel-ds-vgf6w                       2/2       Running   0          9m  
po/kube-proxy-l0hdg                            1/1       Running   0          1h  
po/kube-scheduler-aho-thinkpad-t520            1/1       Running   0          1h

NAME           CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE  
svc/kube-dns   <none>        53/UDP,53/TCP   1h

deploy/kube-dns   1         1         1            1           1h

NAME                     DESIRED   CURRENT   READY     AGE  
rs/kube-dns-2425271678   1         1         1         1h

All services seem to run - good sign.

Start test containers

kubectl create -f https://raw.githubusercontent.com/sverrirab/kube-test-container/master/kubernetes/kube-test-container.yaml  

This will start 5 Pods with kube-test-container, but also other resources like Deployement, ReplicaSet and Service.

To see how well your fresh cluster is performing, maybe you want to have some Ui...


At the beginning UI can help to understand things better.
Let's deploy kube-dashboard

kubectl create -f https://git.io/kube-dashboard  
kubectl proxy  

Now it's served under:

More tests

Let's change the version of kube-test-container to v1.1 and see wich actions kubernetes takes for us.

kubectl set image deployment/kube-test-container kube-test-container=sverrirab/kube-test-container:v1.1  

For more test options consult kube-test-container github page. If you want to learn kubernetes consult Kubernetes by example page besides of course comprehensive official documentation

Hope this helps! Any feedback is welcome as always.

  1. Software Defined Network (SDN). For this flannel will use linux modules overlay and ipvlan you can find more on this by searching on these terms ;)