Initial commit and release

This commit is contained in:
Xan Manning 2019-03-09 20:54:44 +00:00
commit 750c72295e
20 changed files with 522 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.vagrant
*.retry
VAULT_PASSWORD
VAULT_PASS
.vault_pass
.vault_pass.asc
tests/fetch
tests/ubuntu-*.log

44
README.md Normal file
View File

@ -0,0 +1,44 @@
# k3s
Ansible role for installing k3s as either a standalone server or cluster.
## Requirements
This role has been tested on Ansible 2.6.0+ against the following Linux Distributions:
- CentOS 7
- Debian 9
- Ubuntu 18.04 LTS
## Role Variables
| Variable | Description | Default Value |
|--------------------------------|--------------------------------------------------------------------------|--------------------------------|
| `k3s_release_version` | Use a specific version of k3s, eg. `v0.1.0`. Specify `false` for latest. | `false` |
| `k3s_github_url` | Set the GitHub URL to install k3s from. | https://github.com/rancher/k3s |
| `k3s_install_dir` | Installation directory for k3s. | `/usr/local/bin` |
| `k3s_control_workers` | Are control hosts also workers? | `true` |
| `k3s_ensure_docker_installed ` | Use Docker rather than Containerd? | `false` |
## Dependencies
No dependencies on other roles.
## Example Playbook
Example playbook:
```yaml
- hosts: k3s_nodes
roles:
- { role: xanmanning.k3s, k3s_control_workers: false }
```
## License
BSD
## Author Information
[Xan Manning](https://xanmanning.co.uk/)

17
defaults/main.yml Normal file
View File

@ -0,0 +1,17 @@
---
# Use a specific k3s version, if set to "false" we will get the latest
# k3s_release_version: v0.1.0
k3s_release_version: false
# URL for GitHub project
k3s_github_url: https://github.com/rancher/k3s
# Installation directory for k3s
k3s_install_dir: /usr/local/bin
# Are control hosts also worker nodes?
k3s_control_workers: true
# Ensure Docker is installed on nodes
k3s_ensure_docker_installed: false

18
handlers/main.yml Normal file
View File

@ -0,0 +1,18 @@
---
- name: reload systemctl
command: systemctl daemon-reload
args:
warn: false
- name: restart k3s
service:
name: k3s
state: restarted
enabled: true
- name: restart docker
service:
name: docker
state: restarted
enabled: true

61
meta/main.yml Normal file
View File

@ -0,0 +1,61 @@
galaxy_info:
author: Xan Manning
description: Ansible role for installing k3s as either a standalone server or cluster
company: Pyrat Ltd.
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Some suggested licenses:
# - BSD (default)
# - MIT
# - GPLv2
# - GPLv3
# - Apache
# - CC-BY
license: BSD
min_ansible_version: 2.6
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
# Optionally specify the branch Galaxy will use when accessing the GitHub
# repo for this role. During role install, if no tags are available,
# Galaxy will use this branch. During import Galaxy will access files on
# this branch. If Travis integration is configured, only notifications for this
# branch will be accepted. Otherwise, in all cases, the repo's default branch
# (usually master) will be used.
#github_branch:
#
# platforms is a list of platforms, and each platform has a name and a list of versions.
#
platforms:
- name: CentOS
versions:
- 7
- name: Debian
versions:
- 9
- name: Ubuntu
versions:
- 18.03
galaxy_tags:
- k3s
- kubernetes
- docker
- containerd
- cluster
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -0,0 +1,46 @@
---
- name: Ensure ansible_host is mapped to inventory_hostname
lineinfile:
path: /tmp/inventory.txt
line: "{{ item }}@@@{{ hostvars[item].ansible_host }}@@@{{ hostvars[item].k3s_control_node }}"
create: true
loop: "{{ play_hosts }}"
- name: Lookup control node from file
command: "grep 'True' /tmp/inventory.txt"
changed_when: false
register: k3s_control_delegate_raw
- name: Ensure control node is delegated to for obtaining a token
set_fact:
k3s_control_delegate: "{{ k3s_control_delegate_raw.stdout.split('@@@')[0] }}"
- name: Ensure the control node address is registered in Ansible
set_fact:
k3s_control_node_address: "{{ hostvars[k3s_control_delegate].ansible_host }}"
- name: Ensure NODE_TOKEN is captured from control node
slurp:
path: "/var/lib/rancher/k3s/server/node-token"
register: k3s_control_token
delegate_to: "{{ k3s_control_delegate }}"
- name: Ensure k3s service unit file is present
template:
src: k3s.service.j2
dest: /etc/systemd/system/k3s.service
notify:
- reload systemctl
- restart k3s
- meta: flush_handlers
- name: Wait for all nodes to be ready
command: "{{ k3s_install_dir }}/kubectl get nodes"
changed_when: false
register: kubectl_get_nodes_result
until: kubectl_get_nodes_result.stdout.find("NotReady") == -1
retries: 30
delay: 20
when: k3s_control_node

29
tasks/download-k3s.yml Normal file
View File

@ -0,0 +1,29 @@
---
- name: Ensure target host architecture information is set as a fact
set_fact:
k3s_arch: "{{ k3s_arch_lookup[ansible_architecture].arch }}"
k3s_arch_suffix: "{{ k3s_arch_lookup[ansible_architecture].suffix }}"
- name: Ensure URLs are set as facts for downloading binaries
set_fact:
k3s_binary_url: "{{ k3s_github_download_url }}/{{ k3s_release_version }}/k3s{{ k3s_arch_suffix }}"
k3s_hash_url: "{{ k3s_github_download_url }}/{{ k3s_release_version }}/sha256sum-{{ k3s_arch }}.txt"
- name: Ensure the k3s hashsum is downloaded
uri:
url: "{{ k3s_hash_url }}"
return_content: true
register: k3s_hash_sum_raw
- name: Ensure sha256sum is set from hashsum variable
shell: "echo \"{{ k3s_hash_sum_raw.content }}\" | grep 'k3s' | awk '{ print $1 }'"
changed_when: false
register: k3s_hash_sum
- name: Ensure k3s binary is downloaded
get_url:
url: "{{ k3s_binary_url }}"
dest: "{{ k3s_install_dir }}/k3s-{{ k3s_release_version }}"
checksum: "sha256:{{ k3s_hash_sum.stdout }}"
mode: 0755

10
tasks/get-version.yml Normal file
View File

@ -0,0 +1,10 @@
---
- name: Get the latest release version from GitHub
uri:
url: https://github.com/rancher/k3s/releases/latest
register: k3s_latest_release
- name: Ensure the release version is set as a fact
set_fact:
k3s_release_version: "{{ k3s_latest_release.url.split('/')[-1] }}"

View File

@ -0,0 +1,27 @@
---
- name: Ensure Docker prerequisites are installed
apt:
name: "{{ item }}"
state: present
register: ensure_docker_prerequisites_installed
until: ensure_docker_prerequisites_installed is succeeded
retries: 3
delay: 10
loop:
- apt-transport-https
- ca-certificates
- curl
- "{{ 'gnupg2' if ansible_distribution == 'Debian' else 'gnupg-agent' }}"
- software-properties-common
- name: Ensure Docker APT key is present
apt_key:
url: https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg
state: present
- name: Ensure Docker repository is installed and configured
apt_repository:
filename: docker-ce
repo: "deb https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
update_cache: true

View File

@ -0,0 +1,23 @@
---
- name: Ensure Docker prerequisites are installed
yum:
name:
- yum-utils
- device-mapper-persistent-data
- lvm2
state: present
register: ensure_docker_prerequisites_installed
until: ensure_docker_prerequisites_installed is succeeded
retries: 3
delay: 10
- name: Ensure Docker repository is installed and configured
yum_repository:
name: docker-ce
description: Docker CE Repository
baseurl: https://download.docker.com/linux/{{ ansible_distribution | lower }}/{{ ansible_distribution_major_version }}/$basearch/stable
gpgkey: https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg
enabled: true
gpgcheck: true
state: present

17
tasks/install-docker.yml Normal file
View File

@ -0,0 +1,17 @@
---
- name: Ensure docker is installed
package:
name:
- docker-ce
- docker-ce-cli
- containerd.io
state: present
register: ensure_docker_installed
until: ensure_docker_installed is succeeded
retries: 3
delay: 10
notify:
- restart docker
- meta: flush_handlers

28
tasks/install-k3s.yml Normal file
View File

@ -0,0 +1,28 @@
---
- name: Ensure k3s is symlinked into the installation destinations
file:
src: "{{ k3s_install_dir }}/k3s-{{ k3s_release_version }}"
dest: "{{ k3s_install_dir }}/{{ item }}"
state: link
loop:
- k3s
- kubectl
- crictl
- name: Ensure k3s service unit file is present on control plane
template:
src: k3s.service.j2
dest: /etc/systemd/system/k3s.service
when: k3s_control_node
notify:
- reload systemctl
- meta: flush_handlers
- name: Ensure k3s control plane is started
service:
name: k3s
state: started
enabled: true
when: k3s_control_node

17
tasks/main.yml Normal file
View File

@ -0,0 +1,17 @@
---
- include_tasks: preconfigure-k3s.yml
- include_tasks: install-docker-prerequisites-{{ ansible_os_family|lower }}.yml
when: k3s_ensure_docker_installed
and ((k3s_control_workers and k3_control_node)
or (not k3s_control_workers and not k3s_control_node))
- include_tasks: install-docker.yml
when: k3s_ensure_docker_installed
and ((k3s_control_workers and k3_control_node)
or (not k3s_control_workers and not k3s_control_node))
- include_tasks: get-version.yml
when: k3s_release_version is not defined or not k3s_release_version
- include_tasks: download-k3s.yml
- include_tasks: install-k3s.yml
- include_tasks: configure-k3s-cluster.yml
when: play_hosts | length > 1

View File

@ -0,0 +1,25 @@
---
- name: Ensure k3s control node fact is set
set_fact:
k3s_control_node: false
when: k3s_control_node is not defined
- name: Ensure a k3s control node is defined if none are found in play_hosts
block:
- name: Set control host
set_fact:
k3s_control_node: true
when: inventory_hostname == play_hosts[0]
when: true not in (hostvars | json_query('*.k3s_control_node'))
- name: Ensure a count of control masters is generated
set_fact:
k3s_controller_count: "{{ k3s_controller_count + [ item ] }}"
when: item
loop: "{{ hostvars | json_query('*.k3s_control_node') }}"
- name: Fail playbook if there are multiple controllers defined
fail:
msg: "Multiple controllers have been defined. This is not yet supported."
when: k3s_controller_count | length > 1

23
templates/k3s.service.j2 Normal file
View File

@ -0,0 +1,23 @@
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
After=network.target
[Service]
Type=notify
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
{% if k3s_control_node %}
ExecStart={{ k3s_install_dir }}/k3s server{{ ' --disable-agent' if not k3s_control_workers else '' }}{{ ' --docker' if k3s_ensure_docker_installed else '' }}
{% else %}
ExecStart={{ k3s_install_dir }}/k3s agent{{ ' --docker' if k3s_ensure_docker_installed else '' }} --server https://{{ k3s_control_node_address }}:6443 --token {{ k3s_control_token.content | b64decode }}
{% endif %}
KillMode=process
Delegate=yes
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
[Install]
WantedBy=multi-user.target

71
tests/Vagrantfile vendored Normal file
View File

@ -0,0 +1,71 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
$centos_provision = <<SCRIPT
if [ ! -f .vagrant_provision ] ; then
echo "Installing dependencies ..."
sudo yum clean all > /dev/null 2>&1 && echo "[OK] Cleanup YUM."
sudo yum makecache > /dev/null 2>&1 && echo "[OK] Create YUM cache."
sudo yum install python libselinux-python -y -q > /dev/null 2>&1 && \
echo "[OK] Installing Python."
touch .vagrant_provision
else
echo "Already Provisioned."
fi
SCRIPT
$debian_provision = <<SCRIPT
if [ ! -f .vagrant_provision ] ; then
echo "Installing dependencies ..."
sudo apt update > /dev/null 2>&1 && echo "[OK] Update APT cache."
sudo apt-get install python -y > /dev/null 2>&1 && \
echo "[OK] Installing Python."
touch .vagrant_provision
else
echo "Already Provisioned."
fi
SCRIPT
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "node1" do |node1|
node1.vm.box = "centos/7"
node1.vm.hostname = "k3s-node01"
node1.vm.network "private_network", ip: "172.16.3.30"
node1.vm.provider "virtualbox" do |vb|
vb.name = "k3s - node1"
vb.memory = 512
end
node1.vm.provision "shell", inline: $centos_provision
end
config.vm.define "node2" do |node2|
node2.vm.box = "debian/stretch64"
node2.vm.hostname = "k3s-node02"
node2.vm.network "private_network", ip: "172.16.3.31"
node2.vm.provider "virtualbox" do |vb|
vb.name = "k3s - node2"
vb.memory = 512
end
node2.vm.provision "shell", inline: $debian_provision
end
config.vm.define "node3" do |node3|
node3.vm.box = "ubuntu/bionic64"
node3.vm.hostname = "k3s-node03"
node3.vm.network "private_network", ip: "172.16.3.32"
node3.vm.provider "virtualbox" do |vb|
vb.name = "k3s - node3"
vb.memory = 512
end
node3.vm.provision "shell", inline: $debian_provision
node3.vm.provision "ansible" do |a|
a.limit = "all"
a.config_file = "ansible.cfg"
a.inventory_path = "inventory.yml"
a.playbook = "test.yml"
a.verbose = "v"
end
end
end

4
tests/ansible.cfg Normal file
View File

@ -0,0 +1,4 @@
[defaults]
host_key_checking = false
roles_path = ../../

22
tests/inventory.yml Normal file
View File

@ -0,0 +1,22 @@
all:
vars:
ansible_become: true
k3s_ensure_docker_installed: false
k3s_nodes:
hosts:
node1:
ansible_host: 172.16.3.30
ansible_user: vagrant
ansible_port: 22
ansible_ssh_private_key_file: '.vagrant/machines/node1/virtualbox/private_key'
node2:
ansible_host: 172.16.3.31
ansible_user: vagrant
ansible_port: 22
ansible_ssh_private_key_file: '.vagrant/machines/node2/virtualbox/private_key'
node3:
ansible_host: 172.16.3.32
ansible_user: vagrant
ansible_port: 22
ansible_ssh_private_key_file: '.vagrant/machines/node3/virtualbox/private_key'

5
tests/test.yml Normal file
View File

@ -0,0 +1,5 @@
---
- hosts: k3s_nodes
become: true
roles:
- ansible-role-k3s

27
vars/main.yml Normal file
View File

@ -0,0 +1,27 @@
---
k3s_arch_lookup:
amd64:
arch: amd64
suffix: ""
x86_64:
arch: amd64
suffix: ""
arm64:
arch: arm64
suffix: "-arm64"
aarch64:
arch: arm64
suffix: "-arm64"
arm:
arch: arm
suffix: "-armhf"
arm7:
arch: arm
suffix: "-armhf"
armhf:
arch: arm
suffix: "-armhf"
k3s_github_download_url: "{{ k3s_github_url }}/releases/download"
k3s_controller_count: []