Kubernetes with Amazon Web Service (AWS), Kubeadm and Calico.

In this post I will be demonstrating how to install Kubernetes on AWS platform using Kubeadm for bootstrapping the kubernetes cluster and Calico as container networking interface (CNI). The Kubernetes cluster for this setup will consist of a master node and two worker nodes both running Ubuntu 16.04 LTS. We will be running Kubernetes version 1.10.0 in our cluster. Let’s get started!

First, we need to setup our AWS environment which consist of the EC2, Security Group , and VPC configuration.
let us create how instance and configure security groups. on the EC2 dashboard page click on Launch Instance ->

We will choose Ubuntu Server 16.04 LTS AMI

We will select the T2.medium instance type for our Master node. User can choose instance type that fit their use case.

Next we will configure Instance details. Here, I have left the details as default. I am running in default VPC with the subnets being auto-assigned.

Next, we will configure storage. I have gone with  the defaults for the purpose of this demo.

Next, we will configure Tags. I have decided not to add any tags.

Next, we will the security Group. This part is crucial for setting up the cluster. The SG will determine what ports can communication within the cluster. We will need to allow port 6443 and allow all communication within the subnet (subnet CIDR can be gotten from the VPC CIDR that we are using). I have also allowed ssh traffic  from my IP and allowed HTTP and HTTPS traffic. I will not advise to use this configuration in a production environment as it is not secure.

Next we review and then launch. you will also be prompted to create  access-key.

go back to the  EC2 dashboard to view the state of Instance.

I have also named the first Instance created as Master.

Next we will re-run the instance creation steps to create the remaining two Ubuntu Server 16.04 LTS nodes. This time we will select the T2.micro instance type and use the same security group that we used for the first instance (node). The access key can remain the same also.

now that we have setup the three instances (nodes) . let’s us SSH into each instance with the public key we downloaded earlier and setup the Kubernetes v1.10.

Let us SSH into Master and run the below commands.

we will first need to change the public key permission.

tunde:~ babatundeolu-isa$ chmod 400 kubecalico.pem
tunde:~ babatundeolu-isa$ ssh -i "kubecalico.pem" ubuntu@ec2-18-218-194-202.us-east-2.compute.amazonaws.com

In our master node, we will need to disable swap. This is because when Swap is enabled Kubernetes does not know how to handle memory eviction

ubuntu@ip-172-31-7-182:~$ swapoff -a
ubuntu@ip-172-31-7-182:~$ sudo apt-get update
ubuntu@ip-172-31-7-182:~$ sudo apt-get install -y apt-transport-https

we will now change to root user.

ubuntu@ip-172-31-7-182:~$ sudo su
root@ip-172-31-7-182:/home/ubuntu# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add
root@ip-172-31-7-182:/home/ubuntu# cat </etc/apt/sources.list.d/kubernetes.list
 deb http://apt.kubernetes.io/ kubernetes-xenial main

Install Docker, Kubeadm, Kubelet, Kubectl and Kubernetes-cni

root@ip-172-31-7-182:/home/ubuntu# apt update
root@ip-172-31-7-182:/home/ubuntu# apt-get install -y docker.io
root@ip-172-31-7-182:/home/ubuntu# apt-get install -y kubectl=1.10.0-00
root@ip-172-31-7-182:/home/ubuntu# apt-get install -y kubelet=1.10.0-00
root@ip-172-31-7-182:/home/ubuntu# apt-get install -y kubeadm=1.10.0-00
root@ip-172-31-7-182:/home/ubuntu# apt-get install -y kubernetes-cni

we have now installed all the tools needed to setup the Kubernetes cluster.

next we will bootstrap master node with Kubeadm. we have also used the --pod-network-cidr flag to specify the CIDR block that Calico (CNI) will use and the --kubernetes-version flag to indicate the version of kubernetes we want to run.

root@ip-172-31-7-182:/home/ubuntu# kubeadm init --pod-network-cidr=  --kubernetes-version stable-1.10

