- name: Install Kubernetes on Ubuntu 24 become: "{{ 'no' if inventory_hostname == 'nas.home.lan' else 'yes' }}" vars: helm_version: "v3.15.4" helm_tar: "helm-{{ helm_version }}-linux-amd64.tar.gz" helm_url: "https://get.helm.sh/{{ helm_tar }}" helm_bin: /usr/local/bin/helm kubeconfig: /home/jd/.kube/config nfs_server: "192.168.77.106" nfs_path: "/qda_1" helm_env: PATH: /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin HOME: /home/jd XDG_CONFIG_HOME: /home/jd/.config KUBECONFIG: "{{ kubeconfig }}" block: - name: Enable NTP synchronization ansible.builtin.command: timedatectl set-ntp true changed_when: false - name: Restart systemd-timesyncd ansible.builtin.service: name: systemd-timesyncd state: restarted enabled: true - name: Wait for time synchronization ansible.builtin.command: timedatectl status register: timedatectl_status retries: 10 delay: 6 until: "'System clock synchronized: yes' in timedatectl_status.stdout" changed_when: false - name: Read GitLab password from Vault ansible.builtin.set_fact: gitlab_private_key: >- {{ lookup( 'community.hashi_vault.hashi_vault', 'secret=secret/data/gitlab ' ~ 'field=ssh_private_key ' ~ 'url=http://vault.home.lan:8205 ' ~ 'token=' ~ lookup('env', 'VAULT_TOKEN') ) }} - name: Read GitLab password from Vault ansible.builtin.set_fact: gitlab_public_key: >- {{ lookup( 'community.hashi_vault.hashi_vault', 'secret=secret/data/gitlab ' ~ 'field=ssh_public_key ' ~ 'url=http://vault.home.lan:8205 ' ~ 'token=' ~ lookup('env', 'VAULT_TOKEN') ) }} - name: Store ssh key in file ansible.builtin.copy: content: "{{ gitlab_private_key.ssh_private_key }}\n" dest: /home/{{ ansible_user_id }}/.ssh/id_ed25519_gitlab owner: "{{ ansible_user_id }}" group: "{{ ansible_user_id }}" mode: '0600' - name: Store ssh key in file ansible.builtin.copy: content: "{{ gitlab_public_key.ssh_public_key }}\n" dest: /home/{{ ansible_user_id }}/.ssh/id_ed25519_gitlab.pub owner: "{{ ansible_user_id }}" group: "{{ ansible_user_id }}" mode: '0600' - name: Create apt proxy file ansible.builtin.copy: dest: /etc/apt/apt.conf.d/02proxy content: | Acquire::http::Proxy "http://192.168.77.101:3128"; Acquire::https::Proxy "http://192.168.77.101:3128"; # Acquire::https::Proxy "false"; - name: Remove multiple files file: path: "{{ item }}" state: absent loop: - /etc/apt/sources.list.d/docker.sources - /etc/apt/sources.list.d/docker.list - /etc/apt/keyrings/docker.gpg - /etc/apt/trusted.gpg.d/containerd.gpg - /etc/apt/trusted.gpg.d/docker.gpg - name: Update apt cache apt: update_cache: true - name: Disable swap command: swapoff -a when: ansible_swaptotal_mb > 0 - name: Remove swap from fstab replace: path: /etc/fstab regexp: '.*swap.*' replace: '' - name: Enable kernel modules copy: dest: /etc/modules-load.d/k8s.conf content: | overlay br_netfilter - name: Load kernel modules modprobe: name: "{{ item }}" state: present loop: - overlay - br_netfilter - name: Set sysctl params 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: Apply sysctl command: sysctl --system - name: Install required packages apt: name: - apt-transport-https - ca-certificates - curl - git - gpg - curl - gnupg2 # - software-properties-common - gnupg state: present - name: Remove old Docker repository files (if any) file: path: "{{ item }}" state: absent loop: - /etc/apt/sources.list.d/docker.list - /etc/apt/keyrings/docker.gpg - /etc/apt/trusted.gpg.d/containerd.gpg - name: Create keyrings directory file: path: /etc/apt/keyrings state: directory mode: '0755' - name: Add Docker GPG key ansible.builtin.get_url: url: https://download.docker.com/linux/debian/gpg dest: /etc/apt/keyrings/docker.asc mode: '0644' - name: Add Docker repository ansible.builtin.copy: dest: /etc/apt/sources.list.d/docker.sources mode: '0644' content: | Types: deb URIs: https://download.docker.com/linux/debian Suites: {{ ansible_distribution_release }} Components: stable Architectures: {{ 'amd64' if ansible_architecture == 'x86_64' else ansible_architecture }} Signed-By: /etc/apt/keyrings/docker.asc - name: Update apt cache apt: update_cache: true - name: Install required packages apt: name: - containerd.io state: present - name: Generate default containerd config command: containerd config default register: containerd_config - name: Save containerd configuration copy: dest: /etc/containerd/config.toml content: "{{ containerd_config.stdout }}" owner: root group: root mode: 0644 - name: Enable SystemdCgroup in containerd config replace: path: /etc/containerd/config.toml regexp: 'SystemdCgroup\s*=\s*false' replace: 'SystemdCgroup = true' - name: Restart containerd systemd: name: containerd state: restarted enabled: yes - name: Add Kubernetes GPG key ansible.builtin.apt_key: url: https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key keyring: /etc/apt/keyrings/k8s.gpg state: present - name: Add Kubernetes repository copy: dest: /etc/apt/sources.list.d/k8s.list content: 'deb [signed-by=/etc/apt/keyrings/k8s.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' owner: root group: root mode: 0644 - name: Install Kubernetes packages apt: name: - kubelet - kubeadm - kubectl state: present update_cache: yes register: k8s_install retries: 5 delay: 10 until: k8s_install is succeeded - name: Hold Kubernetes packages command: apt-mark hold kubelet kubeadm kubectl - name: Enable kubelet systemd: name: kubelet enabled: yes state: started # # Optional UFW configuration # - name: Ensure UFW is installed # apt: # name: ufw # state: present # when: inventory_hostname == 'ubuntu24-vm01.home.lan' # - name: Allow Kubernetes ports # ufw: # rule: allow # port: "{{ item }}" # proto: tcp # loop: # - 6443 # - 2379:2380 # - 10250 # when: inventory_hostname == 'ubuntu24-vm01.home.lan' - name: Configure containerd for kubeadm copy: dest: /etc/containerd/config.toml content: | [plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "overlayfs" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true - name: Enable and start containerd systemd: name: containerd state: restarted # - name: Pause for 5 minutes to build app cache # ansible.builtin.pause: # minutes: 2 - name: Create .kube directory file: path: /home/{{ ansible_user_id }}/.kube state: directory owner: "{{ ansible_user_id }}" group: "{{ ansible_user_id }}" mode: '0755' when: inventory_hostname.endswith('-vm01.home.lan') - name: Initialize Kubernetes command: sudo kubeadm init --pod-network-cidr=10.244.0.0/16 args: creates: /etc/kubernetes/admin.conf when: inventory_hostname.endswith('-vm01.home.lan') - name: Copy kubeconfig to user copy: remote_src: yes src: /etc/kubernetes/admin.conf dest: /home/{{ ansible_user_id }}/.kube/config owner: "{{ ansible_user_id }}" group: "{{ ansible_user_id }}" mode: '0644' when: inventory_hostname.endswith('-vm01.home.lan') # - name: Pause for 5 minutes to build app cache # ansible.builtin.pause: # minutes: 2 - name: Install Flannel CNI ansible.builtin.command: cmd: kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml environment: KUBECONFIG: /etc/kubernetes/admin.conf when: - inventory_hostname.endswith("-vm01.home.lan") - net_driver == "flannel" register: flannel_result changed_when: "'created' in flannel_result.stdout or 'configured' in flannel_result.stdout" - name: Install Calico ansible.builtin.command: cmd: kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.3/manifests/calico.yaml environment: KUBECONFIG: /etc/kubernetes/admin.conf when: - inventory_hostname.endswith("-vm01.home.lan") - net_driver == "calico" register: calico_result changed_when: "'created' in calico_result.stdout or 'configured' in calico_result.stdout" - name: Get join command command: sudo kubeadm token create --print-join-command register: join_command when: inventory_hostname.endswith('-vm01.home.lan') - name: Save join command set_fact: worker_join_cmd: "{{ join_command.stdout }}" when: inventory_hostname.endswith('-vm01.home.lan') - name: Join cluster command: "{{ hostvars['debian12-vm01.home.lan'].worker_join_cmd }}" args: creates: /etc/kubernetes/kubelet.conf when: not inventory_hostname.endswith('-vm01.home.lan') - name: get repository git: repo: 'https://github.com/ahmetb/kubectx' dest: /opt/kubectx when: inventory_hostname.endswith('-vm01.home.lan') - name: Create symbolic links for kubectx and kubens file: src: /opt/kubectx/{{ item }} dest: /usr/local/bin/{{ item }} state: link loop: - kubectx - kubens when: inventory_hostname.endswith('-vm01.home.lan') - name: Install Additional packages apt: name: - nfs-common - tmux - telnet state: present - name: Ensure aliases exist in user's .bashrc lineinfile: path: "/home/{{ user_name }}/.bashrc" line: "alias {{ item.key }}='{{ item.value }}'" state: present create: yes loop: "{{ aliases | dict2items }}" when: inventory_hostname.endswith('-vm01.home.lan') # ---------------------------- # 1. Install Helm v3 # ---------------------------- - name: Download Helm get_url: url: "{{ helm_url }}" dest: "/tmp/{{ helm_tar }}" mode: '0644' when: inventory_hostname.endswith('-vm01.home.lan') - name: Create Helm config directory file: path: /home/jd/.config/helm state: directory mode: '0755' when: inventory_hostname.endswith('-vm01.home.lan') - name: Extract Helm archive unarchive: src: "/tmp/{{ helm_tar }}" dest: /tmp remote_src: true when: inventory_hostname.endswith('-vm01.home.lan') - name: Install Helm binary copy: src: /tmp/linux-amd64/helm dest: "{{ helm_bin }}" mode: '0755' remote_src: true when: inventory_hostname.endswith('-vm01.home.lan') - name: Verify Helm installation command: helm version environment: "{{ helm_env }}" when: inventory_hostname.endswith('-vm01.home.lan') - name: Ensure correct ownership of Helm config file: path: /home/jd/.kube state: directory owner: jd group: jd mode: '0700' when: inventory_hostname.endswith('-vm01.home.lan') - name: Ensure correct ownership of Helm config file: path: /home/jd/.config/helm state: directory owner: jd group: jd mode: '0700' when: inventory_hostname.endswith('-vm01.home.lan') # ---------------------------- # 3. Add NFS Helm repo # ---------------------------- - name: Add NFS Subdir External Provisioner repo kubernetes.core.helm_repository: name: nfs-subdir-external-provisioner repo_url: https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ environment: "{{ helm_env }}" become_user: "{{ ansible_user_id }}" when: inventory_hostname.endswith('-vm01.home.lan') - name: Update Helm repos command: helm repo update environment: "{{ helm_env }}" become_user: "{{ ansible_user_id }}" when: inventory_hostname.endswith('-vm01.home.lan') # ---------------------------- # 4. Install NFS provisioner # ---------------------------- - name: Install NFS Subdir External Provisioner kubernetes.core.helm: name: nfs-storage chart_ref: nfs-subdir-external-provisioner/nfs-subdir-external-provisioner release_namespace: kube-system create_namespace: true values: nfs: server: "{{ nfs_server }}" path: "{{ nfs_path }}" storageClass: name: nfs-client defaultClass: true kubeconfig: "{{ kubeconfig }}" environment: "{{ helm_env }}" become_user: "{{ ansible_user_id }}" when: inventory_hostname.endswith('-vm01.home.lan') - name: Ensure correct ownership of Helm config file: path: /home/jd/.config state: directory owner: jd group: jd when: inventory_hostname.endswith('-vm01.home.lan') - name: Ensure correct ownership of Helm config file: path: /home/jd/.kube/config state: file owner: jd group: jd mode: '0600' when: inventory_hostname.endswith('-vm01.home.lan')