AWS EC2 — Fully automated installation of Kubernetes cluster (master node) — User Data

John Gakhokidze
3 min readNov 9, 2020

Well, I know, there are AWS EKS and AWS ECS, if you need to run containers. But sometime you need to test something, or you are developing plugin for Kubernetes.

So, here is fully automated procedure, either single node with untainted node, e.g., you can run pods on master node, or master node, and it outputs join command to file. Also you can install helm, if you need it (last lines)

Installation has been tested on Ubuntu 20.04 LTS

This part is user data, and below is CloudFormation Template

Please do not copy/past, instead, files are available on Github

  • Preparing prerequisites

#!/bin/bash
apt update
apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL
https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository “deb [arch=amd64]
https://download.docker.com/linux/ubuntu focal stable”

  • Installing Docker

apt update
apt-cache policy docker-ce
apt install docker-ce -y

  • Be sure to understand, if you follow official Kubernetes documentation, in Ubuntu 20 it does not work, that is why, I did modification to script
  • Adding Kubernetes repositories

#Next 2 lines are different from official Kubernetes guide, but the way Kubernetes describe step does not work
curl -s
https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add
echo “deb
https://packages.cloud.google.com/apt kubernetes-xenial main” > /etc/apt/sources.list.d/kurbenetes.list

  • Turning off swap

#Turn off swap
swapoff -a

  • Installing Kubernetes tools

apt update
apt install kubelet kubeadm kubectl -y

  • next line is getting EC2 instance IP, for kubeadm to initiate cluster

#we need to get EC2 internal IP address- default ENI is eth0
export ipaddr=`ip address|grep eth0|grep inet|awk -F ‘ ‘ ‘{print $2}’ |awk -F ‘\/’ ‘{print $1}’`

  • Kubernetes cluster init

#You can replace 172.16.0.0/16 with your desired pod network
kubeadm init — apiserver-advertise-address=$ipaddr — pod-network-cidr=172.16.0.0/16

#this adds .kube/config for root account, run same for ubuntu user, if you need it
mkdir -p /root/.kube
cp -i /etc/kubernetes/admin.conf /root/.kube/config

#Line bellow only if you need to run for user ubuntu

  • Installing network CNI, here are examples of Calico and Flannel, but you can replace with others

#You need to uncomment one of 2 next lines — flannel and calico used here as an example. Example below is using calico

#Uncomment next line if you want flannel Cluster Pod Network
#curl -o /root/kube-flannel.yml
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#kubectl — kubeconfig /root/.kube/config apply -f /root/kube-flannel.yml

#Uncomment next line if you want calico Cluster Pod Network
curl -o /root/calico.yaml
https://docs.projectcalico.org/v3.16/manifests/calico.yaml
kubectl — kubeconfig /root/.kube/config apply -f /root/calico.yaml

  • Do you need more nodes? Uncomment below

#Uncomment next line if you are planning more nodes, this will put cluster join command to /root/clusterjoin.sh file
#kubeadm token create — print-join-command >clusterjoin.sh

  • Uncomment to untaint master node

#Uncomment the next line if you need to run pods on master node
#kubectl taint node — all node-role.kubernetes.io/master:NoSchedule-

  • Uncomment to install helm

#Uncomment bellow lines if you need to install helm
#curl
https://baltocdn.com/helm/signing.asc | sudo apt-key add -
#echo “deb
https://baltocdn.com/helm/stable/debian/ all main” | tee /etc/apt/sources.list.d/helm-stable-debian.list
#apt update
#apt install helm -y

  • Cloud Formation Template — get it from Github

Some note:

User data is base64 already encoded, be sure:

  1. Check it yourself , for example on https://www.base64encode.org/
  2. If you change something in User Data, you will need to replace User Data (between double quotes)
  3. You need to provide Security Group, Subnet, and KeyPair name
  4. AMI is for us-east-1 - change ami and/or EC2 instance type , if you need something different

--

--