Skip to content

Commit

Permalink
Merge pull request #225 from alacuku/alacuku-pcn-k8s-vagrant-ansible
Browse files Browse the repository at this point in the history
adding ansible playbooks for deploying the pcn-k8s component.
  • Loading branch information
frisso committed Nov 8, 2019
2 parents 6a72cb4 + 6b71464 commit 09aa416
Show file tree
Hide file tree
Showing 17 changed files with 590 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tests/ansible_vagrant/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.vagrant/
kubernetes-playbooks/host_vars/
*.log
kubernetes-playbooks/join-command
Vagranfile
kubernetes-playbooks/inventory.ini
37 changes: 37 additions & 0 deletions tests/ansible_vagrant/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Ansible playbook
An ansible playbook to install a simple k8s cluster with a master node and two worker nodes. The CNI plugin is pcn-k8s. Vagrant is used to provide the VMs.

## Requirements
* Vagrant 2.2.5 or higher
* Ansible 2.8.5 or higher

## Usage
* `ansible-playbook --ask-become-pass master-playbook.yml`
* Connecting to a node: `ssh vagrant@k8s-master-1`.

## Configuration
All the configuration variable can be found in *kubernetes-playbooks/group_vars/all/vars.yml*. Before playing the playbook have a look at the vars.yml file and change the variables according to your needs. Please pay attention to the **Vagrant Configuration Section** and modify the variables in such a way that suits the host's network interfaces and resources such RAM and CPUs.
By default the playbook checks if ssh key named *vagrant_machines* exists in *~/.ssh*. If it does exist than is copied in the VMs and used to login during the playbook execution and by the user to access via SSH the k8s nodes. If it does not exist than a new ssh key is generated and used to configure the VMs.
If you want to change a parameter on the fly without modifying it in the file *kubernetes-playbooks/group_vars/all/vars.yml* you can pass it to the **ansible-playbook** command like this: `ansible-playbook --ask-become-pass --extra-vars '{"k8s_worker_nodes_ips": [192.168.0.24]}' master-playbook.yml`

## How does it work?
The first playbook to be executed is *bootstrap.yml* which does the following:
* Reads the variables in *kubernetes-playbooks/group_vars/all/vars.yml*
* Generates the **Vagrantfile** from the *kubernetes-playbooks/roles/bootstrap/templates/VagrantFile.j2*
* Generates the **kubernetes-playbooks/inventory.ini** from the *kubernetes-playbooks/roles/bootstrap/templates/inventory.ini.j2*
* For each IP in **k8s_worker_nodes_ips** generates a new file in *kubernetes-playbooks/host_vars* using the **k8s_worker_node_prefix** and populates it with an ip taken from the list.
* For each node to be part of the k8s-cluster it adds the hostname and IP address associated to that host in */etc/hosts* in the localhost filesystem.
* At the end it runs the vagrant program to provision the VMs.

Then *vagrant-netconfig*, *k8s-master-node* and *k8s-worker-node* playbooks are played. Their names are self-explanatory on what the do.



## Adding additional worker-nodes
If more worker-nodes are needed:
* add the ip address of the node in group_vars/all/vars.yml

## Remote user
The remote user which runs the ansible commands is defined in two places:
* ansible.cfg
* group_vars/all/vars.yml
8 changes: 8 additions & 0 deletions tests/ansible_vagrant/kubernetes-playbooks/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[defaults]
inventory = inventory.ini
remote_user = vagrant
host_key_checking = False
become = False

[ssh_connection]
retries=2
8 changes: 8 additions & 0 deletions tests/ansible_vagrant/kubernetes-playbooks/bootstrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Playbook used to configure the files before launching the vagrant environment
# Check the role for more information
- hosts: localhost
become: no
roles:
- bootstrap

82 changes: 82 additions & 0 deletions tests/ansible_vagrant/kubernetes-playbooks/group_vars/all/vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#These variables are shared among all roles

docker_packages:
- docker-ce=5:18.09.9~3-0~ubuntu-xenial
- docker-ce-cli=5:18.09.9~3-0~ubuntu-xenial
- containerd.io

