Skip to content

Commit f8c2bc1

Browse files
committed
add ansible k3s automation
1 parent 4ecdf41 commit f8c2bc1

File tree

26 files changed

+1148
-0
lines changed

26 files changed

+1148
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Build a Kubernetes cluster using K3s via Ansible
2+
3+
Easily bring up a cluster on machines running:
4+
5+
- [X] Ubuntu
6+
7+
on processor architectures:
8+
9+
- [X] x64
10+
- [X] arm64
11+
- [X] armhf
12+
13+
## System requirements
14+
15+
The control node **must** have Ansible 8.0+ (ansible-core 2.15+)
16+
17+
All managed nodes in inventory must have:
18+
- Passwordless SSH access
19+
- Root access (or a user with equivalent permissions)
20+
21+
It is also recommended that all managed nodes disable firewalls and swap. See [K3s Requirements](https://docs.k3s.io/installation/requirements) for more information.
22+
23+
## Usage
24+
25+
Second edit the inventory file to match your cluster setup. For example:
26+
```bash
27+
k3s_cluster:
28+
children:
29+
server:
30+
hosts:
31+
192.16.35.11:
32+
agent:
33+
hosts:
34+
192.16.35.12:
35+
192.16.35.13:
36+
```
37+
38+
If multiple hosts are in the server group the playbook will automatically setup k3s in HA mode with embedded etcd.
39+
An odd number of server nodes is required (3,5,7). Read the [official documentation](https://docs.k3s.io/datastore/ha-embedded) for more information.
40+
41+
Start provisioning of the cluster using the following command:
42+
43+
```bash
44+
ansible-playbook deploy.yml -i inventory.yml
45+
```
46+
47+
## Kubeconfig
48+
49+
After successful bringup, the kubeconfig of the cluster is copied to the control node and merged with `~/.kube/config` under the `k3s-ansible` context.
50+
Assuming you have [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) installed, you can confirm access to your **Kubernetes** cluster with the following:
51+
52+
```bash
53+
kubectl config use-context k3s-ansible
54+
kubectl get nodes
55+
```
56+
57+
If you wish for your kubeconfig to be copied elsewhere and not merged, you can set the `kubeconfig` variable in `inventory.yml` to the desired path.
58+
59+
60+
## Need More Features?
61+
62+
This project is intended to provide a "vanilla" K3s install. If you need more features, such as:
63+
- Private Registry
64+
- Advanced Storage (Longhorn, Ceph, etc)
65+
- External Database
66+
- External Load Balancer or VIP
67+
- Alternative CNIs
68+
69+
See these other projects:
70+
- https://github.com/PyratLabs/ansible-role-k3s
71+
- https://github.com/techno-tim/k3s-ansible
72+
- https://github.com/jon-stumpf/k3s-ansible
73+
- https://github.com/alexellis/k3sup
74+
- https://github.com/axivo/k3s-cluster
75+
- https://github.com/k3s-io/k3s-ansible
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[defaults]
2+
nocows = True
3+
roles_path = ./roles
4+
inventory = ./inventory.yml
5+
6+
remote_tmp = $HOME/.ansible/tmp
7+
local_tmp = $HOME/.ansible/tmp
8+
pipelining = True
9+
become = True
10+
host_key_checking = False
11+
deprecation_warnings = False
12+
callback_whitelist = profile_tasks
13+
private_key_file = ~/.ssh/fmsavoia_oci_ssh_key
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
collections:
3+
- name: community.general
4+
- name: ansible.posix
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
- name: Cluster prep
3+
hosts: k3s_cluster
4+
gather_facts: true
5+
become: true
6+
roles:
7+
- role: prereq
8+
9+
- name: Setup K3S server
10+
hosts: server
11+
become: true
12+
roles:
13+
- role: k3s_server
14+
15+
- name: Setup K3S agent
16+
hosts: agent
17+
become: true
18+
roles:
19+
- role: k3s_agent
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
k3s_cluster:
3+
children:
4+
server:
5+
hosts:
6+
152.70.57.197:
7+
agent:
8+
hosts:
9+
141.144.202.55:
10+
193.123.63.252:
11+
vars:
12+
ansible_port: 22
13+
ansible_user: ubuntu
14+
k3s_version: v1.30.2+k3s1
15+
# The token should be a random string of reasonable length. You can generate
16+
# one with the following commands:
17+
# - openssl rand -base64 64
18+
# - pwgen -s 64 1
19+
# You can use ansible-vault to encrypt this value / keep it secret.
20+
# Or you can omit it if not using Vagrant and let the first server automatically generate one.
21+
# token: "changeme!"
22+
api_endpoint: "{{ hostvars[groups['server'][0]]['ansible_host'] | default(groups['server'][0]) }}"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
requires_ansible: ">=2.15.0"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
server_group: server # noqa var-naming[no-role-prefix]
3+
k3s_server_location: "/var/lib/rancher/k3s" # noqa var-naming[no-role-prefix]
4+
systemd_dir: "/etc/systemd/system" # noqa var-naming[no-role-prefix]
5+
api_port: 6443 # noqa var-naming[no-role-prefix]
6+
extra_agent_args: "" # noqa var-naming[no-role-prefix]
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
- name: Get k3s installed version
3+
ansible.builtin.command: k3s --version
4+
register: k3s_version_output
5+
changed_when: false
6+
ignore_errors: true
7+
8+
- name: Set k3s installed version
9+
when: not ansible_check_mode and k3s_version_output.rc == 0
10+
ansible.builtin.set_fact:
11+
installed_k3s_version: "{{ k3s_version_output.stdout_lines[0].split(' ')[2] }}"
12+
13+
# If airgapped, all K3s artifacts are already on the node.
14+
# We should be downloading and installing the newer version only if we are in one of the following cases :
15+
# - we couldn't get k3s installed version in the first task of this role
16+
# - the installed version of K3s on the nodes is older than the requested version in ansible vars
17+
- name: Download artifact only if needed
18+
when: not ansible_check_mode and airgap_dir is undefined and ( k3s_version_output.rc != 0 or installed_k3s_version is version(k3s_version, '<') )
19+
block:
20+
- name: Download K3s install script
21+
ansible.builtin.get_url:
22+
url: https://get.k3s.io/
23+
timeout: 120
24+
dest: /usr/local/bin/k3s-install.sh
25+
owner: root
26+
group: root
27+
mode: "0755"
28+
29+
- name: Download K3s binary
30+
ansible.builtin.command:
31+
cmd: /usr/local/bin/k3s-install.sh
32+
environment:
33+
INSTALL_K3S_SKIP_START: "true"
34+
INSTALL_K3S_VERSION: "{{ k3s_version }}"
35+
INSTALL_K3S_EXEC: "agent"
36+
changed_when: true
37+
38+
- name: Setup optional config file
39+
when: agent_config_yaml is defined
40+
block:
41+
- name: Make config directory
42+
ansible.builtin.file:
43+
path: "/etc/rancher/k3s"
44+
mode: "0755"
45+
state: directory
46+
- name: Copy config values
47+
ansible.builtin.copy:
48+
content: "{{ agent_config_yaml }}"
49+
dest: "/etc/rancher/k3s/config.yaml"
50+
mode: "0644"
51+
register: _agent_config_result
52+
53+
- name: Get the token from the first server
54+
ansible.builtin.set_fact:
55+
token: "{{ hostvars[groups[server_group][0]].token }}"
56+
57+
- name: Delete any existing token from the environment if different from the new one
58+
ansible.builtin.lineinfile:
59+
state: absent
60+
path: "{{ systemd_dir }}/k3s-agent.service.env"
61+
regexp: "^K3S_TOKEN=\\s*(?!{{ token }}\\s*$)"
62+
63+
- name: Add the token for joining the cluster to the environment
64+
no_log: true # avoid logging the server token
65+
ansible.builtin.lineinfile:
66+
path: "{{ systemd_dir }}/k3s-agent.service.env"
67+
line: "{{ item }}"
68+
with_items:
69+
- "K3S_TOKEN={{ token }}"
70+
71+
- name: Copy K3s service file
72+
register: k3s_agent_service
73+
ansible.builtin.template:
74+
src: "k3s-agent.service.j2"
75+
dest: "{{ systemd_dir }}/k3s-agent.service"
76+
owner: root
77+
group: root
78+
mode: "u=rw,g=r,o=r"
79+
80+
- name: Enable and check K3s service
81+
ansible.builtin.systemd:
82+
name: k3s-agent
83+
daemon_reload: "{{ true if k3s_agent_service.changed else false }}"
84+
state: "{{ 'restarted' if (k3s_agent_service.changed or _agent_config_result.changed) else 'started' }}"
85+
enabled: true
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[Unit]
2+
Description=Lightweight Kubernetes
3+
Documentation=https://k3s.io
4+
Wants=network-online.target
5+
After=network-online.target
6+
7+
[Install]
8+
WantedBy=multi-user.target
9+
10+
[Service]
11+
Type=notify
12+
EnvironmentFile=-/etc/default/%N
13+
EnvironmentFile=-/etc/sysconfig/%N
14+
EnvironmentFile=-/etc/systemd/system/k3s-agent.service.env
15+
KillMode=process
16+
Delegate=yes
17+
# Having non-zero Limit*s causes performance problems due to accounting overhead
18+
# in the kernel. We recommend using cgroups to do container-local accounting.
19+
LimitNOFILE=1048576
20+
LimitNPROC=infinity
21+
LimitCORE=infinity
22+
TasksMax=infinity
23+
TimeoutStartSec=0
24+
Restart=always
25+
RestartSec=5s
26+
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
27+
ExecStartPre=-/sbin/modprobe br_netfilter
28+
ExecStartPre=-/sbin/modprobe overlay
29+
ExecStart=/usr/local/bin/k3s agent --data-dir {{ k3s_server_location }} --server https://{{ api_endpoint }}:{{ api_port }} {{ extra_agent_args }}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
k3s_server_location: "/var/lib/rancher/k3s"
3+
systemd_dir: "/etc/systemd/system" # noqa var-naming[no-role-prefix]
4+
api_port: 6443 # noqa var-naming[no-role-prefix]
5+
kubeconfig: ~/.kube/config.new # noqa var-naming[no-role-prefix]
6+
user_kubectl: true # noqa var-naming[no-role-prefix]
7+
cluster_context: k3s-ansible # noqa var-naming[no-role-prefix]
8+
server_group: server # noqa var-naming[no-role-prefix]
9+
agent_group: agent # noqa var-naming[no-role-prefix]
10+
use_external_database: false # noqa var-naming[no-role-prefix]
11+
extra_server_args: "" # noqa var-naming[no-role-prefix]

0 commit comments

Comments
 (0)