mirror of
https://github.com/techno-tim/k3s-ansible.git
synced 2026-08-09 07:23:19 +02:00
010551b8d2
Add a `cilium_envoy` variable (default true, matching upstream Cilium 1.20 which installs Envoy by default) that controls whether the Envoy proxy is deployed for Cilium L7 policies. Pass it to Helm as `envoy.enabled` so users with no L7 policies can skip Envoy to save resources. - roles/k3s_server_post/defaults/main.yml: add cilium_envoy: true default - roles/k3s_server_post/tasks/cilium.yml: add --helm-set envoy.enabled to the install/upgrade command, driven by the cilium_envoy conditional - inventory/sample/group_vars/all.yml: document cilium_envoy sample var - .github/scripts/test-cilium-envoy-toggle.py: regression test asserting the install command carries the envoy.enabled helm-set and renders true/false - .pre-commit-config.yaml: wire the new test into pre-commit Co-authored-by: Léo Nonnenmacher <leo@nonnenmacher-logel.fr>
288 lines
11 KiB
YAML
288 lines
11 KiB
YAML
---
|
|
- name: Prepare Cilium CLI on first master and deploy CNI
|
|
when: ansible_hostname == hostvars[groups[group_name_master | default('master')][0]]['ansible_hostname']
|
|
run_once: true
|
|
block:
|
|
- name: Create tmp directory on first master
|
|
ansible.builtin.file:
|
|
path: /tmp/k3s
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Check if Cilium CLI is installed
|
|
ansible.builtin.command: cilium version
|
|
register: cilium_cli_installed
|
|
failed_when: false
|
|
changed_when: false
|
|
ignore_errors: true
|
|
|
|
- name: Check for Cilium CLI version in command output
|
|
ansible.builtin.set_fact:
|
|
installed_cli_version: >-
|
|
{{
|
|
cilium_cli_installed.stdout_lines
|
|
| join(' ')
|
|
| regex_findall('cilium-cli: (v\d+\.\d+\.\d+)')
|
|
| first
|
|
| default('unknown')
|
|
}}
|
|
when: cilium_cli_installed.rc == 0
|
|
|
|
- name: Log installed Cilium CLI version
|
|
ansible.builtin.debug:
|
|
msg: "Installed Cilium CLI version: {{ installed_cli_version | default('Not installed') }}"
|
|
|
|
- name: Log pinned Cilium CLI version
|
|
ansible.builtin.debug:
|
|
msg: "Pinned Cilium CLI version: {{ cilium_cli_tag }}"
|
|
|
|
- name: Determine if Cilium CLI needs installation or update
|
|
ansible.builtin.set_fact:
|
|
cilium_cli_needs_update: >-
|
|
{{
|
|
cilium_cli_installed.rc != 0 or
|
|
(cilium_cli_installed.rc == 0 and
|
|
installed_cli_version != cilium_cli_tag)
|
|
}}
|
|
|
|
- name: Install or update Cilium CLI
|
|
when: cilium_cli_needs_update
|
|
block:
|
|
- name: Set architecture variable
|
|
ansible.builtin.set_fact:
|
|
cli_arch: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"
|
|
|
|
- name: Download Cilium CLI and checksum
|
|
ansible.builtin.get_url:
|
|
url: "{{ cilium_base_url }}/cilium-linux-{{ cli_arch }}{{ item }}"
|
|
dest: /tmp/k3s/cilium-linux-{{ cli_arch }}{{ item }}
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
loop:
|
|
- .tar.gz
|
|
- .tar.gz.sha256sum
|
|
vars:
|
|
cilium_base_url: https://github.com/cilium/cilium-cli/releases/download/{{ cilium_cli_tag }}
|
|
register: cilium_cli_download
|
|
retries: "{{ download_retries }}"
|
|
delay: "{{ download_delay }}"
|
|
until: cilium_cli_download is succeeded
|
|
|
|
- name: Verify the downloaded tarball
|
|
ansible.builtin.shell: |
|
|
cd /tmp/k3s && sha256sum --check cilium-linux-{{ cli_arch }}.tar.gz.sha256sum
|
|
args:
|
|
executable: /bin/bash
|
|
changed_when: false
|
|
|
|
- name: Extract Cilium CLI to /usr/local/bin
|
|
ansible.builtin.unarchive:
|
|
src: /tmp/k3s/cilium-linux-{{ cli_arch }}.tar.gz
|
|
dest: /usr/local/bin
|
|
remote_src: true
|
|
|
|
- name: Remove downloaded tarball and checksum file
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: absent
|
|
loop:
|
|
- /tmp/k3s/cilium-linux-{{ cli_arch }}.tar.gz
|
|
- /tmp/k3s/cilium-linux-{{ cli_arch }}.tar.gz.sha256sum
|
|
|
|
- name: Wait for connectivity to kube VIP
|
|
ansible.builtin.command: ping -c 1 {{ apiserver_endpoint }}
|
|
register: ping_result
|
|
until: ping_result.rc == 0
|
|
retries: 21
|
|
delay: 1
|
|
ignore_errors: true
|
|
changed_when: false
|
|
|
|
- name: Fail if kube VIP not reachable
|
|
ansible.builtin.fail:
|
|
msg: API endpoint {{ apiserver_endpoint }} is not reachable
|
|
when: ping_result.rc != 0
|
|
|
|
- name: Test for existing Cilium install
|
|
ansible.builtin.command: |
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }} -n kube-system get daemonsets cilium
|
|
register: cilium_installed
|
|
failed_when: false
|
|
changed_when: false
|
|
ignore_errors: true
|
|
|
|
- name: Check existing Cilium install
|
|
when: cilium_installed.rc == 0
|
|
block:
|
|
- name: Check Cilium version
|
|
ansible.builtin.command: cilium version
|
|
register: cilium_version
|
|
failed_when: false
|
|
changed_when: false
|
|
ignore_errors: true
|
|
|
|
- name: Parse installed Cilium version
|
|
ansible.builtin.set_fact:
|
|
installed_cilium_version: >-
|
|
{{
|
|
cilium_version.stdout_lines
|
|
| join(' ')
|
|
| regex_findall('cilium image.+(\d+\.\d+\.\d+)')
|
|
| first
|
|
| default('unknown')
|
|
}}
|
|
|
|
- name: Determine if Cilium needs update
|
|
ansible.builtin.set_fact:
|
|
cilium_needs_update: >-
|
|
{{ 'v' + installed_cilium_version != cilium_tag }}
|
|
|
|
- name: Log result
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
Installed Cilium version: {{ installed_cilium_version }},
|
|
Target Cilium version: {{ cilium_tag }},
|
|
Update needed: {{ cilium_needs_update }}
|
|
|
|
- name: Map the legacy routed mode to Cilium tunnel mode
|
|
ansible.builtin.set_fact:
|
|
# Cilium 1.20 accepts `native` or `tunnel`. `routed` was the name used
|
|
# by older releases and is kept only as a backward-compatible alias.
|
|
cilium_routing_mode: >-
|
|
{{ 'tunnel' if cilium_mode == 'routed' else cilium_mode }}
|
|
|
|
- name: Install Cilium
|
|
ansible.builtin.command: >-
|
|
{% if cilium_installed.rc != 0 %}
|
|
cilium install
|
|
{% else %}
|
|
cilium upgrade
|
|
{% endif %}
|
|
--version "{{ cilium_tag }}"
|
|
--helm-set operator.replicas="1"
|
|
{{ '--helm-set devices=' + cilium_iface if cilium_iface != 'auto' else '' }}
|
|
--helm-set ipam.operator.clusterPoolIPv4PodCIDRList={{ cluster_cidr }}
|
|
{% if cilium_routing_mode == "native" or (cilium_bgp and cilium_exportPodCIDR != 'false') %}
|
|
--helm-set ipv4NativeRoutingCIDR={{ cluster_cidr }}
|
|
{% endif %}
|
|
--helm-set k8sServiceHost="127.0.0.1"
|
|
--helm-set k8sServicePort="6444"
|
|
--helm-set routingMode={{ cilium_routing_mode }}
|
|
--helm-set autoDirectNodeRoutes={{ "true" if cilium_routing_mode == "native" else "false" }}
|
|
--helm-set kubeProxyReplacement={{ kube_proxy_replacement }}
|
|
--helm-set bpf.masquerade={{ enable_bpf_masquerade }}
|
|
--helm-set bgpControlPlane.enabled={{ cilium_bgp | default("false") }}
|
|
--helm-set hubble.enabled={{ "true" if cilium_hubble else "false" }}
|
|
--helm-set hubble.relay.enabled={{ "true" if cilium_hubble else "false" }}
|
|
--helm-set hubble.ui.enabled={{ "true" if cilium_hubble else "false" }}
|
|
--helm-set envoy.enabled={{ "true" if cilium_envoy else "false" }}
|
|
{% if kube_proxy_replacement is not false %}
|
|
--helm-set loadBalancer.algorithm={{ bpf_lb_algorithm }}
|
|
--helm-set loadBalancer.mode={{ bpf_lb_mode }}
|
|
{% endif %}
|
|
environment:
|
|
KUBECONFIG: "{{ ansible_user_dir }}/.kube/config"
|
|
register: cilium_install_result
|
|
changed_when: cilium_install_result.rc == 0
|
|
# cilium install/upgrade fetches the Helm chart from helm.cilium.io, which is
|
|
# fronted by GitHub Pages and can transiently fail DNS resolution through the
|
|
# host resolver (intermittent "lookup helm.cilium.io ... i/o timeout"). Retry
|
|
# so a transient name/network failure does not abort the whole converge play.
|
|
until: cilium_install_result.rc == 0
|
|
retries: "{{ download_retries }}"
|
|
delay: "{{ download_delay }}"
|
|
when: cilium_installed.rc != 0 or cilium_needs_update
|
|
|
|
- name: Wait for Cilium resources
|
|
ansible.builtin.command: >-
|
|
{% if item.type == 'daemonset' %}
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }} wait pods
|
|
--namespace=kube-system
|
|
--selector='k8s-app=cilium'
|
|
--for=condition=Ready
|
|
{% else %}
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }} wait {{ item.type }}/{{ item.name }}
|
|
--namespace=kube-system
|
|
--for=condition=Available
|
|
{% endif %}
|
|
--timeout=30s
|
|
register: cr_result
|
|
changed_when: false
|
|
until: cr_result is succeeded
|
|
retries: 30
|
|
delay: 7
|
|
with_items:
|
|
- { name: cilium-operator, type: deployment }
|
|
- { name: cilium, type: daemonset, selector: k8s-app=cilium }
|
|
- { name: hubble-relay, type: deployment, check_hubble: true }
|
|
- { name: hubble-ui, type: deployment, check_hubble: true }
|
|
loop_control:
|
|
label: "{{ item.type }}/{{ item.name }}"
|
|
when: >-
|
|
not item.check_hubble | default(false) or (item.check_hubble | default(false) and cilium_hubble)
|
|
|
|
- name: Wait for Cilium status to be healthy
|
|
ansible.builtin.command: cilium status --wait
|
|
environment:
|
|
KUBECONFIG: "{{ ansible_user_dir }}/.kube/config"
|
|
register: cilium_status
|
|
changed_when: false
|
|
until: cilium_status.rc == 0
|
|
retries: 30
|
|
delay: 7
|
|
|
|
- name: Configure Cilium BGP
|
|
when: cilium_bgp
|
|
block:
|
|
- name: Set _cilium_bgp_neighbors fact
|
|
ansible.builtin.set_fact:
|
|
_cilium_bgp_neighbors: "{{ lookup('community.general.merge_variables', '^cilium_bgp_neighbors__.+$', initial_value=cilium_bgp_neighbors, groups=cilium_bgp_neighbors_groups) }}" # yamllint disable-line rule:line-length
|
|
|
|
- name: Copy BGP manifests to first master
|
|
ansible.builtin.template:
|
|
src: cilium.crs.j2
|
|
dest: /tmp/k3s/cilium-bgp.yaml
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Preflight validate rendered BGP manifests against installed CRDs
|
|
ansible.builtin.command: >-
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }}
|
|
apply --dry-run=server -f /tmp/k3s/cilium-bgp.yaml
|
|
register: preflight_cr
|
|
changed_when: false
|
|
failed_when: preflight_cr.rc != 0
|
|
|
|
- name: Apply BGP manifests
|
|
ansible.builtin.command: >-
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }}
|
|
apply -f /tmp/k3s/cilium-bgp.yaml
|
|
register: apply_cr
|
|
changed_when: "'configured' in apply_cr.stdout or 'created' in apply_cr.stdout"
|
|
failed_when: apply_cr.rc != 0
|
|
|
|
- name: Remove deprecated CiliumBGPPeeringPolicy after v2 resources are accepted
|
|
ansible.builtin.command: >-
|
|
{{ k3s_kubectl_binary | default('k3s kubectl') }}
|
|
delete CiliumBGPPeeringPolicy.cilium.io 01-bgp-peering-policy
|
|
register: delete_old_policy
|
|
changed_when: "'deleted' in delete_old_policy.stdout"
|
|
# The policy (and possibly its CRD) may already be absent; this is
|
|
# intentionally tolerated, not a command whose failure must be hidden.
|
|
failed_when: false
|
|
|
|
- name: Test for BGP config resources
|
|
ansible.builtin.command: "{{ item }}"
|
|
loop:
|
|
- "{{ k3s_kubectl_binary | default('k3s kubectl') }} get CiliumBGPClusterConfig.cilium.io"
|
|
- "{{ k3s_kubectl_binary | default('k3s kubectl') }} get CiliumBGPPeerConfig.cilium.io"
|
|
- "{{ k3s_kubectl_binary | default('k3s kubectl') }} get CiliumBGPAdvertisement.cilium.io"
|
|
- "{{ k3s_kubectl_binary | default('k3s kubectl') }} get CiliumLoadBalancerIPPool.cilium.io"
|
|
changed_when: false
|
|
loop_control:
|
|
label: "{{ item }}"
|