Kubernetes - Two Steps Installation

Learn how to use Kubeadm to install Kubernetes in mins

ta-ching chen

4 minute read

 Table of Contents


Long time ago, the way to install kubernetes was quite complicate. After kubernetes 1.4, we can use Kubeadm to install a kubernetes cluster with only two steps. Now, let’s start our journey.


  • Ubuntu 16.04


  • install.sh
apt-get update && apt-get install -y apt-transport-https curl
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
apt-get update
# Install docker if you don't have it already.
apt-get install -y docker.io
apt-get install -y kubelet kubeadm kubectl kubernetes-cni

Install basic dependencies 

$ chmod +x install.sh
$ sudo ./install.sh

Install Kubernetes core service 

$ sudo kubeadm init

Here we use flannel as CNI plugin for demonstration.

$ kubeadm init --pod-network-cidr=
$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml


--apiserver-advertise-address: IP address of api server
--apiserver-bind-port: port no. of api server (default 6443).
--pod-network-cidr: range of virtaul IP for pods.
--kubernetes-version: specified Kubernetes version (recommend 1.6+)

Config Kubectl 

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

Now, you have a standalone Kubernetes! Have fun :)

$ kubectl get pod

Kubernetes Cluster Recovery 

By default, the Kubernetes cluster won’t be brought up after the host restart. You will need extra configs as follow:

$ sudo swapoff -a
# comment out swap in /etc/fstab swap to ensure the system won't mount it again. 
$ sudo sed -i 's/.*swap.*/#&/' /etc/fstab
$ sudo systemctl enable kubelet

Now the cluster should be brought up automatically.

If it still not work and /var/log/syslog shows messages related to AppArmor policy

createPodSandbox for pod "kube-apiserver-template_kube-system(b1446568d75d2d0f4098b4b73cd39699)" 
failed: rpc error: code = Unknown desc = failed to start sandbox container for pod "kube-apiserver-template": 
Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused 
"process_linux.go:281: applying cgroup configuration for process caused \"An AppArmor policy prevents this sender from 
sending this message to this recipient; type=\\\"method_call\\\", sender=\\\":1.981\\\" (uid=0 pid=13495 comm=\\\"runc 

Please check whether the Docker is installed via snap.

sudo snap list
Name    Version    Rev   Tracking  Publisher   Notes
docker  18.09.9    423   stable    canonical✓  -

Usually it’s the permission problem caused by AppArmor if you installed Docker via snap. You can either follow the official step to fix it or reinstall Docker in non-snap way.


  • Nodes stall in NotReady status due to cni config uninitialized or pods are not able to access external network
$ kubectl describe nodes
KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

Kubernetes introduces RBAC since v1.6, we need to create correspond Service Account, RBAC rules and flannel daemonset so that kubelet can communicate with api server correctly. Execute following commands and wait for couple seconds before nodes turn into Ready status.

Here we use flannel as CNI plugin with this manifest, please add flag --pod-network-cidr= when init. Or you can use custom network CIDR by changing Network of net-conf.json in the manifest and init with the new CIDR.

$ kubeadm init --pod-network-cidr=
$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml
  • preflight warning when kubeadm init
[preflight] WARNING: Running with swap on is not supported. Please disable swap or set kubelet's --fail-swap-on flag to false.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10255/healthz' failed with error: Get http://localhost:10255/healthz: dial tcp [::1]:10255: getsockopt: connection refused.

Currently, running with swap is not support, we need to turn swap off to solve it.

$ sudo swapoff -a
  • Flannel failed to start
$ kubectl --namespace kube-system get pod
NAME                             READY     STATUS              RESTARTS   AGE
etcd-ubuntu                      1/1       Running             0          13m
kube-apiserver-ubuntu            1/1       Running             0          13m
kube-controller-manager-ubuntu   1/1       Running             0          13m
kube-dns-545bc4bfd4-4csqc        0/3       ContainerCreating   0          14m
kube-flannel-ds-bdg8j            0/1       Error               1          6s
kube-proxy-9brgj                 1/1       Running             0          14m
kube-scheduler-ubuntu            1/1       Running             0          13m

Flannel daemonset failed to start with following error message

$ kubectl --namespace kube-system logs -f kube-flannel-ds-bdg8j
E1102 06:37:57.177991       1 main.go:280] Error registering network: failed to acquire lease: node "ubuntu" pod cidr not assigned

We need to specify Pod CIDR range like following (ex.

$ sudo kubeadm init --pod-network-cidr=
  • Pod failed to scheduling due to PodToleratesNodeTaints

In default, master node is not allowed to schedule any pod on it.

$ kubectl describe pod xxx-698c5969c6-rtvht
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  7s (x6 over 22s)  default-scheduler  No nodes are available that match all of the predicates: PodToleratesNodeTaints (1).

Use following command to allow scheduling on master node.

$ kubectl taint nodes <node name> <node label>:NoSchedule-


$ kubectl get nodes --show-labels
ubuntu    Ready     master    33m       v1.8.2    beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ubuntu,node-role.kubernetes.io/master=

$ kubectl taint nodes ubuntu node-role.kubernetes.io/master:NoSchedule-
node "ubuntu" untainted

Advanced CMD 

Remove Kubernetes 

  • NOTICE: this cmd will remove all kubernetes related services and data.
$ sudo kubeadm reset

Add compute node 

Once kubeadm init is finished, you will see the command below with a valid token. Execute the command on new compute node to join the kubernetes cluster.

$ sudo kubeadm join --token <token> <api server ip>:<port>

Access remote Kubernetes api server 

$ cp admin.conf <path>/admin.conf
$ kubectl --kubeconfig <path>/admin.conf proxy
Starting to serve on
$ kubectl get pod --server=


See Also

To reproduce, republish or re-use the content, please attach with link: https://tachingchen.com/
comments powered by Disqus