we should get an output similar to below contain the token required for worker nodes join Master.

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following 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 3b4od2.xznw4lvat26ckjdq --discovery-token-ca-cert-hash sha256:157cfec2e60e38debe1fb206138830a3745dd7a86498f5e1be6f06a8887565bc
root@ip-172-31-7-182:/home/ubuntu# exit

run the next set of commands as regular user.

ubuntu@ip-172-31-7-182:~$ mkdir -p $HOME/.kube
ubuntu@ip-172-31-7-182:~$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
ubuntu@ip-172-31-7-182:~$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

we will now install Calico CNI. it is required to enable pod communication within the cluster.

ubuntu@ip-172-31-7-182:~$ kubectl apply -f https://docs.projectcalico.org/v2.6/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml

verify pods are running in the cluster and the Master node is ready.

ubuntu@ip-172-31-7-182:~$ kubectl get pods --all-namespaces
ubuntu@ip-172-31-7-182:~$ kubectl get node
NAME              STATUS    ROLES     AGE       VERSION
ip-172-31-7-182   Ready     master    14m       v1.10.0

As you can see our Master node is ready and running Kubernetes version 1.10.0.
let us now add the remaining two worker nodes to the Kubernetes cluster using the token provided by Kubeadm during Master setup.

we will need to install Docker, Kubelet and Kubeadm on the worker nodes.

ubuntu@ip-172-31-38-135:~$ swapoff -a
ubuntu@ip-172-31-38-135:~$ sudo apt-get update
ubuntu@ip-172-31-38-135:~$ sudo apt-get install -y apt-transport-https
ubuntu@ip-172-31-38-135:~$ sudo su 
root@ip-172-31-38-135:/home/ubuntu# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add
root@ip-172-31-38-135:/home/ubuntu# cat </etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
root@ip-172-31-38-135:/home/ubuntu# apt update
root@ip-172-31-38-135:/home/ubuntu# apt-get install -y docker.io
root@ip-172-31-38-135:/home/ubuntu# apt-get install -y kubelet=1.10.0-00
root@ip-172-31-38-135:/home/ubuntu# apt-get install -y kubeadm=1.10.0-00

next we will join the master node using the token generated earlier.

root@ip-172-31-38-135:/home/ubuntu# kubeadm join --token 3b4od2.xznw4lvat26ckjdq --discovery-token-ca-cert-hash sha256:157cfec2e60e38debe1fb206138830a3745dd7a86498f5e1be6f06a8887565bc
[preflight] Running pre-flight checks.
	[WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[discovery] Trying to connect to API Server ""
[discovery] Created cluster-info discovery client, requesting info from ""
[discovery] Requesting info from "" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server ""
[discovery] Successfully established connection with API Server ""

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

we will run the same worker step to join the last worker node to the cluster.

Once that is done, let us go ahead and run kubectl get nodes on the master to the nodes have joined the cluster.

ubuntu@ip-172-31-7-182:~$ kubectl get node
NAME               STATUS    ROLES     AGE       VERSION
ip-172-31-36-82    Ready         2m        v1.10.0
ip-172-31-38-135   Ready         8m        v1.10.0
ip-172-31-7-182    Ready     master    35m       v1.10.0

let us view the cluster health.

ubuntu@ip-172-31-7-182:~$ kubectl get componentstatus
NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-0               Healthy   {"health": "true"}

We have setup Kubernetes cluster running version 1.10.0 using Kubeadm on AWS and used Calico as CNI of choice. Practice using Kubernetes using this cluster we have created together.




3 thoughts on “Kubernetes with Amazon Web Service (AWS), Kubeadm and Calico.”

  1. Hi BabaTunde…
    I tried the command, but it is not runing and throwing below error. May be I am doing some stupid mistake, but not sure what is that…

    root@ip-172-31-11-111:/home/ubuntu# cat deb http://apt.kubernetes.io/ kubernetes-xenial main
    bash: http://apt.kubernetes.io/: No such file or directory
    root@ip-172-31-11-111:/home/ubuntu# > EOF

Leave a Reply

Your email address will not be published. Required fields are marked *