#Latest versions
k8s_packages:
- kubelet
- kubeadm
- kubectl

#Needed for apt over HTTPS
apt_packages:
- apt-transport-https
- ca-certificates
- curl
- gnupg-agent
- software-properties-common

##path to the public key used to ssh to the machines
#pub_key_path: /home/aldo/.ssh/vagrant_machines.pub

#pod-network-cidr used in k8s
pod_network_cidr: 10.244.0.0/16

#user to be added to the k8s group
user: vagrant

# zone to which set the time
time_zone: Europe/Rome

#####################
#Nodes Configuration#
#####################

#Node configuration. The cluster can have only one master node and many worker nodes as needed.
k8s_master_nodes_ips:
- 192.168.0.23

k8s_worker_nodes_ips:
- 192.168.0.24
- 192.168.0.25
- 192.168.0.26
- 192.168.0.27

#theese prefixes are used when generating the names of the nodes. Used in the host_vars files, inventory.ini and in /etc/hosts in the local system.
k8s_master_node_prefix: k8s-master-

k8s_worker_node_prefix: k8s-node-


############################
#Vagrant file configuration#
############################

#flavor of the operating system to be used in the VMs
image_name: "ubuntu/bionic64"
#the nic on your host to which the VM interface will be bridged.
bridge_nic: enp1s0f0

#Path to the generated SSH private key file
ssh_key_path: ~/.ssh
ssh_key_name: vagrant_machines

#path to the public key used to ssh to the machines, if this key does not exist than a new one is generated with the same name
pub_key_path: "{{ssh_key_path}}/{{ssh_key_name}}.pub"

#Amount of RAM memory for a single VM
virtual_memory_size: 4096

#Amount of Virtual CPUs for a single VM
virtual_cpus: 2

###################
#CNI configuration#
###################

cni_manifests:
- https://raw.githubusercontent.com/polycube-network/polycube/master/src/components/k8s/standalone_etcd.yaml
- https://raw.githubusercontent.com/polycube-network/polycube/master/src/components/k8s/pcn-k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Playbook used to configure a master node.
# Check the role for more information
- hosts: k8s_master_nodes
become: yes
roles:
- k8s-master

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# Playbook used to configure a worker node.
# Check the role for more information
- hosts: k8s_worker_nodes
become: yes
roles:
- k8s-worker
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# Master playbook to run a once the whole configuration.
# Check the specific playbooks and roles to have more information.
- import_playbook: bootstrap.yml
- import_playbook: vagrant-netconfig.yml
- import_playbook: k8s-master-node.yml
- import_playbook: k8s-worker-node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
# tasks file for bootstrap
#This task generates the vagrant file for the VMs to be created.

- name: Template the VagrantFile.j2 configuration file to ../Vagrantfile
template:
src: VagrantFile.j2
dest: ../Vagrantfile
delegate_to: localhost

- name: Template the inventory.ini.j2 configuration file to invetory.ini
template:
src: inventory.ini.j2
dest: inventory.ini
delegate_to: localhost

- name: Refresh inventory to ensure that the new generated one is used
meta: refresh_inventory

- name: Find and save in a local variable all host_vars files
find:
paths: ./host_vars
patterns: "*.yml"
register: files_to_delete

- name: Delete all the host_vars files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{ files_to_delete.files }}"

- name: Creating the "host_vars" file for each k8s' master-node
file:
path: ./host_vars/{{item}}.yml
state: touch
mode: u=rw,g=r,o=r
loop: "{{ groups.k8s_master_nodes }}"

- name: Populating the k8s-master-nodes host_vars files with the node ip
lineinfile:
path: "./host_vars/{{ item.0 }}.yml"
line: "node_ip: {{ item.1 }}"
loop: "{{ groups.k8s_master_nodes|zip(k8s_master_nodes_ips)|list }}"

- name: Creating the "host_vars" file for each k8s' worker-node
file:
path: ./host_vars/{{item}}.yml
state: touch
mode: u=rw,g=r,o=r
loop: "{{ groups.k8s_worker_nodes }}"

