This commit is contained in:
Oriol 2023-03-12 05:42:53 +00:00
commit 4d2fb39e47
11 changed files with 619 additions and 0 deletions

107
README.md Normal file
View File

@ -0,0 +1,107 @@
# Intended for OrangePI5 **(might work on other devices)**
- Tested on [ARMBIAN](https://www.armbian.com/orangepi-5/) Bullseye
- Previously on the [orangepi](http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-pi-5.html) official Debian versions, but can't **confirm still works**
# Files
```yaml
arm_initial_setup.yaml: standalone playbook to normalize the initialization of an ARMBIAN device
run.sh: placeholder script used for testing
ksetup/:
```
## arm_initial_setup.yaml
It will:
- Set the loacale for ROOT user
- Set the language for ROOT user
- Create `wheel` group
- Add `wheel` group to sudoers (using password)
- Add a new user with its password
- Add the new user to the `wheel` group
- Change ROOT password
- Disable SSH to the ROOT user
- Executes `sleep 1 && dhclient -r && dhclient && reboot`. The `dhclient -r` it's for my own usage so **modify it if it bothers you**.
## ksetup
### playbook.yaml
Used to "orchestrate" the process and call the rest of the **task** playbooks.
### TASK playbooks
- list (TODO)
# USAGE
## Setup
On my infrastructure, **I** use a DHCP and DNS to connect / communicate the nodes.
You **might** need to edit the file `/etc/hosts` and <u>manually</u> point the resources IP addresses.
So my first step is to reserve the MAC addresses and configure the DHCP server.
Afterwards update the DNS server to point to those IPs.
## Set the SD card / SBC (Single Board Computer)
Beware of using the right IMG / device, as you don't want to <u>delete the wrong drive</u>, **right?**
```shell
dd if=Armbian_23.02.2_Orangepi5_bullseye_legacy_5.10.110_minimal.img of=/dev/sdg status=progress bs=1M status=progress
```
## arm_initial_setup.yaml
### Change the values of the desired variables
```yaml
# New values
## Users
new_user_name: "orangepi"
new_user_pass: "orangepi"
new_root_pass: "1234"
## Locales
new_locale: "en_US.UTF-8"
new_language: "en_US.UTF-8"
```
### Change the connection variables (Optional)
**Optional**, if you are not planning to use root, the playbook might require some slight changes in order to work with an user that's not root, idk, not my problem, this playbook <u>**assumes**</u> you will be using an ARMBIAN image.
```yaml
ansible_user: "root"
ansible_password: "1234"
```
# License
## DWTFUW
Do whatever the fuck you want license ™

122
armbian_initial_setup.yaml Normal file
View File

@ -0,0 +1,122 @@
# Author: Oriol Filter
# 12/03/2023
# Intended for armbian (bullseye, fuck ubuntu tho)
- name: Pre Setup
hosts: all
gather_facts: false
vars:
# Connect
ansible_user: "root"
ansible_password: "1234"
ansible_become_password: "{{ ansible_password }}"
# ansible_user: "orangepi"
# ansible_password: "orangepi"
# ansible_become_password: "orangepi" # Temporal
# New values
## Users
new_user_name: "orangepi"
new_user_pass: "orangepi"
new_root_pass: "1234"
## Locales
new_locale: "en_US.UTF-8"
new_language: "en_US.UTF-8"
# SSH with ROOT
tasks:
# Set locale
# https://serverfault.com/a/981742
- name: Ensure localisation files for '{{ new_locale }}' are available
locale_gen:
name: "{{ new_locale }}"
state: present
- name: Ensure localisation files for '{{ new_language }}' are available
locale_gen:
name: "{{ new_language }}"
state: present
- name: Get current locale and language configuration
command: localectl status
register: locale_status
changed_when: false
- name: Parse 'LANG' from current locale and language configuration
set_fact:
locale_lang: "{{ locale_status.stdout | regex_search('LANG=([^\n]+)', '\\1') | first }}"
- name: Parse 'LANGUAGE' from current locale and language configuration
set_fact:
locale_language: "{{ locale_status.stdout | regex_search('LANGUAGE=([^\n]+)', '\\1') | default([locale_lang], true) | first }}"
- name: Configure locale to '{{ new_locale }}' and language to '{{ new_language }}'
command: localectl set-locale LANG={{ new_locale }} LANGUAGE={{ new_language }}
changed_when: locale_lang != new_locale or locale_language != new_language
become: yes # no idea if it's needed nor I care about
# Wheel group with sudo access
# https://stackoverflow.com/a/33362805
- name: Make sure we have a 'wheel' group
group:
name: wheel
state: present
become: true
- name: Allow 'wheel' group to have passwordless sudo
ansible.builtin.lineinfile:
dest: /etc/sudoers
state: present
regexp: '^%wheel'
line: '%wheel ALL=(ALL) PASSWD: ALL'
validate: visudo -cf %s
become: true
# Create orangepi user (will bother about it later) move to -> kuser (kluster user)
- name: Add user new_user_name
ansible.builtin.user:
name: "{{ new_user_name }}"
password: "{{ new_user_pass | password_hash }}"
shell: /bin/bash
become: true
- name: adding user '{{ new_user_name }}' to group wheel
user:
name: '{{ new_user_name }}'
groups: sudo
append: yes
become: true
# Set root password to whatever shit
- name: Change root default password
ansible.builtin.user:
name: root
password: "{{ new_root_pass | password_hash }}"
become: yes
# Disable SSH with ROOT
- name: PermitRootLogin = no
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: PermitRootLogin = no
backrefs: yes
become: yes
# REBOOT
- name: reboot
ansible.builtin.shell: 'sleep 1 && dhclient -r && dhclient && reboot'
# ignore_errors: true # expected to fail due the imminent restart
ignore_unreachable: true
become: yes

8
inventory.yaml Normal file
View File

@ -0,0 +1,8 @@
master:
hosts:
masterk.filter.home:
is_master: yes
slaves:
hosts:
slave[01:01].filter.home:
is_master: no

5
ksetup/end_tasks.yaml Executable file
View File

@ -0,0 +1,5 @@
#reboot
- name: reboot
reboot:

View File

@ -0,0 +1 @@
kubeadm join 192.168.1.10:6443 --token ezekcz.n6hwck49wfvj4h6f --discovery-token-ca-cert-hash sha256:7f78629fddc1310a35d2534d5dafa77761fa9770ff4da871583e32bc549470f7

85
ksetup/master_tasks.yaml Executable file
View File

@ -0,0 +1,85 @@
# Init
- name: Init cluster
ansible.builtin.command: "kubeadm init"
become: true
# Set kubectl tool
- user:
name: "{{ ansible_user_id }}"
state: present
register: user_info_registered
- name: create .kube directory
become: yes
become_user: "{{ ansible_user_id }}"
file:
path: "{{ user_info_registered.home }}/.kube"
state: directory
mode: 0755
- debug: var=user_info_registered.home
- name: copy admin.conf to user's kube config
copy:
src: /etc/kubernetes/admin.conf
remote_src: yes
dest: "{{ user_info_registered.home }}/.kube/config"
owner: "{{ ansible_user_id }}"
become: true
# Network Plugin
# Download and install Flannel
#- name: Download and install Flannel
# ansible.builtin.get_url:
# url: https://github.com/flannel-io/flannel/releases/download/v0.19.2/flanneld-arm64
# dest: /usr/local/bin/flanneld
# owner: root
# group: root
# mode: '0755'
#
#- name: Create Flannel networks directory
# ansible.builtin.file:
# path: /var/lib/k8s/flannel/networks
# state: directory
# recurse: yes
# owner: root
# group: root
# mode: '0755'
#-
#
- name: Calico
ansible.builtin.command: "kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml"
#- name: Calico Tigera ?
# ansible.builtin.shell: "kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/tigera-operator.yaml"
# become_user: some_user
#- name: Calico Custom resources ?
# ansible.builtin.command: "kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml"
#
#
## Remove taints
- name: Remove Taint (allows deployment in control plane)
ansible.builtin.shell: "kubectl taint nodes --all node-role.kubernetes.io/control-plane-"
# Join token / command
- name: Generate join token
shell: kubeadm token create --print-join-command
register: kubeadm_join_cmd
- set_fact:
kubeadm_join_command: "{{ kubeadm_join_cmd.stdout }}"
- debug: var=kubeadm_join_command
- name: Store join command in "{{ kubeadm_join_path }}"
copy:
dest: "{{ kubeadm_join_path }}"
content: |
{{ kubeadm_join_command }}
delegate_to: localhost

47
ksetup/playbook.yaml Executable file
View File

@ -0,0 +1,47 @@
# Author: Oriol Filter
# 11/03/2023
# Intended for armbian (bullseye, fuck ubuntu tho) it's aarch64
# Maybe still works for orangepi "official" versions, but I don't care about them unless I used soooooo... gl!
# https://medium.com/karlmax-berlin/how-to-install-kubernetes-on-raspberry-pi-53b4ce300b58
- name: Preparethings
hosts: all
gather_facts: true
vars:
# Testing purpouses
ansible_user: "orangepi" # Testing purposes
ansible_password: "orangepi" # Testing purposes
ansible_become_password: "orangepi" # Testing purposes
# Actual vars
set_hostname: "{{ ansible_host }}"
# is_master: Figurative
# Cluster shit
kubeadm_join_path: "./kubeadm-join.command"
kubeadm_join_command: ""
tasks:
# - check vars
- debug: var=set_hostname
- debug: var=is_master
# Init / Basic setup
- name: set up node
import_tasks: set_node_tasks.yaml
become: true
# If is_master: init
- name: init cluster
import_tasks: master_tasks.yaml
when: is_master
# else: join
- name: join cluster
import_tasks: slave_tasks.yaml
when: not is_master
# Do other stuff
- name: post setup
import_tasks: end_tasks.yaml

201
ksetup/set_node_tasks.yaml Executable file
View File

@ -0,0 +1,201 @@
# Hostname
## Set hostname
- name: Set a hostname
ansible.builtin.hostname:
name: "{{ set_hostname }}"
# Swap
- name: Swapoff
ansible.builtin.command: swapoff -a
- name: Disable ram on boot (orangepi) # Untested
copy:
dest: "/etc/default/orangepi-zram-config"
content: ENABLED=false
when:
- ansible_distribution | lower == "orangepi"
- ansible_architecture == "aarch64"
- name: Disable ram on boot (armbian) # Untested
copy:
dest: "/etc/default/armbian-zram-config"
content: ENABLED=false
when:
- ansible_architecture == "aarch64"
- ansible_distribution | lower == "ubuntu" or ansible_distribution | lower == "debian"
# INTENDED FOR ARM DISTROS FUCK U
#- name: Sed when x86_64
# ansible.builtin.command: sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# when: ansible_architecture == "x86_64"
# Packages
# Delete default containerd
## Looking forward the version 1.6
- name: apt prune containerd
ansible.builtin.apt:
name: containerd
state: absent
purge: true
## BnB
- name: apt update
ansible.builtin.apt:
update_cache: yes
- name: apt upgrade
ansible.builtin.apt:
name: "*"
state: latest
## Keyrings directory
- name: Creating a new directory
file:
path: "/etc/apt/keyrings"
state: directory
recurse: true
mode: '0755'
# ignore_errors: true
## Docker repo
- name: Add Docker GPG key
apt_key:
url: https://download.docker.com/linux/debian/gpg
state: present
- name: Add Docker APT repository
apt_repository:
repo: deb [arch=arm64] https://download.docker.com/linux/debian bullseye stable
state: present
## Kubeshit repo
- name: Download Kubernetes GPG key
ansible.builtin.get_url:
url: "https://packages.cloud.google.com/apt/doc/apt-key.gpg"
dest: "/etc/apt/keyrings/kubernetes-archive-keyring.gpg"
timeout: 10
- name: Add Kubernetes keyring
copy:
dest: "/etc/apt/sources.list.d/kubernetes.list"
content: "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main"
## Install packages
- name: apt update
ansible.builtin.apt:
update_cache: yes
- name: Install Kubelet Kubeadm Kubectl
ansible.builtin.apt:
pkg:
- kubelet
- kubeadm
- kubectl
- name: Hold kubeadm
ansible.builtin.dpkg_selections:
name: kubeadm
selection: hold
- name: Hold kubelet
ansible.builtin.dpkg_selections:
name: kubelet
selection: hold
- name: Hold kubectl
ansible.builtin.dpkg_selections:
name: kubectl
selection: hold
## Containerd
- name: Install Container Runtime
ansible.builtin.apt:
pkg:
- containerd.io
- containernetworking-plugins
- name: Containerd set default config
ansible.builtin.shell: containerd config default | tee /etc/containerd/config.toml
become: yes
- name: SystemdCgroup = true
lineinfile:
dest: /etc/containerd/config.toml
regexp: '^\s*SystemdCgroup = false$'
line: ' SystemdCgroup = true'
backrefs: yes
# Iptables
## Set files
- name: Iptables thingies (not touching specific firewall rules.)
copy:
dest: "/etc/sysctl.d/k8s.conf"
content: |
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
- name: Iptables thingies
copy:
dest: "/etc/modules-load.d/k8s.conf"
content: |
overlay
br_netfilter
## Modprobe
- name: Add the overlay module
community.general.modprobe:
name: overlay
state: present
- name: Add the br_netfilter module
community.general.modprobe:
name: br_netfilter
state: present
- name: Apply changes (might need to use sysctl module with the reload flag, will try eventually)
ansible.builtin.command: "sysctl --system"
## Systemctl
### Enable
- name: Enable kubelet
ansible.builtin.systemd:
name: kubelet
enabled: true
- name: Enable containerd
ansible.builtin.systemd:
name: containerd
enabled: true
### Restart
- name: Enable kubelet
ansible.builtin.systemd:
name: kubelet
state: restarted
- name: Restart containerd
ansible.builtin.systemd:
name: containerd
state: restarted
## Set /etc/hosts
### This could be better but who cares
- name: Set /etc/hosts file content (template/base)
copy:
dest: "/etc/hosts"
content: |
127.0.0.1 localhost
127.0.1.1 {{ set_hostname }}
::1 localhost {{ set_hostname }} ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

8
ksetup/slave_tasks.yaml Executable file
View File

@ -0,0 +1,8 @@
- name: Populate {{ kubeadm_join_command }}
ansible.builtin.set_fact: kubeadm_join_command="{{ lookup('file', kubeadm_join_path ) }}"
- debug: var=kubeadm_join_command
- name: Join kubeadm
ansible.builtin.command: "{{ kubeadm_join_command }}"
become: yes

21
main_issues.md Normal file
View File

@ -0,0 +1,21 @@
# Main issues I ran into
## kubeadm init
### Something something API V1
Probably ~~(surely)~~ the `containerd` version you are using is 1.4 something, that's due being the default version installed / from the default repositories.
To fix it, install `containerd.io`.
If currently can't find `containerd.io`, follow the [Set up the repository](https://docs.docker.com/engine/install/debian/#install-using-the-repository) to set up the repositories and finally run `apt-get install containerd.io`
You can check the version by running `containerd --version`
## CNI plugin initializing
Wait, if after a while still this way, confirm that you actually deployed the network plugin.
```shell
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml
```

14
run.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
export ANSIBLE_HOST_KEY_CHECKING=False
# Replace for an inventory
IP="192.168.1.50,192.168.1.51,"
ansible-playbook -i $IP, armbian_initial_setup.yaml && sleep 25 # Wait for reboot
ansible-playbook -i inventory.yaml ksetup/playbook.yaml