Create a Kubernetes Cluster in KVM using Ansible
Tags: ansible, devops, kubernetes, kvm
Published: 2020-07-06 13:53:05

I have been trying to use Ansible more often and since I don't have much idea about how Kubernetes works either I decided to learn about both at same time creating an Ansible playbook to create a Kubernetes Cluster in KVM.

You can see the readme file from my [GitHub](https://github.com/Project-42) with more information about the different files and how to make it work:

[README.md](https://github.com/Project-42/KVM_Ansible_Kubernetes/blob/master/README.md)

Here is the execution, but this post is more an invitation for you to try it out and tell me what different path would have you taken and see what errors I have made along the road.

If you visit the [GitHub repository](https://github.com/Project-42/KVM_Ansible_Kubernetes), you will see some issues I'm already aware and will try to fix, but I'm trying now to start actually using the cluster and see what can I do with it, so not sure how much of those will get fixed any time soon :P

```
14:24:57 |=| server in ~/Github/Kubernetes ± |master ✓| → time ansible-playbook playbook.yml

PLAY [create VMs] ****************************************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [localhost]

TASK [List all KVM Networks] *****************************************************************************
ok: [localhost]

TASK [Define Network] ************************************************************************************
changed: [localhost]

TASK [Create Network] ************************************************************************************
ok: [localhost]

TASK [Modify Network] ************************************************************************************
changed: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
changed: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
changed: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

TASK [Autostart Network] *********************************************************************************
changed: [localhost]

TASK [Create a directory if it does not exist] ***********************************************************
changed: [localhost]

TASK [Get VM disks] **************************************************************************************
ok: [localhost]

TASK [Create Seed] ***************************************************************************************
changed: [localhost]

TASK [Duplicate Seed] ************************************************************************************
changed: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
changed: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
changed: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

TASK [Get list of VMs] ***********************************************************************************
ok: [localhost]

TASK [define vm] *****************************************************************************************
changed: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
changed: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
changed: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

TASK [start vm] ******************************************************************************************
changed: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
changed: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
changed: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

TASK [add Kbernetes line to /etc/hosts] ******************************************************************
changed: [localhost]

TASK [add a list of hosts to /etc/hosts] *****************************************************************
changed: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
changed: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
changed: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

TASK [Test reachability] *********************************************************************************
ok: [localhost] => (item={'key': 'kmaster', 'value': {'name': 'kmaster', 'mem': 4096, 'cpus': 4, 'mac': '52:54:00:6c:20:00', 'ip': '10.10.1.10'}})
ok: [localhost] => (item={'key': 'knode1', 'value': {'name': 'knode1', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:01', 'ip': '10.10.1.11'}})
ok: [localhost] => (item={'key': 'knode2', 'value': {'name': 'knode2', 'mem': 2048, 'cpus': 4, 'mac': '52:54:00:6c:20:02', 'ip': '10.10.1.12'}})

PLAY [hostname] ******************************************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]
ok: [knode2]
ok: [knode1]

TASK [Update hostname using hostname] ********************************************************************
changed: [kmaster]
changed: [knode1]
changed: [knode2]

PLAY [Kubenertes requirements] ***************************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]
ok: [knode1]
ok: [knode2]

TASK [Disable swap] **************************************************************************************
changed: [knode1]
changed: [knode2]
changed: [kmaster]

TASK [Remove swapfile from /etc/fstab] *******************************************************************
changed: [knode1] => (item=swap)
changed: [kmaster] => (item=swap)
changed: [knode2] => (item=swap)

TASK [Set bridge-nf-call settings] ***********************************************************************
changed: [kmaster] => (item=modprobe bridge)
changed: [knode2] => (item=modprobe bridge)
changed: [knode1] => (item=modprobe bridge)
changed: [kmaster] => (item=echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf)
changed: [knode2] => (item=echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf)
changed: [knode1] => (item=echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf)
changed: [kmaster] => (item=modprobe br_netfilter)
changed: [knode2] => (item=modprobe br_netfilter)
changed: [knode1] => (item=modprobe br_netfilter)
changed: [kmaster] => (item=sysctl -p /etc/sysctl.conf)
changed: [knode2] => (item=sysctl -p /etc/sysctl.conf)
changed: [knode1] => (item=sysctl -p /etc/sysctl.conf)

TASK [Disable SELinux] ***********************************************************************************
[WARNING]: SELinux state temporarily changed from 'enforcing' to 'permissive'. State change will take
effect next reboot.
changed: [kmaster]
changed: [knode2]
changed: [knode1]

TASK [test to see if selinux is running] *****************************************************************
changed: [kmaster]
changed: [knode1]
changed: [knode2]

TASK [print a message if selinux is enabled] *************************************************************
ok: [kmaster] => {
    "msg": "selinux is enabled"
}
ok: [knode1] => {
    "msg": "selinux is enabled"
}
ok: [knode2] => {
    "msg": "selinux is enabled"
}

TASK [reboot vms] ****************************************************************************************
changed: [kmaster]
changed: [knode2]
changed: [knode1]

TASK [Install yum-utils lvm2 device-mapper-persistent-data] **********************************************
changed: [knode2]
changed: [knode1]
changed: [kmaster]

TASK [Add docker-ce-stable repository] *******************************************************************
changed: [knode1]
changed: [kmaster]
changed: [knode2]

PLAY [Update all nodes and install docker-ce] ************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]
ok: [knode1]
ok: [knode2]

TASK [upgrade all packages] ******************************************************************************
ok: [kmaster]
ok: [knode1]
ok: [knode2]

TASK [Install Docker] ************************************************************************************
changed: [knode2]
changed: [knode1]
changed: [kmaster]

PLAY [Continue Kubenertes requirements] ******************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]
ok: [knode2]
ok: [knode1]

TASK [Add user root to docker group] *********************************************************************
changed: [knode2]
changed: [knode1]
changed: [kmaster]

TASK [enable service docker] *****************************************************************************
changed: [knode2]
changed: [kmaster]
changed: [knode1]

TASK [Start Docker service] ******************************************************************************
changed: [knode2]
changed: [kmaster]
changed: [knode1]

TASK [Ensure Kubernetes repository exists.] **************************************************************
changed: [kmaster]
changed: [knode1]
changed: [knode2]

TASK [Add Kubernetes GPG keys.] **************************************************************************
changed: [knode2] => (item=https://packages.cloud.google.com/yum/doc/yum-key.gpg)
changed: [knode1] => (item=https://packages.cloud.google.com/yum/doc/yum-key.gpg)
changed: [kmaster] => (item=https://packages.cloud.google.com/yum/doc/yum-key.gpg)
changed: [knode2] => (item=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg)
changed: [knode1] => (item=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg)
changed: [kmaster] => (item=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg)

TASK [Make cache if Kubernetes GPG key changed.] *********************************************************
changed: [knode2]
changed: [kmaster]
changed: [knode1]

TASK [Install packages kubelet kubeadm kubectl] **********************************************************
changed: [kmaster]
changed: [knode2]
changed: [knode1]

TASK [enable service kubelet] ****************************************************************************
changed: [kmaster]
changed: [knode1]
changed: [knode2]

TASK [Restart kubelet] ***********************************************************************************
changed: [knode1]
changed: [knode2]
changed: [kmaster]

TASK [Stop and disable firewalld.] ***********************************************************************
changed: [kmaster]
changed: [knode2]
changed: [knode1]

PLAY [kmaster configuration] *****************************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]

TASK [Check whether Kubernetes has already been initialized.] ********************************************
ok: [kmaster]

TASK [Initialize Kubernetes master using flannel] ********************************************************
changed: [kmaster]

TASK [Initialize Kubernetes master using calico] *********************************************************
skipping: [kmaster]

TASK [Setup kubeconfig for root user] ********************************************************************
changed: [kmaster]

TASK [check if configuration is alredy in root home] *****************************************************
ok: [kmaster]

TASK [copy configuration from etc] ***********************************************************************
changed: [kmaster]

TASK [Install calico pod network] ************************************************************************
skipping: [kmaster]

TASK [Install flannel pod network] ***********************************************************************
changed: [kmaster]

TASK [Generate join command] *****************************************************************************
changed: [kmaster]

TASK [Copy join command to local file] *******************************************************************
changed: [kmaster]

PLAY [kubernetes cluster creation] ***********************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [knode1]
ok: [knode2]

TASK [Copy the join command to server location] **********************************************************
changed: [knode1]
changed: [knode2]

TASK [Join the node to cluster] **************************************************************************
changed: [knode2]
changed: [knode1]

TASK [Delete Join command file from KVM_HOST] ************************************************************
changed: [knode1]
ok: [knode2]

PLAY [kmaster restart] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************************
ok: [kmaster]

TASK [Reboot kmaster] ************************************************************************************
changed: [kmaster]

PLAY RECAP ***********************************************************************************************
kmaster                    : ok=37   changed=27   unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
knode1                     : ok=30   changed=23   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
knode2                     : ok=30   changed=22   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost                  : ok=16   changed=10   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


real    12m59.909s
user    3m39.977s
sys 0m32.073s

14:38:01 |=| server in ~/Github/Kubernetes ± |master ✓| → 
14:47:17 |=| server in ~/Github/Kubernetes ± |master ✓| → ssh root@kmaster 
[root@kmaster ~]# 
[root@kmaster ~]# kubectl get nodes 
NAME      STATUS   ROLES    AGE   VERSION
kmaster   Ready    master   13m   v1.18.5
knode1    Ready    <none>   12m   v1.18.5
knode2    Ready    <none>   12m   v1.18.5
[root@kmaster ~]#
[root@kmaster ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                              READY   STATUS    RESTARTS   AGE
kube-system   coredns-66bff467f8-b8w6j          1/1     Running   0          10m
kube-system   coredns-66bff467f8-vpdd6          1/1     Running   0          10m
kube-system   etcd-kmaster                      1/1     Running   1          10m
kube-system   kube-apiserver-kmaster            1/1     Running   1          10m
kube-system   kube-controller-manager-kmaster   1/1     Running   1          10m
kube-system   kube-flannel-ds-amd64-6fwvp       1/1     Running   1          10m
kube-system   kube-flannel-ds-amd64-g8vnj       1/1     Running   1          10m
kube-system   kube-flannel-ds-amd64-hdllq       1/1     Running   1          10m
kube-system   kube-proxy-2x6gs                  1/1     Running   0          10m
kube-system   kube-proxy-djrsh                  1/1     Running   1          10m
kube-system   kube-proxy-txqm7                  1/1     Running   0          10m
kube-system   kube-scheduler-kmaster            1/1     Running   1          10m
[root@kmaster ~]# w
 09:47:42 up 9 min,  1 user,  load average: 0.07, 0.25, 0.21
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.10.1.1        09:47    6.00s  0.01s  0.00s w

 



```


Hope this allows you to test Kubernetes in your system and more importantly, see how cool Ansible is even when you have little knowledge of it.