Files
k3s-ansible/roles/k3s_agent/tasks/main.yml
T
Aleksei Sviridkin e5ec2f07b4 fix: apply k3s version bumps declaratively through site.yml (#544)
Re-running site.yml with a raised k3s_version replaced the on-disk
binary but left agents and joined servers running the old runtime,
because the install script skips the service start and the roles only
restarted the service on a config change. A version-only bump was
therefore not applied until the services were restarted by hand.

Always restart the k3s service in the server and agent roles on a
site.yml run, so the cluster reliably picks up a new config or runtime
without any logic to detect whether the binary changed. On a
multi-server cluster, run the playbook with --forks=1 so the servers
restart one at a time and the etcd quorum is preserved; document this
in the README.

Keep the dedicated upgrade.yml integration test and add a second
upgrade through site.yml, asserting the running version the kubelet
reports rather than the on-disk binary, so the tests fail if the
restart regresses.



Assisted-By: Claude <noreply@anthropic.com>

Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-07-14 16:24:42 -07:00

107 lines
4.1 KiB
YAML

---
- name: Get k3s installed version
ansible.builtin.command: k3s --version
register: k3s_agent_version_output
changed_when: false
failed_when: false
- name: Set k3s installed version
when: not ansible_check_mode and k3s_agent_version_output.rc == 0
ansible.builtin.set_fact:
k3s_agent_installed_version: "{{ k3s_agent_version_output.stdout_lines[0].split(' ')[2] }}"
# If airgapped, all K3s artifacts are already on the node.
# We should be downloading and installing the newer version only if we are in one of the following cases :
# - we couldn't get k3s installed version in the first task of this role
# - the installed version of K3s on the nodes is older than the requested version in ansible vars
- name: Download artifact only if needed
when: not ansible_check_mode and airgap_dir is undefined and ( k3s_agent_version_output.rc != 0 or k3s_agent_installed_version is version(k3s_version, '<') )
block:
- name: Download K3s install script
ansible.builtin.get_url:
url: https://get.k3s.io/
timeout: 120
dest: /usr/local/bin/k3s-install.sh
owner: root
group: root
mode: "0755"
- name: Set skip_download var for install script
# noqa var-naming[no-role-prefix]
ansible.builtin.set_fact:
skip_download: "false"
# We always run the install script, we just skip the download step as needed
- name: Run K3s install script
# noqa var-naming[no-role-prefix]
ansible.builtin.command:
cmd: /usr/local/bin/k3s-install.sh
environment: "{{ _install_envs }}"
vars:
_base_envs:
INSTALL_K3S_SKIP_DOWNLOAD: "{{ skip_download | default('true') }}"
INSTALL_K3S_SKIP_START: "true"
INSTALL_K3S_SYSTEMD_DIR: "{{ systemd_dir }}"
INSTALL_K3S_VERSION: "{{ k3s_version }}"
INSTALL_K3S_EXEC: "agent --server https://{{ api_endpoint }}:{{ api_port }} {{ extra_agent_args }}"
# We overrides the extra_install_envs with required keys from _base_envs on purpose
_install_envs: "{{ extra_install_envs | default({}) | combine(_base_envs) }}"
changed_when: true
- name: Setup optional config file
when: agent_config_yaml is defined
block:
- name: Make config directory
ansible.builtin.file:
path: "/etc/rancher/k3s"
mode: "0755"
state: directory
- name: Copy config values
# noqa var-naming[no-role-prefix]
ansible.builtin.copy:
content: "{{ agent_config_yaml }}"
dest: "/etc/rancher/k3s/config.yaml"
mode: "0644"
register: _agent_config_result
- name: Get the token from the first server
when: token is not defined and hostvars[groups[server_group][0]].random_token is defined
# noqa var-naming[no-role-prefix]
ansible.builtin.set_fact:
token: "{{ hostvars[groups[server_group][0]].random_token }}"
- name: Set k3s agent environment file based on init system
ansible.builtin.set_fact:
k3s_agent_env_file: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary(systemd_dir ~ '/k3s-agent.service.env', '/etc/rancher/k3s/k3s-agent.env') }}"
- name: Add service environment variables
when: extra_service_envs is defined
ansible.builtin.lineinfile:
path: "{{ k3s_agent_env_file }}"
line: "{{ item }}"
loop: "{{ extra_service_envs }}"
- name: Delete any existing token from the environment if different from the new one
ansible.builtin.lineinfile:
state: absent
path: "{{ k3s_agent_env_file }}"
regexp: "^K3S_TOKEN=\\s*(?!{{ token | regex_escape }}\\s*$)"
- name: Add the token for joining the cluster to the environment
no_log: true # avoid logging the server token
ansible.builtin.lineinfile:
path: "{{ k3s_agent_env_file }}"
line: "{{ item }}"
loop:
- "K3S_TOKEN={{ token }}"
# Always restart so a re-run of site.yml — whether it changed the agent config
# or bumped k3s_version — reliably brings the agent onto the new state. The
# install script leaves the service stopped (INSTALL_K3S_SKIP_START), so a plain
# restart also covers the first install.
- name: Enable and start K3s agent
ansible.builtin.service:
name: k3s-agent
state: restarted
enabled: true