diff --git a/README.md b/README.md index df4d239a..ab2ea174 100644 --- a/README.md +++ b/README.md @@ -45,14 +45,50 @@ With that out of the way please continue on if you are still interested... - [Organizing Cluster Access Using kubeconfig Files](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) -### 💻 Systems +### 💻 System Preparation -- One or more nodes with a fresh install of [Ubuntu 22.04 Server](https://ubuntu.com/download/server) (not minimal / not raspi edition). - - These nodes can be ARM64/AMD64 bare metal or VMs. - - An odd number of control plane nodes, greater than or equal to 3 is required if deploying more than one control plane node. -- A [Cloudflare](https://www.cloudflare.com/) account with a domain, this will be managed by external-dns. You can [register new domains](https://www.cloudflare.com/products/registrar/) directly thru Cloudflare. +Download [Debian 12](https://cdimage.debian.org/debian-cd/current/amd64/iso-dvd/) (for raspi/arm64 use the [tested images](https://raspi.debian.net/tested-images/)) -📍 It is recommended to have 3 master nodes for a highly available control plane. + +#### AMD64 + +There is a decent guide [here](https://www.linuxtechi.com/how-to-install-debian-12-step-by-step/) on how to get Debian installed. + +1. Deviations from that guide + + ```txt + - Choose "Guided - use entire disk" + - Choose "All files in one partition" + - Delete Swap partition + - Uncheck all Debian desktop environment options + - Keep ssh server checked + ``` + +2. (Post install) Enable SSH for root user + + ```sh + sed -i 's/#\?\(PermitRootLogin\s*\).*$/\1yes/' /etc/ssh/sshd_config + systemctl restart sshd + ``` + +3. (Post install) Add SSH keys (or use `ssh-copy-id` on the client that is connecting) + + ```sh + mkdir -m 700 ~/.ssh + curl https://github.com/${github_username}.keys > ~/.ssh/authorized_keys + chmod 600 ~/.ssh/authorized_keys + ``` + +4. (Post install) If you cannot run `apt update` without errors, try removing CD/DVD as apt source + + ```sh + sed -i '1d' /etc/apt/sources.list + apt update + ``` + +#### Raspberry Pi / ARM64 + +TBD ## 📂 Repository structure @@ -186,9 +222,9 @@ In order to expose services to the internet you will need to create a [Cloudflar task configure ``` -### ⚡ Preparing Ubuntu Server with Ansible +### ⚡ Preparing Debian Server with Ansible -📍 Here we will be running an Ansible Playbook to prepare Ubuntu server for running a Kubernetes cluster. +📍 Here we will be running an Ansible Playbook to prepare Debian server for running a Kubernetes cluster. 📍 Nodes are not security hardened by default, you can do this with [dev-sec/ansible-collection-hardening](https://github.com/dev-sec/ansible-collection-hardening) or similar if supported. This is an advanced configuration and generally not recommended unless you want to [DevSecOps](https://www.ibm.com/topics/devsecops) your cluster and nodes. diff --git a/ansible/playbooks/cluster-prepare.yaml b/ansible/playbooks/cluster-prepare.yaml index 39e9efce..769ff9d5 100644 --- a/ansible/playbooks/cluster-prepare.yaml +++ b/ansible/playbooks/cluster-prepare.yaml @@ -15,75 +15,81 @@ community.general.timezone: name: "{{ timezone | default('Etc/UTC') }}" - - name: Networking + - name: Packages + block: + - name: Packages | Install + ansible.builtin.apt: + name: apt-transport-https,ca-certificates,conntrack,curl,dirmngr,gdisk,gnupg,htop, + iptables,iputils-ping,ipvsadm,libseccomp2,lm-sensors,neofetch,net-tools,nfs-common, + nvme-cli,open-iscsi,parted,psmisc,python3,python3-apt,python3-kubernetes,python3-yaml, + smartmontools,socat,software-properties-common,unzip,util-linux + install_recommends: false + - name: Packages | Remove + ansible.builtin.apt: + name: apparmor + state: absent + purge: true + autoremove: true + + - name: User Configuration + block: + - name: User Configuration | SSH keys + ansible.posix.authorized_key: + user: "{{ ansible_user }}" + key: "https://github.com/{{ github_username }}.keys" + - name: User Configuration | Silence login + ansible.builtin.file: + dest: /root/.hushlogin + state: touch + owner: "{{ ansible_user }}" + mode: "0644" + modification_time: preserve + access_time: preserve + + - name: Network Configuration notify: Restart systemd-networkd block: - - name: Networking | Set hostname to inventory hostname + - name: Network Configuration | Set hostname ansible.builtin.hostname: name: "{{ inventory_hostname }}" - - name: Networking | Update hosts file to include inventory hostname - ansible.builtin.blockinfile: - path: /etc/hosts - block: | - 127.0.1.1 {{ inventory_hostname }} # https://github.com/cilium/cilium/issues/18706 - - name: Networking | Cilium (1) + - name: Network Configuration | Cilium (1) ansible.builtin.lineinfile: dest: /etc/systemd/networkd.conf regexp: ManageForeignRoutingPolicyRules line: ManageForeignRoutingPolicyRules=no - - name: Networking | Cilium (2) + - name: Network Configuration | Cilium (2) ansible.builtin.lineinfile: dest: /etc/systemd/networkd.conf regexp: ManageForeignRoutes line: ManageForeignRoutes=no - - name: Packages + - name: System Configuration + notify: Reboot block: - - name: Packages | Install required packages - ansible.builtin.apt: - name: hdparm,htop,ipvsadm,lm-sensors,nano,nfs-common,nvme-cli, - socat,python3-kubernetes,python3-yaml - state: present - update_cache: true - - name: Packages | RasPi packages - ansible.builtin.apt: - name: ["linux-modules-extra-raspi"] - install_recommends: false - notify: Reboot - when: "'raspi' in ansible_kernel" - - - name: System Configuration (1) - block: - - name: System Configuration (1) | Disable ufw - ansible.builtin.systemd: - service: ufw.service - enabled: false - masked: true - state: stopped - register: stop_service - failed_when: - - stop_service.failed == true - - '"Could not find the requested service" not in stop_service.msg' - - name: System Configuration (1) | Enable fstrim - ansible.builtin.systemd: - service: fstrim.timer - enabled: true - - - name: System Configuration (2) - block: - - name: System Configuration (2) | Enable kernel modules now + - name: System Configuration | Neofetch + ansible.builtin.copy: + dest: /etc/profile.d/neofetch.sh + mode: "0755" + content: neofetch --config none + - name: System Configuration | Disable swap + ansible.posix.mount: + name: "{{ item }}" + fstype: swap + state: absent + loop: ["none", "swap"] + - name: System Configuration | Kernel modules (1) community.general.modprobe: name: "{{ item }}" state: present loop: ["br_netfilter", "ceph", "ip_vs", "ip_vs_rr", "nbd", "overlay", "rbd"] - - name: System Configuration (2) | Enable kernel modules on boot + - name: System Configuration | Kernel modules (2) ansible.builtin.copy: + dest: "/etc/modules-load.d/{{ item }}.conf" mode: "0644" content: "{{ item }}" - dest: "/etc/modules-load.d/{{ item }}.conf" loop: ["br_netfilter", "ceph", "ip_vs", "ip_vs_rr", "nbd", "overlay", "rbd"] - - name: System Configuration (2) | Set sysctls + - name: System Configuration | Sysctl ansible.posix.sysctl: name: "{{ item.key }}" value: "{{ item.value }}" @@ -95,16 +101,6 @@ fs.inotify.max_queued_events: 65536 fs.inotify.max_user_watches: 524288 fs.inotify.max_user_instances: 8192 - - name: System Configuration (2) | Disable swap at runtime - ansible.builtin.command: swapoff -a - when: ansible_swaptotal_mb > 0 - - name: System Configuration (2) | Disable swap at boot - ansible.posix.mount: - name: "{{ item }}" - fstype: swap - state: absent - loop: ["none", "swap"] - notify: Reboot handlers: - name: Restart systemd-networkd diff --git a/template/templates/ansible/supplemental.yaml.j2 b/template/templates/ansible/supplemental.yaml.j2 index 6c9c8afb..6c2bcdc4 100644 --- a/template/templates/ansible/supplemental.yaml.j2 +++ b/template/templates/ansible/supplemental.yaml.j2 @@ -1,5 +1,6 @@ --- timezone: "{{ bootstrap_timezone }}" +github_username: "{{ bootstrap_github_username }}" coredns_addr: "{{ bootstrap_coredns_addr }}" kube_vip_addr: "{{ bootstrap_kube_vip_addr }}" cluster_cidr: "{{ bootstrap_cluster_cidr }}"