Thursday, 24 September 2020

Kubernetes (k8s) Cluster with Kubeadm on AWS

This post list down the steps for creating Kubernetes cluster on AWS EC2 instance using Kubeadm. The setup will include one master node, one worker node and one sample application running on worker node accessible from browser. The setup is eligible for free tier AWS account.









1) Launch Ubuntu EC2 instance for master node






2) Install kubeadm and docker on master node

swapoff -a

sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
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
EOF

apt-get update && apt-get install -y kubelet kubeadm kubectl docker.io
service docker start

3) Setup control-plane with kubeadm init

Cluster setup with kubeadm requires a minimum of 2 CPUs on host machine. So running "kubeadm init" on free tier eligible EC2 instance will result in following error:

[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

To setup cluster on machine with 1 CPU, run kubeadm init with --ignore-preflight-errors=all. This will ignore the error and continue cluster setup. 

kubeadm init --ignore-preflight-errors all







Once done, control-plane should get initialized successfully with following message




Now execute the commands as mentioned in above initialization message.

mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config
Next deploy a pod network to cluster as mentioned in cluster initialization message:

Following is the setup for Weave Net. Weave Net provides a network to connect all pods together, implementing the Kubernetes model. Kubernetes uses the Container Network Interface (CNI) to join pods onto Weave Net. Weave Net can be installed onto your CNI-enabled Kubernetes cluster with command:

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
Check status of master node and all pods. (It took some time for coredns to get started. EC2 instance was also restarted in between)











Now we are ready to join worker nodes in the cluster. 

4) Setup worker node


1) Launch another Ubuntu EC2 instance

 

2) Install kubeadm and docker

swapoff -a

sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
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
EOF

apt-get update && apt-get install -y kubelet kubeadm kubectl docker.io

service docker start
For EC2 instance based on Amazon Linux AMI , the run following commands to install kubeadm

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
yum install kubeadm
If above command on Amazon Linux instance fails with following error:

Error: Package: kubelet-1.19.2-0.x86_64 (kubernetes)
           Requires: iptables >= 1.4.21
           Installed: iptables-1.4.18-1.22.amzn1.x86_64 (installed)
               iptables = 1.4.18-1.22.amzn1

then update iptables package with:

yum install 'ftp://ftp.pbone.net/mirror/ftp.scientificlinux.org/linux/scientific/7.3/x86_64/os/Packages/iptables-1.4.21-17.el7.x86_64.rpm'
3) Go to AWS console, and enable inbound access for port 6443 on Master EC2 instance security group.

4) Create kube config file. We can either use "kubectl config" command, or copy $HOME/.kube/config file from master node to worker node. So copy file from master node.

5) Now join the worker node to cluster with command displayed in kubeadm init output. If token is not know, then "kubeadm token list" command can be used on master node to list token.

systemctl enable docker.service

kubeadm join 172.31.0.8:6443 --token hkjm3g.kj7wwxj4lcc7x0y2 --discovery-token-ca-cert-hash sha256:88706a6fcd1a5a8c0c35f3311647f25a70359194e40a88ff3a4ace28f238abd9


 





Run "kubectl get nodes" on control plane or worker node to confirm worker node has joined successfully






4) Deploy sample application on worker node


a) Create deployment with nginx image

cat <<EOF >deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
EOF
2) Expose the deployment as NodePort type service

cat <<EOF >service.yaml
apiVersion: v1
kind: Service
metadata:
  name: service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - nodePort: 31000
    port: 80
    targetPort: 80
EOF
3) Go to AWS console, and enable inbound for port 31000 on worker node EC2 security group

4) Access nginx from browser with worker node public IP.









 


We have now a Kubernetes cluster configured with one master node, one worker node and sample application running on worker node. ✌

No comments:

Post a Comment