It is an unspoken consensus that 2020 was a stormy year. As this new year unravels, it is a fact that painful memories were inscribed on the minds and on the hearts of a lot of people around the globe. Lessons have been learnt, opportunities have been realized but what is most important is that you are safe. As 2021 unfolds, we hope that such the dark clouds that shrouded the past year will clear and pure sunshine will be allowed to illuminate our hopes and dreams.
In this guide, we shall be focusing on Kubernetes. Yes, this platform that continues to transform how we deploy and manage business applications. Whether it is CI/CD or you prefer the manual way, Kubernetes still remains the best choice to handle, manage, scale, and orchestrate your applications. For those who do not know, Kubernetes will be deprecating dockershim in future releases which means they will not be supporting docker as the container runtime. Before you throw tantrums, it is important to note that the change will not be affecting how you build and deploy your images. Docker contains a lot of components that Kubernetes has no use of bearing in mind that they need a simple light-weight container runtime to launch and run containers.
As you have already guessed, you can continue building your images using docker and Kubernetes will pull and run them using other container run times such as containerd or CRI-O. Containerd and CRI-O are pretty lightweight and they plug in fantastically to the Container Runtime Interface specifications.
In order for this deployment to start and succeed, we are going to need an extra server or computer that will be used as the installation server. This machine will contain Kubespray files and will connect to your servers where kubernetes will be installed and proceed to setup Kubernetes in them. The deployment architecture is simplified by the diagram below with one master, one etcd and two worker nodes.
Make sure you generate SSH keys on the builder machine and copy your public key to the Debian 10 servers where Kubernetes will be built.
Having said all of that, we are going to install Kubernetes on Debian 10 servers using Kubespray and we shall be using containerd as the container runtime. The following steps will suffice to get your cluster ready to accommodate your apps.
Step 1: Prepare your servers
Preparing your servers is a crucial step which ensures that every aspect of the deployment runs smoothly till the very end. In this step, we shall be doing simple updates and making sure that important packages have been installed. Issue the commands below in each of your servers to kick everything off on a clean slate.
sudo apt update sudo apt upgrade
Step 2: Clone Kubespray Git repository and add configurations
In this step, we are going to fetch Kubespray files in our local machine (the installer machine) then make the necessay configurations by choosing containerd as the container run time as well as populating the requisite files with the details of our servers (etc, masters, workers).
$ cd ~ $ git clone https://github.com/kubernetes-sigs/kubespray.git Cloning into 'kubespray'...
Change to the project directory:
$ cd kubespray
This directory contains the inventory files and playbooks used to deploy Kubernetes.
Step 3: Prepare Local machine
On the Local machine where you’ll run deployment from, you need to install pip Python package manager.
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python3 get-pip.py --user
Step 4: Create Kubernetes Cluster inventory file and Install dependencies
The inventory is composed of 3 groups:
- kube-node : list of kubernetes nodes where the pods will run.
- kube-master : list of servers where kubernetes master components (apiserver, scheduler, controller) will run.
- etcd: list of servers to compose the etcd server. You should have at least 3 servers for failover purpose.
There are also two special groups:
- calico-rr : explained for advanced Calico networking cases
- bastion : configure a bastion host if your nodes are not directly reachable
Create an inventory file:
cp -rfp inventory/sample inventory/mycluster
Define your inventory with your server’s IP addresses and map to correct node purpose.
$ vim inventory/mycluster/inventory.ini master0 ansible_host=172.20.193.154 ip=172.20.193.154 worker1 ansible_host=172.20.198.157 ip=172.20.198.157 worker2 ansible_host=172.20.202.161 ip=172.20.202.161 # ## configure a bastion host if your nodes are not directly reachable # bastion ansible_host=x.x.x.x ansible_user=some_user [kube-master] master0 [etcd] master0 [kube-node] worker1 worker2 [calico-rr] [k8s-cluster:children] kube-master kube-node calico-rr
Add A records to /etc/hosts on your workstation.
$ sudo vim /etc/hosts 172.20.193.154 master0 172.20.198.157 worker1 172.20.202.161 worker2
If your private ssh key has passphrase, save it before starting deployment.
$ eval `ssh-agent -s` && ssh-add Agent pid 4516 Enter passphrase for /home/centos/.ssh/id_rsa: Identity added: /home/centos/.ssh/id_rsa (/home/centos/.ssh/id_rsa)
Install dependencies from requirements.txt
# Python 2.x sudo pip install --user -r requirements.txt # Python 3.x sudo pip3 install -r requirements.txt
Confirm ansible installation.
$ ansible --version ansible 2.9.6 config file = /etc/ansible/ansible.cfg configured module search path = ['/home/tech/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3/dist-packages/ansible executable location = /usr/bin/ansible python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
Review and change parameters under inventory/mycluster/group_vars
We shall review and change parameters under inventory/mycluster/group_vars to ensure that Kubespray uses containerd.
##Change from docker to containerd at around line 176 and add the two lines below $ vim inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml container_manager: containerd etcd_deployment_type: host kubelet_deployment_type: host
Step 5: Deploy Kubernetes Cluster with Kubespray Ansible Playbook
Now execute the playbook to deploy Production ready Kubernetes with Ansible. Please note that the target servers must have access to the Internet in order to pull images.
Start the deployment by running the command:
ansible-playbook -i inventory/mycluster/inventory.ini --become \ --user=tech --become-user=root cluster.yml
Replace “tech” with the remote user ansible will connect to the nodes as. You should not get failed task in execution.
Installation progress should look like below
The very last messages will look like the screenshot shared below.
Once the playbook executes to the tail end, login to the master node and check cluster status.
$ sudo kubectl cluster-info Kubernetes master is running at https://172.20.193.154:6443 To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
You can also check the nodes
$ sudo kubectl get nodes NAME STATUS ROLES AGE VERSION master0 Ready master 11m v1.19.5 worker1 Ready
10m v1.19.5 worker2 Ready 10m v1.19.5 $ sudo kubectl get endpoints -n kube-system NAME ENDPOINTS AGE coredns 10.233.101.1:53,10.233.103.1:53,10.233.101.1:53 + 3 more... 23m kube-controller-manager 27m kube-scheduler 27m
Step 6: Install Kubernetes Dashboard & Access
This is an optional step in case you do not have other options to access your Kubernetes cluster via a cool interface like Lens or VMware Octant .To get the dashboard installed, follow the detailed guide below.
And once it is working, you will need to create an admin user to access your cluster. Use the guide below to fix that:
If you like, you can also use Active Directory to authenticate your users using how to Authenticate Kubernetes Dashboard Users With Active Directory.
Step 7: Install Nginx-Ingress controller
In this step, we are going to include an ingress controller to help us access our services from outside the cluster. The simplest approach to enabling external access to services is using the NodePort service type. The disadvantage of NodePort is that services must use a limited range of ports (by default, in the 30000 to 32767 range), and just a single port can be mapped to a single service.
The ingress resource makes it possible to expose multiple services using a singular external endpoint, a load balancer, or both at once. Taking this approach, teams can enact host, prefix, and other rules to route traffic to defined service resources however they prefer.
We shall therefore install Nginx Ingress controller and configure it so that we can be able to access one sample application we will setup. To install Nginx Ingress controller, download the manifest below and apply it in your cluster
wget kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.1/deploy/static/provider/cloud/deploy.yaml
Then install using kubectl
sudo kubectl apply -f deploy.yaml
Confirm that the ingress controller pod is running after sometime
$ sudo kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-f7d8c 0/1 Completed 0 109m ingress-nginx-admission-patch-4fxtb 0/1 Completed 0 109m ingress-nginx-controller-85df779996-b9c2k 1/1 Running 0 109m
Next, we are going to deploy httpbin application then use our ingress controller to access it. Fetch httpbin as follows
Then install using kubectl
sudo kubectl apply -f httpbin.yaml
In case you would wish it to be deployed in a different namespace, simply edit the file before applying it.
Step 8: Add Ingress Rule to access your service
Until now, we have a working ingress controller and a sample deployment (httpbin) that we shall use to test how it works. Create the following Ingress resource that will target httpbin. If you read the manifest we fetched earlier, you will notice that it creates a service called “httpbin” and will be listening at port 8000. Armed with that information, let us create an Ingress thus:
$ vim httpbin-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: httpbin-ingress namespace: default annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: master.computingpost.com http: paths: - path: / pathType: Prefix backend: service: name: httpbin port: number: 8000
Save the file then apply it in your cluster. Note that “master.
computingpost.com” must be resolving to the IP of the ingress as shown below.
$ sudo kubectl apply -f httpbin-ingress.yaml ingress.networking.k8s.io/httpbin-ingress configured
Then confirm that the ingress was created successfully
$ sudo kubectl get ing Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE approot
master1.computingpost.com 172.20.202.161 80 168m httpbin-ingress master.computingpost.com 172.20.202.161 80 108m
What is happening here is that, any traffic that will come from “master.
computingpost.com” root url, it will be routed to the httpbin service automatically. Is that not pretty!
What else are we left to do than to test if we can reach our serivice? First, let us investigate how our Ingress Controller service looks like.
$ sudo kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.233.8.37
80:30242/TCP,443:31635/TCP 123m ingress-nginx-controller-admission ClusterIP 10.233.51.71 443/TCP 123m
As you will notice, our “ingress-nginx-controller” is exposed via NodePort. That is very good information because we can be really frustrated while accessing our applications in other ways. With that in mind, let us now open up our browser, and point it to our application at //master.
computingpost.com:30242. And ensure that port 30242 has been opened in “master.
computingpost.com” node’s firewall. You should see something eye popping as shown below:
Kubespray makes the deployment of Kubernetes a cinch. Thanks to the team that developed the playbooks involved in achieving this complex deployment, we now have a ready platform just waiting for your applications that will serve the world.
In case you have a bigger cluster you intend to setup, simply place the various components (etcd, master, workers etc) in the deployment scripts and Kubespray will handle the rest. May your year flourish, your endeavor bear good fruits and your investments pay off. Let us face it with fortitude, with laughter, hard work and grace.