prole/infrastructure/roles/k3s/tasks/main.yml
chrisfu 96f594fd3c Refactor initialization scripts and add new service components
- Consolidated and split initialization scripts in etc/:
    - Removed init_prole-db.sh and init_authority.sh.
    - Added init_kdc.sh for in-cluster MIT Kerberos KDC (prole-authority).
    - Added init_ollama.sh for Ollama AI service integration.
    - Added init_service_layer.sh for high-level service orchestration.
    - Added init_k3s_registry.sh for private registry management.
- Major updates to install.py:
    - Support for new Ollama and KDC configuration.
    - Improved prole.cfg rendering and namespace handling.
    - Updated unattended install flags.
- Infrastructure and Deployment:
    - Updated K3s Ansible role with private registry support (registries.yaml template).
    - Added prole-authority Dockerfile.
    - Updated OpenBao Kerberos ConfigMap and other K8s manifests.
- Configuration:
    - Updated prole.cfg with new sections for Ollama and Monitoring.
    - Refined environment variable exports in env.sh and prole_cfg.sh.
2026-02-11 13:09:31 -08:00

315 lines
11 KiB
YAML

---
- name: Skip k3s when state is absent
ansible.builtin.meta: end_host
when: k3s_state == "absent"
- name: Set k3s service name
ansible.builtin.set_fact:
k3s_service_name: "{{ 'k3s' if k3s_role == 'server' else 'k3s-agent' }}"
- name: Check if k3s service is installed
ansible.builtin.stat:
path: "/etc/systemd/system/{{ k3s_service_name }}.service"
register: k3s_service
- name: Check if k3s binary exists
ansible.builtin.stat:
path: /usr/local/bin/k3s
register: k3s_bin
- name: Determine if k3s needs installation
ansible.builtin.set_fact:
k3s_needs_install: "{{ not k3s_bin.stat.exists or not k3s_service.stat.exists }}"
- name: Install k3s dependencies
ansible.builtin.package:
name:
- curl
- iptables
state: present
- name: Preflight - ensure rancher mountpoint is mounted
ansible.builtin.command: "findmnt -n {{ k3s_rancher_mountpoint | default('/var/lib/rancher') }}"
register: rancher_mounted
changed_when: false
failed_when: rancher_mounted.rc != 0
- name: Preflight - ensure cgroup kernel params are present
ansible.builtin.command: "cat /proc/cmdline"
register: k3s_proc_cmdline
changed_when: false
- name: Fail if cgroup params are missing (reboot required)
ansible.builtin.fail:
msg: "Missing cgroup params in /proc/cmdline: {{ ['cgroup_memory=1', 'cgroup_enable=memory'] | reject('in', k3s_proc_cmdline.stdout) | list }}. Reboot required before k3s install."
when: (['cgroup_memory=1', 'cgroup_enable=memory'] | reject('in', k3s_proc_cmdline.stdout) | list) | length > 0
- name: Guardrail - ensure rancher mountpoint is not on SD/rootfs
ansible.builtin.command: "findmnt -n -o SOURCE {{ k3s_rancher_mountpoint | default('/var/lib/rancher') }}"
register: rancher_source
changed_when: false
- name: Fail if rancher mountpoint is on SD
ansible.builtin.fail:
msg: "{{ k3s_rancher_mountpoint | default('/var/lib/rancher') }} is on SD/rootfs ({{ rancher_source.stdout }}). Refusing to proceed."
when: rancher_source.stdout is search("mmcblk0") or rancher_source.stdout is search("/dev/mmc")
- name: Preflight - ensure required mountpoints are mounted
ansible.builtin.command: "findmnt -n {{ item }}"
register: k3s_required_mounts_present
changed_when: false
failed_when: k3s_required_mounts_present.rc != 0
loop: "{{ k3s_required_mounts | default([]) }}"
when: (k3s_required_mounts | default([])) | length > 0
- name: Guardrail - ensure required mountpoints are not on SD
ansible.builtin.command: "findmnt -n -o SOURCE {{ item }}"
register: k3s_required_mounts_sources
changed_when: false
loop: "{{ k3s_required_mounts | default([]) }}"
when: (k3s_required_mounts | default([])) | length > 0
- name: Fail if required mountpoint is on SD
ansible.builtin.fail:
msg: "{{ item.item }} is on SD/rootfs ({{ item.stdout }}). Refusing to proceed."
loop: "{{ k3s_required_mounts_sources.results }}"
when: item.stdout is search("mmcblk0") or item.stdout is search("/dev/mmc")
- name: Validate join configuration
ansible.builtin.assert:
that:
- k3s_server_url is defined
- k3s_server_url | length > 0
- k3s_token is defined
- k3s_token | length > 0
fail_msg: "k3s_server_url and k3s_token are required for non-init nodes."
when: not k3s_cluster_init | bool
- name: Ensure k3s config directory exists
ansible.builtin.file:
path: /etc/rancher/k3s
state: directory
mode: "0755"
- name: Load registry defaults from prole.cfg
ansible.builtin.set_fact:
k3s_prole_k3s_server_cfg: "{{ lookup('ansible.builtin.ini', 'PROLE_K3S_SERVER section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='') }}"
k3s_prole_service_namespace_cfg: "{{ lookup('ansible.builtin.ini', 'SERVICE_NAMESPACE section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='') }}"
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Resolve k3s registry host
ansible.builtin.set_fact:
k3s_registry_host_resolved: >-
{{ (k3s_registry_host | default('')) if (k3s_registry_host | default('') | length > 0)
else (k3s_prole_k3s_server_cfg | default('')) if (k3s_prole_k3s_server_cfg | default('') | length > 0)
else (k3s_server_url | default('')) if (k3s_server_url | default('') | length > 0)
else inventory_hostname }}
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Normalize k3s registry host
ansible.builtin.set_fact:
k3s_registry_host_resolved: "{{ k3s_registry_host_resolved | regex_replace('^https?://', '') | regex_replace('/.*$', '') | regex_replace(':.*$', '') }}"
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Resolve k3s registry namespace
ansible.builtin.set_fact:
k3s_registry_namespace_resolved: >-
{{ (k3s_registry_namespace | default('')) if (k3s_registry_namespace | default('') | length > 0)
else (k3s_prole_service_namespace_cfg | default('')) if (k3s_prole_service_namespace_cfg | default('') | length > 0)
else 'default' }}
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Validate k3s registry host
ansible.builtin.assert:
that:
- k3s_registry_host_resolved | length > 0
fail_msg: "k3s registry host could not be resolved (set k3s_registry_host or PROLE_K3S_SERVER)."
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Render k3s registries config
ansible.builtin.template:
src: registries.yaml.j2
dest: "{{ k3s_registry_config_path }}"
mode: "0644"
notify: Restart k3s
when: k3s_state == "present" and k3s_registry_config_enabled | bool
- name: Ensure kubeconfig group exists
ansible.builtin.group:
name: "{{ k3s_kubeconfig_group }}"
state: present
- name: Ensure kubeconfig users are in group (server)
ansible.builtin.user:
name: "{{ item }}"
groups: "{{ k3s_kubeconfig_group }}"
append: true
loop: "{{ k3s_kubeconfig_users }}"
when: k3s_role == "server" and (k3s_kubeconfig_users | length) > 0
- name: Ensure rancher directories are group-accessible
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: "{{ k3s_kubeconfig_group }}"
mode: "0750"
loop:
- /etc/rancher
- /etc/rancher/k3s
- "{{ k3s_rancher_mountpoint | default('/var/lib/rancher') }}"
when: k3s_state != "absent"
- name: Render k3s config
ansible.builtin.template:
src: config.yaml.j2
dest: /etc/rancher/k3s/config.yaml
mode: "0640"
notify: Restart k3s
- name: Build k3s install environment
ansible.builtin.set_fact:
k3s_install_env: >-
{{ {'INSTALL_K3S_EXEC': k3s_role}
| combine((k3s_version | length > 0) | ternary({'INSTALL_K3S_VERSION': k3s_version}, {})) }}
- name: Install k3s
ansible.builtin.shell: |
curl -sfL https://get.k3s.io | sh -
environment:
"{{ k3s_install_env }}"
args:
creates: /usr/local/bin/k3s
when: k3s_needs_install
- name: Ensure k3s service state
ansible.builtin.service:
name: "{{ k3s_service_name }}"
state: "{{ 'started' if k3s_state == 'present' else 'stopped' }}"
enabled: "{{ k3s_state == 'present' }}"
when: k3s_service.stat.exists or k3s_bin.stat.exists
- name: Ensure prole config directory exists
ansible.builtin.file:
path: "{{ prole_conf }}"
state: directory
mode: "0755"
when: k3s_state == "present"
- name: Sync prole.cfg to k3s hosts
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../conf/prole.cfg"
dest: "{{ prole_conf }}/prole.cfg"
mode: "0644"
when: k3s_state == "present"
- name: Ensure prole home directory exists
ansible.builtin.file:
path: "{{ prole_home }}"
state: directory
mode: "0755"
when: k3s_state == "present"
- name: Ensure prole service directory exists
ansible.builtin.file:
path: "{{ prole_home }}/etc"
state: directory
mode: "0755"
when: k3s_state == "present"
- name: Sync init_port_forwards.sh to k3s hosts
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../etc/init_port_forwards.sh"
dest: "{{ prole_home }}/etc/init_port_forwards.sh"
mode: "0755"
when: k3s_state == "present"
- name: Sync prole_cfg.sh to k3s hosts
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../etc/prole_cfg.sh"
dest: "{{ prole_home }}/etc/prole_cfg.sh"
mode: "0755"
when: k3s_state == "present"
- name: Select k3s init server for port-forward token
ansible.builtin.set_fact:
prole_port_forward_source_host: "{{ item }}"
loop: "{{ groups['k3s_hosts'] }}"
when: hostvars[item].k3s_cluster_init | default(false) | bool
delegate_to: localhost
delegate_facts: true
run_once: true
- name: Require k3s init server for port-forward token
ansible.builtin.assert:
that:
- hostvars['localhost'].prole_port_forward_source_host | default('') | length > 0
fail_msg: "No k3s init server found for port-forward token."
delegate_to: localhost
run_once: true
- name: Ensure prole-installer token secret exists
ansible.builtin.shell: |
k3s kubectl -n kube-system apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: prole-installer-token
annotations:
kubernetes.io/service-account.name: prole-installer
type: kubernetes.io/service-account-token
EOF
delegate_to: "{{ hostvars['localhost'].prole_port_forward_source_host }}"
run_once: true
when: k3s_state == "present"
- name: Read prole-installer token for port forwards
ansible.builtin.shell: >
k3s kubectl -n kube-system get secret prole-installer-token
-o jsonpath='{.data.token}' | base64 -d
delegate_to: "{{ hostvars['localhost'].prole_port_forward_source_host }}"
run_once: true
register: prole_installer_token
changed_when: false
when: k3s_state == "present"
- name: Store prole-installer token on controller
ansible.builtin.set_fact:
prole_port_forward_token: "{{ prole_installer_token.stdout | default('') }}"
delegate_to: localhost
delegate_facts: true
run_once: true
when: k3s_state == "present"
- name: Set prole port-forward token for host
ansible.builtin.set_fact:
prole_port_forward_token: "{{ hostvars['localhost'].prole_port_forward_token }}"
when:
- k3s_state == "present"
- hostvars['localhost'].prole_port_forward_token | default('') | length > 0
- name: Render kubeconfig for port forwards
ansible.builtin.template:
src: prole-kubeconfig.yaml.j2
dest: "{{ prole_port_forward_kubeconfig }}"
mode: "0640"
owner: root
group: "{{ k3s_kubeconfig_group }}"
when: k3s_state == "present"
- name: Install prole port-forwards systemd unit
ansible.builtin.template:
src: prole-port-forwards.service.j2
dest: "/etc/systemd/system/{{ prole_port_forward_service_name }}.service"
mode: "0644"
when: k3s_state == "present"
- name: Enable and start prole port-forwards service
ansible.builtin.systemd:
name: "{{ prole_port_forward_service_name }}"
enabled: true
state: started
daemon_reload: true
when: k3s_state == "present"