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

Prerequisites

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

Kubernetes repo

The 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  
EOF

kubelet, kubeadm and kubernetes-cni.

  • kubelet is responsible to run pods on worker nodes.
  • kubeadm is an 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 to get specific about networking. In this tutorial I’m going 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=127.0.0.1 address where Kubernetes publishes his API endpoint.

alternatively you can use more flags

  • –skip-preflight-checks allows kubeadm to check the host kernel for required features, sometimes you want to skip that.
  • –kubernetes-version this pins the version of the cluster eg. stable-1.6.

Let’s do it.

kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=127.0.0.1

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 [10.96.0.1 192.168.178.23]
[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:
  http://kubernetes.io/docs/admin/addons/

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

  kubeadm join --token 1b172f.4f364a5a37714f21 192.168.178.23:6443

Now we should try to access our cluster with the non-priviledged users. If you don’t have one (e.g. because of fresh OS installation? ) here quick tip:

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

Please do the following steps as not privileged 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

The flannel driver maintains a mapping between allocated subnets and real host IP addresses. Flannel uses UDP to encapsulate IP datagrams to transmit them to the desired host. To go further 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 at 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   10.96.0.10   <none>        53/UDP,53/TCP   1h

NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
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 five Pods of kube-test-container, but also other resources like Deployment, ReplicaSet, and Service.

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

Kube-Dashboard

In 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 http://127.0.0.1:8001

More tests

Let’s change the version of kube-test-container to v1.1 and see which 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 ;) ↩︎