Introduction
Automate Kubernetes cluster installation using Ansible. This post will walk through setting up an Ansible control node on a VM. Ansible communicates to the manage servers through SSH and transfers modules via SFTP. Ansible server or control node will then provide keys to the server for seamless control. The servers that will be controlled will not require extra software. Will be using YAML to configure the managed nodes. Although, such as JSON is also possible, YAML is more human readable. Ansible can interact with hosts either through command line tools or its configuration scripts, which are known as Playbooks.Control Node Requirements
- Ansible control should have Python installed. Will be using Python3 in this installation
- Generate SSH keys
Installing Ansible
# Update packages
sudo apt update
# install Ansible
sudo apt-get -y install python3-pip
sudo apt install ansible
Setup Ansible Clients
# create inventory file
# inventory file contains list of nodes that will be managed by Ansible that is
# organized in groups.
# The default inventory is located in /ect/ansible/hosts
sudo nano /etc/ansible/hosts
# /etc/ansible/hosts
[k8smaster]
192.168.1.108
[k8sworker]
192.168.1.149
192.168.1.112
#
# checking your inventory
ansible-inventory --list -y
Connecting to the Managed Hosts
# create a user e.g. "k8s5gc" to all managed node
# and Ansible control node with sudo
sudo adduser k8s5gc
sudo usermod -aG sudo k8s5gc
# Test connectivity towards the managed hosts
ansible all -m ping -u k8s5gc
# OUTPUT
subok@k8s5gcans1:~$ ansible all -m ping -u k8s5gc
BECOME password:
worker1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
master | SUCCESS => {
"changed": false,
"ping": "pong"
}
worker2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
# generate password less keys
ssh-keygen
# transfer the key to the managed nodes
# master
ssh-copy-id k8s5gc@192.168.1.108
# worker
ssh-copy-id k8s5gc@192.168.1.112
ssh-copy-id k8s5gc@192.168.1.149
Our first Ansible YAML
We have completed the Ansible control node setup. In our first Ansible YAML configuration, we will create a user
Create a dedicated user e.g. “ansblusr1” to all managed node and add a dedicated sudo user entry without password.
# create_user.yml
---
- hosts: users
become: yes
vars_prompt:
- name: "new_user"
prompt: "User to be created in the remote nodes"
private: no
tasks:
- name: creating the user {{ new_user }}.
user:
name: "{{ new_user }}"
createhome: yes
shell: /bin/bash
append: yes
state: present
- name: Create a dedicated sudo entry file for the user.
file:
path: "/etc/sudoers.d/{{ new_user }}"
state: touch
mode: '0600'
- name: "Setting up Sudo without Password for user {{ new_user }}."
lineinfile:
dest: "/etc/sudoers.d/{{ new_user }}"
line: '{{ new_user }} ALL=(ALL) NOPASSWD: ALL'
validate: 'visudo -cf %s'
- name: Set authorized key for user copying it from current {{ new_user }} user.
authorized_key:
user: "{{ new_user }}"
state: present
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
- name: Print the created user.
shell: id "{{ new_user }}"
register: new_user_created
- debug:
msg: "{{ new_user_created.stdout_lines[0] }}"
...
$ ansible-playbook cretae_user.yaml
# OUTPUT
$ ansible-playbook create_user_prompt.yml
BECOME password:
User to be created in the remote nodes: ansblusr1
PLAY [users] *******************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************
The authenticity of host 'k8s5gcms01.subok-tech.local (192.168.1.108)' can't be established.
ECDSA key fingerprint is SHA256:qTh2vmB/nscRdTe8rbK163c2+m41acspksBEYykUbEI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
ok: [k8s5gcms01.subok-tech.local]
TASK [creating the user ansblusr1.] ********************************************************************************************************************************************************************
changed: [k8s5gcms01.subok-tech.local]
TASK [Create a dedicated sudo entry file for the user.] ************************************************************************************************************************************************
changed: [k8s5gcms01.subok-tech.local]
TASK [Setting up Sudo without Password for user ansblusr1.] ********************************************************************************************************************************************
changed: [k8s5gcms01.subok-tech.local]
TASK [Set authorized key for user copying it from current ansblusr1 user.] ****************************************************************************************************************************
changed: [k8s5gcms01.subok-tech.local]
TASK [Print the created user.] *************************************************************************************************************************************************************************
changed: [k8s5gcms01.subok-tech.local]
TASK [debug] *******************************************************************************************************************************************************************************************
ok: [k8s5gcms01.subok-tech.local] => {
"msg": "uid=1002(ansblusr1) gid=1002(ansblusr1) groups=1002(ansblusr1)"
}
PLAY RECAP *********************************************************************************************************************************************************************************************
k8s5gcms01.subok-tech.local : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# let's test a simple cli command to managed nodes
$ ansible all -m ping -u ansblusr1
BECOME password:
worker2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
worker1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
master | SUCCESS => {
"changed": false,
"ping": "pong"
}
k8s5gcms01.subok-tech.local | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.108 | SUCCESS => {
"changed": false,
"ping": "pong"
}
$ ansible all -a "uptime" -u ansblusr1
BECOME password:
worker1 | CHANGED | rc=0 >>
06:57:12 up 2 days, 23:23, 2 users, load average: 0.00, 0.04, 0.01
worker2 | CHANGED | rc=0 >>
06:57:12 up 2 days, 23:23, 2 users, load average: 0.00, 0.03, 0.04
master | CHANGED | rc=0 >>
06:57:13 up 2 days, 23:23, 4 users, load average: 1.95, 1.62, 1.46
k8s5gcms01.subok-tech.local | CHANGED | rc=0 >>
06:57:13 up 2 days, 23:23, 3 users, load average: 1.95, 1.62, 1.46
192.168.1.108 | CHANGED | rc=0 >>
06:57:13 up 2 days, 23:23, 3 users, load average: 1.95, 1.62, 1.46
Although more than 20years working on Mobile Telecommunications – Core Network. Always wanting to learn and try new things.