- name: Populating the k8s-worker-nodes host_vars files with the node ips
lineinfile:
path: "./host_vars/{{ item.0 }}.yml"
line: "node_ip: {{ item.1 }}"
loop: "{{ groups.k8s_worker_nodes|zip(k8s_worker_nodes_ips)|list }}"

- name: Removing k8s-master-nodes from /etc/hosts in the localhost if they already exist
become: yes
lineinfile:
path: /etc/hosts
regexp: ".*{{ item }}.*"
state: absent
loop: "{{ groups.k8s_master_nodes }}"

- name: Adding k8s-master-nodes from /etc/hosts in the localhost
become: yes
lineinfile:
path: /etc/hosts
line: "{{ item.1 }} {{item.0}}"
loop: "{{ groups.k8s_master_nodes|zip(k8s_master_nodes_ips)|list }}"

- name: Removing k8s-worker-nodes from /etc/hosts in the localhost if they already exist
become: yes
lineinfile:
path: /etc/hosts
regexp: ".*{{ item }}.*"
state: absent
loop: "{{ groups.k8s_worker_nodes }}"

- name: Adding k8s-worker-nodes to /etc/hosts in the localhost
become: yes
lineinfile:
path: /etc/hosts
line: "{{ item.1 }} {{item.0}}"
loop: "{{ groups.k8s_worker_nodes|zip(k8s_worker_nodes_ips)|list }}"

- name: Check if the ~/.ssh directory exists, if not create it
file:
path: "{{ ssh_key_path }}"
state: directory
mode: '0755'

- name: Checking if ssh key exists and if not generate a new one
openssh_keypair:
path: "{{ ssh_key_path }}/{{ssh_key_name}}"

- name: Run "vagrant up" with the Vagrantfile as input.
command: vagrant up
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
IMAGE_NAME = "{{ image_name }}"
BRIDGE_NIC = "{{ bridge_nic }}"

Vagrant.configure("2") do |config|
config.ssh.insert_key = true

config.vm.provider "virtualbox" do |v|
v.memory = {{ virtual_memory_size }}
v.cpus = {{ virtual_cpus }}
end
{% for node_ip in k8s_master_nodes_ips %}
config.vm.define "k8s-master" do |master|
master.vm.box = IMAGE_NAME
# change the bridge interface to match the one on your host machine
master.vm.network "public_network", bridge: BRIDGE_NIC, ip: "{{ node_ip }}"
master.vm.hostname = "k8s-master"
master.vm.provision "ansible" do |ansible|
# Configures the ssh-key
ansible.playbook = "kubernetes-playbooks/vagrant-ssh-key.yml"
ansible.extra_vars = {
pub_key_path: "{{ pub_key_path }}"
}
end
end
{% endfor %}

{% for node_ip in k8s_worker_nodes_ips %}
config.vm.define "node-{{ loop.index }}" do |node|
node.vm.box = IMAGE_NAME
# change the bridge interface to match the one on your host machine
node.vm.network "public_network", bridge: BRIDGE_NIC, ip: "{{ node_ip }}"
node.vm.hostname = "node-{{ loop.index }}"
node.vm.provision "ansible" do |ansible|
# Configures the ssh-key
ansible.playbook = "kubernetes-playbooks/vagrant-ssh-key.yml"
ansible.extra_vars = {
pub_key_path: "{{ pub_key_path }}"
}
end
end
{% endfor %}
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#this file is autogenerated by the bootstrap

[k8s_master_nodes]
{% for node_ip in k8s_master_nodes_ips %}
{{ k8s_master_node_prefix }}{{ loop.index }}
{% endfor %}

[k8s_worker_nodes]
{% for node_ip in k8s_worker_nodes_ips %}
{{ k8s_worker_node_prefix}}{{ loop.index }}
{% endfor %}

## All nodes
[all_nodes:children]
k8s_master_nodes
k8s_worker_nodes

0 comments on commit 09aa416

Please sign in to comment.