Merge branch 'development' into 'master'

build: release to stable

See merge request nofusscomputing/projects/ansible/kubernetes!18
This commit is contained in:
2024-02-03 05:13:01 +00:00
29 changed files with 31080 additions and 259 deletions

View File

@ -4,4 +4,4 @@ commitizen:
name: cz_conventional_commits
tag_format: $major.$minor.$patch$prerelease
update_changelog_on_bump: true
version: 0.1.0
version: 0.2.0rc1

View File

@ -19,3 +19,25 @@ Ansible-roles.Submodule.Deploy:
GIT_COMMIT_TYPE: feat
GIT_COMMIT_TYPE_CATEGORY: $CI_PROJECT_NAME
GIT_CONFIG_SUBMODULE_NAME: nfc_kubernetes
Website.Submodule.Deploy:
extends: .submodule_update_trigger
variables:
SUBMODULE_UPDATE_TRIGGER_PROJECT: nofusscomputing/infrastructure/website
environment:
url: https://nofusscomputing.com/$PAGES_ENVIRONMENT_PATH
name: Documentation
rules:
- if: # condition_dev_branch_push
$CI_COMMIT_BRANCH == "development" &&
$CI_PIPELINE_SOURCE == "push"
exists:
- '{docs/**,pages/**}/*.md'
changes:
paths:
- '{docs/**,pages/**}/*.md'
compare_to: 'master'
when: always
- when: never

View File

@ -1,3 +1,48 @@
## 0.2.0rc1 (2023-11-06)
### Bug Fixes
- **config**: [f09737b2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/f09737b21f1bac4d505207136e9505c83140b4cf) - typo in config template [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
- **rbac**: [6ab17bdc](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/6ab17bdc3c660e704ce7319a21a517f38907a541) - authorization:namespace:owner ns owner not to remove cluster resources [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
- **container_registries**: [9936cd44](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/9936cd449911a0e9612309690fbca82e8565c2b3) - these are optional, dont attempt to configure if non specified [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
- **config**: [5278a499](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/5278a4996e0370bbe14ba08189879c19f6b1f983) - server attribute not required for prime master node [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
### Documentaton / Guides
- [0acc7a3c](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/0acc7a3cc2b93f94fc92839e34dec02cfe4d5ec2) - added note on config for system resources [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) [#7](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/7) ]
### Features
- **rbac**: [59f50d53](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/59f50d53df4e28ef114d734f652cb25d396a381d) - new cluster role and binding ingress-admin [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
- **config**: [d2081284](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/d2081284d1d526a57a34082f5ad944dc12671750) - configurabl system reserved cpu,memory,storage [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
- **install**: [42ac18e0](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/42ac18e05768e61f0d960fb3afe2482431bd5fce) - disable swap [ [!6](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/6) ]
## 0.2.0rc0 (2023-11-02)
### Bug Fixes
- **firewall**: [9c420475](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/9c4204751e00c6d8a36c0fcb1ff66f0a87ba574e) - use correct chain name [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) [#2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/2) ]
- **firewall**: [ba59dd30](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/ba59dd305728b15801aca3aef81ea8aa35e5d402) - correct rules so that kubernetes hosts are added to firewall allowed hosts [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) [#2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/2) ]
- **wireguard**: [4a9d9839](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/4a9d98394e3fd327a0f681e42b5415e25520cff4) - install before k3s [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **templates**: [89b65732](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/89b65732478883a5ccc29c9100c30840bf08d55e) - add clause to filter for prime master only [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **install**: [b77cc6a8](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/b77cc6a8e902739f43519d4e9a0c0dcfca0cc30f) - install prime then wait till ready before install other nodes [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **install**: [26f1f2ef](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/26f1f2efe63b47f7ab569f99aa0c1b5f28ff461b) - server install to use version variables [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **configure**: [db515d2c](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/db515d2c1d921950c034911fad6622f969232895) - move required config files to install portion [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **config**: [1b62a666](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/1b62a6663285b6c62323ca387ba176cc9d7eff74) - cluster-init only required for master nodes [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
### Code Refactor
- [4d9f9dcd](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/4d9f9dcdff5d07bb9f0722ddc22ff061ffa24f20) - use kubernetes_config for cluster config [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **template**: [50f48ab5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/50f48ab5a1a5983ed7465fefda7119df5d4fff96) - config.yaml rearranged orderd, and updated for kube role [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
- **install**: [4465bcd2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/4465bcd2c4f4a94cacd0f35025d63f4f858ee58d) - clean wait for k3s to be ready [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) ]
### Features
- **install**: [c7907bf5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/c7907bf585d182b5e68d241428dd69d7c1af1be7) - install additional master nodes [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) [#2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/2) ]
- **install**: [fd547a4c](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/fd547a4c0fbfa34fca6ec6860d294c1713594e41) - install worker nodes [ [!5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/5) [#2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/2) ]
- **install**: [76e48fd9](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/76e48fd965b9113d7aa69679524bc119f45db6ac) - wait for cluster to be ready before continuing [ [!4](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/4) ]
- **config**: [abc01ce4](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/commit/abc01ce48cbd586dfec067b3fcdbca0d204843d4) - enable configering etc cron and retention [ [!4](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/merge_requests/4) ]
## 0.1.0 (2023-10-29)
### Bug Fixes

View File

@ -13,7 +13,7 @@
![GitHub forks](https://img.shields.io/github/forks/NofussComputing/ansible_role_homeassistant?logo=github&style=plastic&color=000000&labell=Forks) ![GitHub stars](https://img.shields.io/github/stars/NofussComputing/ansible_role_homeassistant?color=000000&logo=github&style=plastic) ![Github Watchers](https://img.shields.io/github/watchers/NofussComputing/ansible_role_homeassistant?color=000000&label=Watchers&logo=github&style=plastic)
![GitHub forks](https://img.shields.io/github/forks/NofussComputing/ansible_role_nfc_kubernetes?logo=github&style=plastic&color=000000&labell=Forks) ![GitHub stars](https://img.shields.io/github/stars/NofussComputing/ansible_role_nfc_kubernetes?color=000000&logo=github&style=plastic) ![Github Watchers](https://img.shields.io/github/watchers/NofussComputing/ansible_role_nfc_kubernetes?color=000000&label=Watchers&logo=github&style=plastic)
<br>
This project is hosted on [gitlab](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes) and has a read-only copy hosted on [Github](https://github.com/NofussComputing/ansible_role_nfc_kubernetes).

View File

@ -1,5 +1,29 @@
KubernetesPodSubnet: 10.85.0.0/16
KubernetesServiceSubnet: 10.86.0.0/16
# Depreciated:
# Calico is being migrated to use the calico operator.
# in a near future release, this method of deploying calico
# will be removed. use tag `operator_migrate_calico` to migrate
calico_image_tag: v3.25.0 # Depreciated
# EoF Depreciated
# SoF New Variables
nfc_kubernetes_calico_version: v3.27.0
nfc_kubernetes_tigera_operator_registry: quay.io
nfc_kubernetes_tigera_operator_image: tigera/operator
nfc_kubernetes_tigera_operator_tag: v1.32.3 # Calico v3.27.0
# EoF New Variables, EEoF Depreciated
nfc_kubernetes_enable_metallb: false
nfc_kubernetes_enable_servicelb: false
############################################################################################################
#
# Old Vars requiring refactoring
#
# ############################################################################################################
# KubernetesPodSubnet: 10.85.0.0/16
# KubernetesServiceSubnet: 10.86.0.0/16
Kubernetes_Prime: false # Optional, Boolean. Is the current host the Prime master?
@ -7,57 +31,43 @@ Kubernetes_Master: false # Optional, Boolean.
ContainerDioVersion: 1.6.20-1
KubernetesVersion: '1.26.2' # must match the repository release version
kubernetes_version_olm: '0.26.0'
KubernetesVersion_k8s_prefix: '-00'
KubernetesVersion_k3s_prefix: '+k3s1'
kubernetes_private_container_registry: [] # Optional, Array. if none use `[]`
kubernetes_etcd_snapshot_cron_schedule: '0 */12 * * *'
kubernetes_etcd_snapshot_retention: 5
# host_external_ip: '' # Optional, String. External IP Address for host.
# Optional, Dict. Used to configure Kubernetes with OIDC Authentication.
# kubernetes_oidc:
# enabled: true # Mandatory, boolen. speaks for itself.
# issuer_url: https://domainname.com/realms/realm-name # Mandatory, String. URL of OIDC Provider
# client_id: kubernetes-test # Mandatory, string. OIDC Client ID
# username_claim: preferred_username # Mandatory, String. Claim name containing username.
# username_prefix: oidc # Optional, String. What to prefix to username
# groups_claim: roles # Mandatory, String. Claim name containing groups
# groups_prefix: '' # Optional, String. string to append to groups
kubernetes_type: k8s # Mandatory, String. choice K8s | k3s
kube_apiserver_arg_audit_log_maxage: 2
kubelet_arg_system_reserved_cpu: 450m
kubelet_arg_system_reserved_memory: 512Mi
kubelet_arg_system_reserved_storage: 8Gi
# kubernetes_olm_install: true # optional, boolean. default=true
nfc_kubernetes:
enable_firewall: true # Optional, bool enable firewall rules from role 'nfc_firewall'
nfc_kubernetes_no_restart: false # Set to true to prevent role from restarting kubernetes on the host(s)
nfc_kubernetes_no_restart_master: false # Set to true to prevent role from restarting kubernetes on master host(s)
nfc_kubernetes_no_restart_prime: false # Set to true to prevent role from restarting kubernetes on prime host
nfc_kubernetes_no_restart_slave: false # Set to true to prevent role from restarting kubernetes on slave host(s)
k3s:
files:
# - name: config.yaml
# path: /etc/rancher/k3s
# content: |
# flannel-backend: none
# cluster-cidr: "{{ KubernetesPodSubnet }}"
# cluster-init: true
# {% if not Kubernetes_Prime | default(false) | bool -%}server: https://{{ hostvars[kubernetes_config.cluster.prime.name].ansible_host }}:6443{% endif %}
# service-cidr: "{{ KubernetesServiceSubnet }}"
# disable-network-policy: true
# disable:
# - traefik
# kube-apiserver-arg:
# - audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log
# - audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml
# # - admission-control-config-file=/var/lib/rancher/k3s/server/psa.yaml
# {% if kubernetes_oidc.enabled | default(false) | bool -%}
# - oidc-issuer-url={{ kubernetes_oidc.issuer_url }}
# - oidc-client-id={{ kubernetes_oidc.client_id }}
# - oidc-username-claim={{ kubernetes_oidc.username_claim }}
# - {% if kubernetes_oidc.oidc_username_prefix | default('') != '' %}oidc-username-prefix={{ kubernetes_oidc.oidc_username_prefix }}{% endif %}
# - oidc-groups-claim={{ kubernetes_oidc.groups_claim }}
# {% if kubernetes_oidc.groups_prefix | default('') != '' %}- oidc-groups-prefix={{ kubernetes_oidc.groups_prefix }}{% endif %}
# {% endif %}
# node-external-ip: "{{ host_external_ip }}"
- name: audit.yaml
path: /var/lib/rancher/k3s/server
@ -66,6 +76,7 @@ k3s:
kind: Policy
rules:
- level: Request
when: "{{ Kubernetes_Master | default(false) }}"
- name: 90-kubelet.conf
path: /etc/sysctl.d
@ -79,7 +90,7 @@ k3s:
- name: psa.yaml
path: /var/lib/rancher/k3s/server
content: ""
# apiVersion: apiserver.config.k8s.io/v1
# apiVersion: apiserver.conf0 */12 * * *ig.k8s.io/v1
# kind: AdmissionConfiguration
# plugins:
# - name: PodSecurity
@ -97,7 +108,7 @@ k3s:
# usernames: []
# runtimeClasses: []
# namespaces: [kube-system]
when: "{{ kubernetes_config.cluster.prime.name == inventory_hostname }}"
#############################################################################################
@ -107,12 +118,13 @@ k3s:
#############################################################################################
# kubernetes_config: # Dict. Cluster Config
# cluster:
# access: # Mandatory. List, DNS host name or IPv4/IPv6 Address.
# access: # Mandatory. List, DNS host name or IPv4/IPv6 Address.
# # if none use '[]'
# - 'my.dnshostname.com'
# - '2001:4860:4860::8888'
# - '192.168.1.1'
# Name: earth # Mandatory, String. Cluster Name
# group_name: # Mandatory, String. name of the ansible inventory group containg all cluster hosts
# prime:
# name: k3s-prod # Mandatory, String. Ansible inventory_host that will
# # act as the prime master node.
@ -124,3 +136,22 @@ k3s:
# node_token: !vault |
# $ANSIBLE_VAULT;1.2;AES256;kubernetes/cluster/production
# {rest_of encrypted key}
# oidc: # Used to configure Kubernetes with OIDC Authentication.
# enabled: true # Mandatory, boolen. speaks for itself.
# issuer_url: https://domainname.com/realms/realm-name # Mandatory, String. URL of OIDC Provider
# client_id: kubernetes-test # Mandatory, string. OIDC Client ID
# username_claim: preferred_username # Mandatory, String. Claim name containing username.
# username_prefix: oidc # Optional, String. What to prefix to username
# groups_claim: roles # Mandatory, String. Claim name containing groups
# groups_prefix: '' # Optional, String. string to append to groups
# hosts:
# my-host-name:
# labels:
# mylabel: myvalue
# taints:
# - effect: NoSchedule
# key: taintkey
# value: taintvalue

View File

@ -6,22 +6,36 @@ template: project.html
about: https://gitlab.com/nofusscomputing/projects/ansible/roles/kubernetes
---
This Ansible roles purpose is to install and configure Kubernetes with configuration from code. You can also use [our playbooks](../../playbooks/index.md) to deploy using this role. this is especially useful if you are also using [our Ansible Execution Environment](../../execution_environment/index.md)
This Ansible role is designed to deploy a K3s Kubernetes cluster. After adding your configuration, the cluster will deploy and have a configured CNI (calico) and be in a state ready to use. This role can be used with our [our playbooks](../../playbooks/index.md) or comes included, along with the playbook within our [Ansible Execution Environment](../../execution_environment/index.md).
## Features
This role deploys a K3s cluster. In addition it has the following features:
- CNI Setup
- Configurable Container Registries
- Configurable:
- _[ToDo-#3](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/3)_ Encryption between nodes (Wireguard)
- Container Registries
- etcd snapshot cron schedule
- etcd snapshot retention
- Cluster Domain
- Configure System reserved CPU, Storage and Memory.
- Node Labels
- Node Taints
- Service Load Balancer Namespace
- Encryption between nodes (Wireguard)
- [Firewall configured for kubernetes host](firewall.md)
- _[ToDo-#2](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/2)_ Multi-node Deployment
- Multi-node Deployment
- OpenID Connect SSO Authentication
@ -29,10 +43,14 @@ This role deploys a K3s cluster. In addition it has the following features:
- _[ToDo-#5](https://gitlab.com/nofusscomputing/projects/ansible/kubernetes/-/issues/5)_ Restore backup on fresh install of a cluster
- Installs OLM for operator subscriptions
- Install MetalLB
## Role Workflow
The roles workflow is as follows
For a more probable than not success this role first installs/configures prime master, other master(s) and worker nodes using the following simplified workflow:
1. Download both install script and k3s binary to ansible controller
@ -40,20 +58,32 @@ The roles workflow is as follows
1. Create required config files needed for installation
1. _(kubernetes prime only)_ Add install required config files
1. _(kubernetes prime master only)_ Add install required config files
1. Install kubernetes
1. _(kubernetes prime master only)_ Wait for kubernetes to be ready. Playbook is paused until `true`
1. Configure Kubernetes
If the playbook is setup as per [our recommendation](ansible.md) step 2 onwards is first done on master nodes then worker nodes.
!!! tip
If you prefer to manually restart the kubernetes service the following variables can be set to prevent a restart of the kubernetes service
``` yaml
nfc_kubernetes_no_restart: false
nfc_kubernetes_no_restart_master: false
nfc_kubernetes_no_restart_prime: false
nfc_kubernetes_no_restart_slave: false
```
_See default variables below for explanation of each variable if it's not evident enough._
## Default Variables
``` yaml title="defaults/main.yaml" linenums="1"
--8<-- "defaults/main.yaml"
--8<-- "defaults/main.yml"
```

View File

@ -0,0 +1,24 @@
---
title: Release Notes
description: No Fuss Computings Ansible role nfc_kubernetes
date: 2024-01-31
template: project.html
about: https://gitlab.com/nofusscomputing/projects/ansible/roles/kubernetes
---
This document details any changes that have occured that may impact users of this role. It's a rolling document and will be amended from time to time.
## Changes with an impact
- _**31 Jan 2024**_ Calico CNI deployment has been migrated to use the calico operator.
- All new cluster installations will be deployed with the operator
- Existing deployments will be required to run a deployment with job tag `operator_migrate_calico` to migrate their deployment to the operator
- if an issue occurs with the migration it can be rolled back by `kubectl delete -f` for all manifests in the `/var/lib/rancher/k3s/ansible` directory and redeploying with job tag `calico_manifest`. This re-deploys calico using the current manifest.
- This tag will be removed in the future at no set date.
- `ServiceLB` / `klipperLB` no longer deploys by default and to deploy it variable `nfc_kubernetes_enable_servicelb` must be set `true`

View File

@ -16,6 +16,38 @@
- name: Restart Kubernetes
ansible.builtin.service:
name: "{% if kubernetes_type == 'k3s' %}k3s{% else %}kubelet{% endif %}"
name: |-
{%- if kubernetes_type == 'k3s' -%}
{%- if Kubernetes_Master | default(false) | bool -%}
k3s
{%- else -%}
k3s-agent
{%- endif -%}
{%- else -%}
kubelet
{%- endif %}
state: restarted
listen: kubernetes_restart
when: |-
not (
nfc_kubernetes_no_restart
or
(
inventory_hostname in groups['kubernetes_master']
and
nfc_kubernetes_no_restart_master
)
or
(
inventory_hostname == kubernetes_config.cluster.prime.name
and
nfc_kubernetes_no_restart_prime
)
or
(
inventory_hostname in groups['kubernetes_worker']
and
nfc_kubernetes_no_restart_slave
)
)

View File

@ -43,6 +43,8 @@ nav:
- projects/ansible/roles/kubernetes/rbac.md
- projects/ansible/roles/kubernetes/release_notes.md
- Operations:

View File

@ -4,29 +4,26 @@
- name: K3s Install
ansible.builtin.include_tasks:
file: k3s/install.yaml
apply:
tags:
- always
when: >
install_kubernetes | default(true) | bool
and
not kubernetes_installed | default(false) | bool
tags:
- always
- name: K3s Configure
ansible.builtin.include_tasks:
file: k3s/configure.yaml
apply:
tags:
- always
when: >
install_kubernetes | default(true) | bool
and
kubernetes_installed | default(false) | bool
- name: Wireguard Cluster Encryption
ansible.builtin.include_tasks:
file: k3s/wireguard.yaml
when: >
install_kubernetes | default(true) | bool
and
kubernetes_installed | default(false) | bool
and
not kubernetes_installed_encryption | default(false) | bool
and
kubernetes_config.cluster.networking.encrypt | default(false) | bool
tags:
- always

View File

@ -1,38 +1,5 @@
---
- name: Local Container Registry
ansible.builtin.copy:
content: |
#
# Private Container Registries for Kubernetes
#
# Managed By ansible/role/nfc_kubernetes
#
# Dont edit this file directly as it will be overwritten.
#
{% set registries = kubernetes_private_container_registry | default([]) -%}
{% if registries | length > 0 %}mirrors:
{% for entry in registries %}
{{ entry.name }}:
endpoint:
- "{{ entry.url }}"
{%- endfor %}
{% endif %}
dest: /etc/rancher/k3s/registries.yaml
owner: root
mode: '700'
# notify: "restart ContainerD"
# with_items: "{{ containerd.repositories }}"
# when:
# ansible_os_family == 'Debian'
# and
# Kubernetes_private_container_registry | default([]) | length > 0
- name: Additional config files
ansible.builtin.copy:
content: |
@ -42,6 +9,7 @@
owner: root
group: root
loop: "{{ k3s.files }}"
when: item.when | default(false) | bool
- name: Copy Templates
@ -53,22 +21,42 @@
force: true
notify: "{{ item.notify | default(omit) }}"
loop: "{{ templates_to_apply }}"
when: >
item.when | default(true) | bool
vars:
templates_to_apply:
- src: "calico.yaml.j2"
dest: /var/lib/rancher/k3s/server/manifests/calico.yaml
- src: kubernetes-manifest-rbac.yaml.j2
dest: /var/lib/rancher/k3s/server/manifests/rbac-authorization-common.yaml
when: "{{ kubernetes_config.cluster.prime.name == inventory_hostname }}"
- src: iptables-kubernetes.rules.j2
dest: "/etc/iptables.rules.d/iptables-kubernetes.rules"
notify: firewall_reloader
- src: k3s-registries.yaml.j2
dest: /etc/rancher/k3s/registries.yaml
notify: kubernetes_restart
- src: k3s-config.yaml.j2
dest: /etc/rancher/k3s/config.yaml
notify: kubernetes_restart
- name: Add Kubernetes Node Labels
ansible.builtin.copy:
content: |-
apiVersion: v1
kind: Node
metadata:
name: "{{ inventory_hostname }}"
{% if kubernetes_config.hosts[inventory_hostname].labels | default([]) | list | length > 0 -%}
labels:
{{ kubernetes_config.hosts[inventory_hostname].labels | to_nice_yaml | indent(4) }}
{%- endif +%}
{% if kubernetes_config.hosts[inventory_hostname].taints | default([]) | list | length > 0 -%}
spec:
taints:
{{ kubernetes_config.hosts[inventory_hostname].taints | to_nice_yaml(indent=0) | indent(4) }}
{% endif %}
dest: /var/lib/rancher/k3s/server/manifests/node-manifest-{{ inventory_hostname }}.yaml
owner: root
group: root
mode: '700'
delegate_to: "{{ kubernetes_config.cluster.prime.name }}"
when:
kubernetes_config.hosts[inventory_hostname].labels | default([]) | list | length > 0
or
kubernetes_config.hosts[inventory_hostname].taints | default([]) | list | length > 0

View File

@ -1,12 +1,70 @@
---
- name: Check for calico deployment manifest
ansible.builtin.stat:
name: /var/lib/rancher/k3s/server/manifests/calico.yaml
become: true
register: file_calico_yaml_metadata
- name: Check for calico Operator deployment manifest
ansible.builtin.stat:
name: /var/lib/rancher/k3s/ansible/deployment-manifest-calico_operator.yaml
become: true
register: file_calico_operator_yaml_metadata
- name: Install Software
ansible.builtin.include_role:
name: nfc_common
vars:
common_gather_facts: false
initial_common_tasks: true # Don't run init tasks
aptInstall:
- name: curl
- name: iptables
- name: jq
- name: wireguard
- name: Remove swapfile from /etc/fstab
ansible.posix.mount:
name: "{{ item }}"
fstype: swap
state: absent
with_items:
- swap
- none
when:
- ansible_os_family == 'Debian' # ansible_lsb.codename = bullseye, ansible_lsb.major_release = 11
tags:
- install
- name: Disable swap
ansible.builtin.command:
cmd: swapoff -a
changed_when: false
when:
- ansible_os_family == 'Debian'
tags:
- install
- name: Check an armbian os system
ansible.builtin.stat:
path: /etc/default/armbian-zram-config
register: armbian_stat_result
- name: Armbian Disable Swap
ansible.builtin.shell:
cmd: |
sed -i 's/\# SWAP=false/SWAP=false/g' /etc/default/armbian-zram-config;
sed -i 's/ENABLED=true/ENABLED=false/g' /etc/default/armbian-zram-config;
args:
executable: bash
changed_when: false
when: armbian_stat_result.stat.exists
- name: Create Required directories
@ -26,19 +84,58 @@
- name: /var/lib/rancher/k3s/server/manifests
state: directory
mode: 700
- name: /var/lib/rancher/k3s/ansible
state: directory
mode: 700
- name: Add sysctl net.ipv4.ip_forward
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
name: "{{ item.name }}"
value: "{{ item.value }}"
sysctl_set: true
state: present
reload: true
notify: reboot_host
loop: "{{ settings }}"
notify: reboot_host # On change reboot
vars:
settings:
- name: net.ipv4.ip_forward
value: '1'
- name: fs.inotify.max_user_watches
value: '524288'
- name: fs.inotify.max_user_instances
value: '512'
when:
- ansible_os_family == 'Debian'
# On change reboot
- name: Check for Network Manager Directory
ansible.builtin.stat:
name: /etc/NetworkManager/conf.d
become: true
register: directory_network_manager_metadata
- name: Network Manager Setup
ansible.builtin.copy:
content: |-
#
# K3s Configuration for Network Manager
#
# Managed By ansible/role/nfc_kubernetes
#
# Dont edit this file directly as it will be overwritten.
#
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
dest: /etc/NetworkManager/conf.d/calico.conf
mode: '770'
owner: root
group: root
become: true
diff: true
when: directory_network_manager_metadata.stat.exists
- name: Check if K3s Installed
@ -51,7 +148,12 @@
register: k3s_installed
- name: Download K3s Binary
- name: Check Machine Architecture
ansible.builtin.set_fact:
nfc_kubernetes_install_architectures: "{{ nfc_kubernetes_install_architectures | default({}) | combine({ansible_architecture: ''}) }}"
- name: Download Install Scripts
ansible.builtin.uri:
url: "{{ item.url }}"
method: GET
@ -61,8 +163,10 @@
- 304
dest: "{{ item.dest }}"
mode: "744"
register: k3s_download_files
changed_when: false
register: k3s_download_script
delegate_to: localhost
run_once: true
# no_log: true
when: ansible_os_family == 'Debian'
loop: "{{ download_files }}"
@ -71,14 +175,46 @@
download_files:
- dest: /tmp/install.sh
url: https://get.k3s.io
- dest: "/tmp/k3s"
url: "https://github.com/k3s-io/k3s/releases/download/v{{ KubernetesVersion + KubernetesVersion_k3s_prefix | urlencode }}/k3s"
- dest: /tmp/install_olm.sh
url: https://raw.githubusercontent.com/operator-framework/operator-lifecycle-manager/v{{ kubernetes_version_olm }}/scripts/install.sh
- name: Download K3s Binary
ansible.builtin.uri:
url: |-
https://github.com/k3s-io/k3s/releases/download/v
{{- KubernetesVersion + KubernetesVersion_k3s_prefix | urlencode -}}
/k3s
{%- if cpu_arch.key == 'aarch64' -%}
-arm64
{%- endif %}
method: GET
return_content: false
status_code:
- 200
- 304
dest: "/tmp/k3s.{{ cpu_arch.key }}"
mode: "744"
changed_when: false
register: k3s_download_files
delegate_to: localhost
run_once: true
# no_log: true
when: ansible_os_family == 'Debian'
loop: "{{ nfc_kubernetes_install_architectures | dict2items }}"
loop_control:
loop_var: cpu_arch
vars:
ansible_connection: local
- name: "[TRACE] Downloaded File SHA256"
ansible.builtin.set_fact:
hash_sha256_k3s_downloaded_binary: "{{ lookup('ansible.builtin.file', '/tmp/k3s') | hash('sha256') | string }}"
hash_sha256_k3s_downloaded_binary: "{{ lookup('ansible.builtin.file', '/tmp/k3s.' + cpu_arch.key) | hash('sha256') | string }}"
delegate_to: localhost
loop: "{{ nfc_kubernetes_install_architectures | dict2items }}"
loop_control:
loop_var: cpu_arch
- name: Existing k3s File hash
@ -90,20 +226,26 @@
- name: Copy K3s binary to Host
ansible.builtin.copy:
src: "/tmp/k3s"
src: "/tmp/k3s.{{ ansible_architecture }}"
dest: "/usr/local/bin/k3s"
mode: '740'
owner: root
group: root
when: hash_sha256_k3s_existing_binary.stat.checksum | default('0') != hash_sha256_k3s_downloaded_binary
- name: Copy install script to Host
- name: Copy install scripts to Host
ansible.builtin.copy:
src: "/tmp/install.sh"
dest: "/tmp/install.sh"
src: "{{ item }}"
dest: "{{ item }}"
mode: '755'
owner: root
group: root
changed_when: false
loop: "{{ install_scripts }}"
vars:
install_scripts:
- "/tmp/install.sh"
- "/tmp/install_olm.sh"
# when: hash_sha256_k3s_existing_binary.stat.checksum | default('0') != hash_sha256_k3s_downloaded_binary
- name: Required Initial config files
@ -116,7 +258,8 @@
group: root
loop: "{{ k3s.files }}"
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
item.when | default(true) | bool
# kubernetes_config.cluster.prime.name == inventory_hostname
- name: Copy Intial required templates
@ -128,13 +271,37 @@
force: true
notify: "{{ item.notify | default(omit) }}"
loop: "{{ templates_to_apply }}"
diff: true
when: >
item.when | default(true) | bool
vars:
templates_to_apply:
- src: k3s-config.yaml.j2
dest: /etc/rancher/k3s/config.yaml
notify: kubernetes_restart
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
- src: "calico.yaml.j2"
dest: /var/lib/rancher/k3s/server/manifests/calico.yaml
when: >
{{
kubernetes_config.cluster.prime.name == inventory_hostname
and
(
(
not file_calico_operator_yaml_metadata.stat.exists
and
file_calico_yaml_metadata.stat.exists
and
k3s_installed.rc == 0
)
or
'calico_manifest' in ansible_run_tags
)
}}
- src: k3s-registries.yaml.j2
dest: /etc/rancher/k3s/registries.yaml
notify: kubernetes_restart
when: "{{ (kubernetes_private_container_registry | default([])) | from_yaml | list | length > 0 }}"
# - name: Templates IPv6
# ansible.builtin.template:
@ -153,36 +320,205 @@
changed_when: false
- name: Server install K3s
ansible.builtin.shell:
cmd: |
# INSTALL_K3S_SKIP_DOWNLOAD=true \
# INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \
# /tmp/install.sh
curl -sfL https://get.k3s.io | \
INSTALL_K3S_VERSION="v1.26.9+k3s1" \
sh -
failed_when: false
# when: >
# k3s_installed.rc | int == 1
# and
# Kubernetes_Master | default(false)
when: Kubernetes_Master | default(false) | bool
- name: Agent install K3s
- name: Install K3s (prime master)
ansible.builtin.shell:
cmd: |
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \
K3S_URL=https://{{ hostvars[kubernetes_config.cluster.prime.name].ansible_host }}:6443 \
K3S_TOKEN={{ node_token }} \
/tmp/install.sh
/tmp/install.sh --cluster-init
changed_when: false
when: >
k3s_installed.rc | int == 1
kubernetes_config.cluster.prime.name == inventory_hostname
and
k3s_installed.rc == 1
- name: Install Calico Operator
ansible.builtin.include_tasks:
file: migrate_to_operator.yaml
apply:
tags:
- always
when: >-
(
(
'operator_migrate_calico' in ansible_run_tags
or
'operator_calico' in ansible_run_tags
)
or
not file_calico_yaml_metadata.stat.exists
)
and
'calico_manifest' not in ansible_run_tags
and
kubernetes_config.cluster.prime.name == inventory_hostname
- name: Install MetalLB Operator
ansible.builtin.include_tasks:
file: manifest_apply.yaml
apply:
tags:
- always
loop: "{{ manifests }}"
loop_control:
loop_var: manifest
vars:
manifests:
- name: MetalLB Operator
template: Deployment-manifest-MetalLB_Operator.yaml
when: >-
nfc_kubernetes_enable_metallb | default(false) | bool
and
kubernetes_config.cluster.prime.name == inventory_hostname
- name: Wait for kubernetes prime to be ready
ansible.builtin.shell:
cmd: |
set -o pipefail
if [ `which jq` ]; then
echo $(kubectl get no $(hostname) -o json | jq .status.conditions[4].status | tr -d '"');
else
echo jq command not found;
exit 127;
fi
executable: /bin/bash
delegate_to: "{{ kubernetes_config.cluster.prime.name }}"
run_once: true
register: kubernetes_ready_check
retries: 30
delay: 10
until: >
kubernetes_ready_check.stdout | default(false) | bool
or
kubernetes_ready_check.rc != 0
changed_when: false
failed_when: kubernetes_ready_check.rc != 0
- name: Install olm
ansible.builtin.shell:
cmd: |
/tmp/install_olm.sh v{{ kubernetes_version_olm }}
changed_when: false
failed_when: >
'already installed' not in install_olm.stdout
and
install_olm.rc == 1
register: install_olm
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
and
kubernetes_olm_install | default(false) | bool
- name: Uninstall OLM
ansible.builtin.shell:
cmd: |
kubectl delete -n olm deployment packageserver;
kubectl delete -n olm deployment catalog-operator;
kubectl delete -n olm deployment olm-operator;
kubectl delete crd catalogsources.operators.coreos.com;
kubectl delete` crd clusterserviceversions.operators.coreos.com;
kubectl delete crd installplans.operators.coreos.com;
kubectl delete crd olmconfigs.operators.coreos.com;
kubectl delete crd operatorconditions.operators.coreos.com;
kubectl delete crd operatorgroups.operators.coreos.com;
kubectl delete crd operators.operators.coreos.com;
kubectl delete crd subscriptions.operators.coreos.com;
kubectl delete namespace operators --force;
kubectl delete namespace olm --force;
changed_when: false
failed_when: false
register: install_olm
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
and
'olm_uninstall' not in ansible_run_tags
- name: Enable Cluster Encryption
ansible.builtin.command:
cmd: kubectl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true,"wireguardEnabledV6":true}}'
changed_when: false
failed_when: false # New cluster will fail
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
and
kubernetes_config.cluster.networking.encrypt | default(false) | bool
and
(
'calico_manifest' in ansible_run_tags
or
(
'operator_migrate_calico' not in ansible_run_tags
or
'operator_calico' not in ansible_run_tags
)
)
- name: Fetch Join Token
ansible.builtin.slurp:
src: /var/lib/rancher/k3s/server/token
delegate_to: "{{ kubernetes_config.cluster.prime.name }}"
run_once: true
register: k3s_join_token
no_log: true # Value is sensitive
- name: Create Token fact
ansible.builtin.set_fact:
k3s_join_token: "{{ k3s_join_token.content | b64decode | replace('\n', '') }}"
delegate_to: "{{ kubernetes_config.cluster.prime.name }}"
run_once: true
no_log: true # Value is sensitive
- name: Install K3s (master nodes)
ansible.builtin.shell:
cmd: |
INSTALL_K3S_EXEC="server" \
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \
K3S_TOKEN="{{ k3s_join_token }}" \
/tmp/install.sh
executable: /bin/bash
changed_when: false
when: >
Kubernetes_Master | default(false) | bool
and
not kubernetes_config.cluster.prime.name == inventory_hostname
and
k3s_installed.rc == 1
- name: Install K3s (worker nodes)
ansible.builtin.shell:
cmd: |
set -o pipefail
INSTALL_K3S_EXEC="agent" \
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \
K3S_TOKEN="{{ k3s_join_token }}" \
K3S_URL="https://{{ hostvars[kubernetes_config.cluster.prime.name].ansible_host }}:6443" \
/tmp/install.sh -
executable: /bin/bash
changed_when: false
when: >
not Kubernetes_Master | default(false) | bool
and
k3s_installed.rc == 1
- name: Set Kubernetes Final Install Fact
ansible.builtin.set_fact:
kubernetes_installed: true
# Clear Token as no llonger required and due to being a sensitive value
k3s_join_token: null
nfc_kubernetes_install_architectures: {}

View File

@ -0,0 +1,49 @@
---
# Save the manifests in a dir so that diff's can be shown for changes
- name: Copy Manifest for addition - {{ manifest.name }}
ansible.builtin.template:
src: "{{ manifest.template }}"
dest: "/var/lib/rancher/k3s/ansible/{{ manifest.template | lower | replace('.j2', '') }}"
mode: '744'
become: true
diff: true
- name: Try / Catch
block:
# Try to create first, if fail use replace.
- name: Apply Manifest Create - {{ manifest.name }}
ansible.builtin.command:
cmd: "kubectl create -f /var/lib/rancher/k3s/ansible/{{ manifest.template | lower | replace('.j2', '') }}"
become: true
changed_when: false
failed_when: >
'Error from server' in manifest_stdout.stderr
register: manifest_stdout
rescue:
- name: TRACE - Manifest Create - {{ manifest.name }}
ansible.builtin.debug:
msg: "{{ manifest_stdout }}"
- name: Replace Manifests - "Rescue" - {{ manifest.name }}
ansible.builtin.command:
cmd: "kubectl replace -f /var/lib/rancher/k3s/ansible/{{ manifest.template | lower | replace('.j2', '') }}"
become: true
changed_when: false
failed_when: >
'Error from server' in manifest_stdout.stderr
and
'ensure CRDs are installed first' in manifest_stdout.stderr
register: manifest_stdout
- name: TRACE - Replace Manifest - "Rescue" - {{ manifest.name }}
ansible.builtin.debug:
msg: "{{ manifest_stdout }}"

View File

@ -0,0 +1,198 @@
---
# Reference https://docs.tigera.io/calico/3.25/operations/operator-migration
# Script creation of imageset: https://docs.tigera.io/calico/latest/operations/image-options/imageset#create-an-imageset
# above may pull sha for arch of machine who ran the script
- name: Try / Catch
vars:
operator_manifests:
- Deployment-manifest-Calico_Operator.yaml.j2
- Installation-manifest-Calico_Cluster.yaml.j2
- FelixConfiguration-manifest-Calico_Cluster.yaml
- IPPool-manifest-Calico_Cluster.yaml.j2
- APIServer-manifest-Calico_Cluster.yaml
- ConfigMap-manifest-Calico_Service_Endpoint.yaml.j2
block:
- name: Move Calico Manifest from addons directory
ansible.builtin.command:
cmd: mv /var/lib/rancher/k3s/server/manifests/calico.yaml /tmp/
become: true
changed_when: false
when: file_calico_yaml_metadata.stat.exists
- name: Remove addon from Kubernetes
ansible.builtin.command:
cmd: kubectl delete addon -n kube-system calico
become: true
changed_when: false
when: file_calico_yaml_metadata.stat.exists
- name: Uninstall Calico
ansible.builtin.command:
cmd: kubectl delete -f /tmp/calico.yaml
become: true
changed_when: false
when: file_calico_yaml_metadata.stat.exists
# Save the manifests in a dir so that diff's can be shown for changes
- name: Copy Manifest for addition
ansible.builtin.template:
src: "{{ item }}"
dest: "/var/lib/rancher/k3s/ansible/{{ item | lower | replace('.j2', '') }}"
mode: '744'
become: true
diff: true
loop: "{{ operator_manifests }}"
- name: Try / Catch
block:
- name: Apply Operator Manifests
ansible.builtin.command:
cmd: "kubectl create -f /var/lib/rancher/k3s/ansible/{{ item | lower | replace('.j2', '') }}"
become: true
changed_when: false
failed_when: >
'Error from server' in operator_manifest_stdout.stderr
loop: "{{ operator_manifests }}"
register: operator_manifest_stdout
rescue:
- name: TRACE - Operator manifest apply
ansible.builtin.debug:
msg: "{{ operator_manifest_stdout }}"
- name: Apply Operator Manifests - "Rescue"
ansible.builtin.command:
cmd: "kubectl replace -f /var/lib/rancher/k3s/ansible/{{ item | lower | replace('.j2', '') }}"
become: true
changed_when: false
failed_when: >
'Error from server' in operator_manifest_stdout.stderr
and
'ensure CRDs are installed first' in operator_manifest_stdout.stderr
loop: "{{ operator_manifests }}"
register: operator_manifest_stdout
- name: TRACE - Operator manifest apply. Rescued
ansible.builtin.debug:
msg: "{{ operator_manifest_stdout }}"
- name: Fetch Calico Kubectl Plugin
ansible.builtin.uri:
url: |-
https://github.com/projectcalico/calico/releases/download/{{ nfc_kubernetes_calico_version }}/calicoctl-linux-
{%- if cpu_arch.key == 'aarch64' -%}
arm64
{%- else -%}
amd64
{%- endif %}
status_code:
- 200
- 304
dest: "/tmp/kubectl-calico.{{ cpu_arch.key }}"
mode: '777'
owner: root
group: 'root'
changed_when: false
become: true
delegate_to: localhost
loop: "{{ nfc_kubernetes_install_architectures | dict2items }}"
loop_control:
loop_var: cpu_arch
vars:
ansible_connection: local
- name: Add calico Plugin
ansible.builtin.copy:
src: "/tmp/kubectl-calico.{{ ansible_architecture }}"
dest: /usr/local/bin/kubectl-calico
mode: '770'
owner: root
group: 'root'
become: true
when: inventory_hostname in groups['kubernetes_master']
- name: Setup Automagic Host Endpoints
ansible.builtin.shell:
cmd: |-
kubectl calico \
patch kubecontrollersconfiguration \
default --patch='{"spec": {"controllers": {"node": {"hostEndpoint": {"autoCreate": "Enabled"}}}}}'
executable: bash
become: true
changed_when: false
failed_when: false # fixme
- name: Remove calico migration label
ansible.builtin.shell:
cmd: |-
kubectl label \
{{ inventory_hostname }} \
projectcalico.org/operator-node-migration-
executable: bash
become: true
delegate_to: "{{ kubernetes_config.cluster.prime.name }}"
changed_when: false
failed_when: false
loop: "{{ groups[kubernetes_config.cluster.group_name] }}"
# kubectl label node ip-10-229-92-202.eu-west-1.compute.internal projectcalico.org/operator-node-migration-
# migration started
rescue:
- name: Remove Operator Manifests
ansible.builtin.command:
cmd: "kubectl delete -f /var/lib/rancher/k3s/ansible/{{ item | lower | replace('.j2', '') }}"
become: true
changed_when: false
failed_when: false
loop: "{{ operator_manifests }}"
when: file_calico_yaml_metadata.stat.exists # Only rescue if it was a migration
- name: Move Calico Manifest from addons directory
ansible.builtin.command:
cmd: mv /tmp/calico.yaml /var/lib/rancher/k3s/server/manifests/
become: true
changed_when: false
when: file_calico_yaml_metadata.stat.exists
- name: Re-install Calico
ansible.builtin.command:
cmd: kubectl apply -f /var/lib/rancher/k3s/server/manifests/calico.yaml
become: true
changed_when: false
when: file_calico_yaml_metadata.stat.exists
always:
- name: Clean-up Temp File
ansible.builtin.file:
name: /tmp/calico.yaml
state: absent
become: true
when: file_calico_yaml_metadata.stat.exists

View File

@ -1,22 +0,0 @@
---
- name: Install Wireguard
ansible.builtin.apt:
name:
- wireguard
update_cache: false
when: >
ansible_os_family == 'Debian'
# and
# kubernetes.networking.encrypt | default(false) | bool
- name: Enable Cluster Encryption
ansible.builtin.command:
cmd: kubectl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true,"wireguardEnabledV6":true}}'
changed_when: false
when: >
kubernetes_config.cluster.prime.name == inventory_hostname
- name: Set Kubernetes Encryption Final Install Fact
ansible.builtin.set_fact:
kubernetes_installed_encryption: true

View File

@ -1,14 +1,38 @@
---
- name: Firewall Rules
ansible.builtin.include_role:
name: nfc_firewall
vars:
nfc_firewall_enabled_kubernetes: "{{ nfc_kubernetes.enable_firewall | default(false) | bool }}"
tags:
- never
- install
# fix, reload firewall `iptables-reloader`
- name: Reload iptables
ansible.builtin.command:
cmd: bash -c /usr/bin/iptables-reloader
changed_when: false
tags:
- never
- install
- name: K8s Cluster
ansible.builtin.include_tasks: k8s.yaml
when: kubernetes_type == 'k8s'
tags:
- never
- install
- name: K3s Cluster
ansible.builtin.include_tasks: k3s.yaml
when: kubernetes_type == 'k3s'
tags:
- never
- install
- operator_calico
- operator_migrate_calico

View File

@ -0,0 +1,6 @@
---
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}

View File

@ -0,0 +1,11 @@
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kubernetes-services-endpoint
namespace: tigera-operator
data:
KUBERNETES_SERVICE_HOST: "
{%- set octet = kubernetes_config.cluster.networking.ServiceSubnet | split('.') -%}
{{- octet[0] }}.{{- octet[1] }}.{{- octet[2] }}.1"
KUBERNETES_SERVICE_PORT: '443'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
---
apiVersion: crd.projectcalico.org/v1
kind: FelixConfiguration
metadata:
name: default
spec:
# bpfConnectTimeLoadBalancing: TCP
# bpfExternalServiceMode: DSR
# bpfHostNetworkedNATWithoutCTLB: Enabled
bpfLogLevel: ""
floatingIPs: Disabled
healthPort: 9099
logSeverityScreen: Info
reportingInterval: 0s
wireguardEnabled: true
wireguardEnabledV6: true

View File

@ -0,0 +1,16 @@
---
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 26
cidr: {{ kubernetes_config.cluster.networking.podSubnet }}
ipipMode: Never
natOutgoing: true
nodeSelector: all()
vxlanMode: Always

View File

@ -0,0 +1,53 @@
---
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
bgp: Disabled
containerIPForwarding: Enabled
hostPorts: Enabled
ipPools:
- blockSize: 26
cidr: {{ kubernetes_config.cluster.networking.podSubnet }}
disableBGPExport: false
encapsulation: VXLAN
natOutgoing: Enabled
nodeSelector: all()
# linuxDataplane: Iptables
linuxDataplane: BPF
mtu: 0
multiInterfaceMode: None
nodeAddressAutodetectionV4:
kubernetes: NodeInternalIP
cni:
ipam:
type: Calico
type: Calico
componentResources:
- componentName: Node
resourceRequirements:
requests:
cpu: 250m
controlPlaneReplicas: 3
flexVolumePath: None
kubeletVolumePluginPath: None
nodeUpdateStrategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
nonPrivileged: Disabled
serviceCIDRs:
- {{ kubernetes_config.cluster.networking.ServiceSubnet }}
typhaDeployment:
spec:
template:
spec:
tolerations:
- effect: NoExecute
key: CriticalAddonsOnly
value: "true"
variant: Calico

View File

@ -1,4 +1,11 @@
---
# Depreciated:
# Calico is being migrated to use the calico operator.
# in a near future release, this method of deploying calico
# will be removed. use tag `operator_migrate_calico` to migrate
# and tag `operator_calico` to keep.
#
#
# URL: https://github.com/projectcalico/calico/blob/8f2548a71ddc4fbe2497a0c20a3b24fc7a165851/manifests/calico.yaml
# Source: calico/templates/calico-kube-controllers.yaml
# This manifest creates a Pod Disruption Budget for Controller to allow K8s Cluster Autoscaler to evict
@ -4774,13 +4781,13 @@ spec:
value: "autodetect"
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
value: "Always"
value: "Never"
# Enable or Disable VXLAN on the default IP pool.
- name: CALICO_IPV4POOL_VXLAN
value: "Never"
value: "Always"
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
value: "Always"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
@ -4815,6 +4822,8 @@ spec:
value: "false"
- name: FELIX_HEALTHENABLED
value: "true"
- name: IP_AUTODETECTION_METHOD
value: kubernetes-internal-ip
securityContext:
privileged: true
resources:
@ -4831,7 +4840,7 @@ spec:
command:
- /bin/calico-node
- -felix-live
- -bird-live
#- -bird-live
periodSeconds: 10
initialDelaySeconds: 10
failureThreshold: 6
@ -4841,7 +4850,7 @@ spec:
command:
- /bin/calico-node
- -felix-ready
- -bird-ready
#- -bird-ready
periodSeconds: 10
timeoutSeconds: 10
volumeMounts:

View File

@ -31,8 +31,9 @@
{%- endif -%}
{%- for kubernetes_host in groups[kubernetes_type] -%}
{%- for kubernetes_host in groups[kubernetes_config.cluster.group_name] -%}
{%- set kubernetes_host = hostvars[kubernetes_host].ansible_host -%}
{%- if kubernetes_host is regex('^[a-z]') and ':' not in kubernetes_host -%} {#- Convert DNs name to IP Address -#}
@ -46,40 +47,48 @@
{%- endif -%}
{%- if kubernetes_host | list | length > 0 -%} {#- Convert dns lookup to list, and select the first item -#}
{%- if
kubernetes_host is iterable
and
kubernetes_host is not string
-%} {#- Convert dns lookup to list, and select the first item -#}
{%- set kubernetes_host = kubernetes_host | from_yaml_all | list -%}
{%- set kubernetes_host = kubernetes_host[0] -%}
{%- set kubernetes_host = kubernetes_host[0] | default('') -%}
{%- endif -%}
{%- endif -%}
{%- if kubernetes_host != '' -%}
{%- for master_host in groups['kubernetes_master'] -%}
{%- if master_host in groups[kubernetes_config.cluster.group_name] -%}
{%- if master_host is regex('^[a-z]') and ':' not in master_host -%} {#- Convert DNs name to IP Address -#}
{%- set master_host = hostvars[master_host].ansible_host -%}
{%- if ipv6 | default(false) -%}
{%- if master_host is regex('^[a-z]') and ':' not in master_host -%} {#- Convert DNs name to IP Address -#}
{%- set master_host = query('community.dns.lookup', master_host + '.', type='AAAA' ) -%}
{%- if ipv6 | default(false) -%}
{%- else -%}
{%- set master_host = query('community.dns.lookup', master_host + '.', type='AAAA' ) -%}
{%- set master_host = query('community.dns.lookup', master_host + '.', type='A' ) -%}
{%- else -%}
{%- set master_host = query('community.dns.lookup', master_host + '.', type='A' ) -%}
{%- endif -%}
{%- if master_host | list | length > 0 -%} {#- Convert dns lookup to list, and select the first item -#}
{%- set master_host = master_host | from_yaml_all | list -%}
{%- set master_host = master_host[0] -%}
{%- endif -%}
{%- endif -%}
{%- if master_host | list | length > 0 -%} {#- Convert dns lookup to list, and select the first item -#}
{%- set master_host = master_host | from_yaml_all | list -%}
{%- set master_host = master_host[0] -%}
{%- endif -%}
{%- endif -%}
{%- if Kubernetes_Master | default(false) | bool -%}
{%- if Kubernetes_Master | default(false) | bool -%}
{%- if
master_host == kubernetes_host
@ -103,12 +112,19 @@
{#- master hosts only -#}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-embedded-etcd -s ' + master_host + ' -j ACCEPT'] -%}
{# {%- set data.firewall_rules = data.firewall_rules + ['-I INPUT -s ' + master_host + ' -p tcp -m multiport --dports 2380 -j ACCEPT'] -%} #}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + master_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-embedded-etcd -s ' + master_host + ' -j ACCEPT'] -%}
{# {%- set data.firewall_rules = data.firewall_rules + ['-I INPUT -s ' + master_host + ' -p tcp -m multiport --dports 2380 -j ACCEPT'] -%} #}
{%- if '-I kubernetes-api -s ' + master_host + ' -j ACCEPT' not in data.firewall_rules -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + master_host + ' -j ACCEPT'] -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
@ -133,65 +149,101 @@
{#- All cluster Hosts -#}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubelet-metrics -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- if Kubernetes_Master | default(false) | bool -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- endif -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-flannel-vxlan -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-kubelet-metrics -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-flannel-wg-four -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-flannel-wg-six -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-calico-bgp -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-calico-typha -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- if nfc_kubernetes_enable_metallb | default(false) -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I metallb-l2-tcp -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I metallb-l2-udp -s ' + kubernetes_host + ' -j ACCEPT'] -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- if Kubernetes_Master | default(false) | bool -%}
{%- for api_client in kubernetes_config.cluster.access | default([]) -%}
{%- if host_external_ip is defined -%}
{%- if api_client is regex('^[a-z]') and ':' not in api_client -%} {#- Convert DNs name to IP Address -#}
{%- set api_client_dns_name = api_client -%}
{%- if ipv6 | default(false) -%}
{%- set api_client = query('community.dns.lookup', api_client + '.', type='AAAA' ) -%}
{%- else -%}
{%- set api_client = query('community.dns.lookup', api_client + '.', type='A' ) -%}
{%- endif -%}
{%- if api_client | list | length > 0 -%} {#- Convert dns lookup to list, and select the first item -#}
{%- set api_client = api_client | from_yaml_all | list -%}
{%- set api_client = api_client[0] -%}
{%- endif -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + host_external_ip + ' -m comment --comment "hosts configured external IP" -j ACCEPT'] -%}
{%- endif -%}
{%- for api_client in kubernetes_config.cluster.access | default([]) -%}
{%- if
api_client != ansible_host
and
(
{%- if api_client is regex('^[a-z]') and ':' not in api_client -%} {#- Convert DNs name to IP Address -#}
{%- set api_client_dns_name = api_client -%}
{%- if ipv6 | default(false) -%}
{%- set api_client = query('community.dns.lookup', api_client + '.', type='AAAA' ) -%}
{%- else -%}
{%- set api_client = query('community.dns.lookup', api_client + '.', type='A' ) -%}
{%- endif -%}
{%- if api_client | list | length > 0 -%} {#- Convert dns lookup to list, and select the first item -#}
{%- set api_client = api_client | from_yaml_all | list -%}
{%- set api_client = api_client[0] -%}
{%- endif -%}
{%- endif -%}
{%- if
api_client != ansible_host
and
(
ipv6 | default(false)
and
':' in api_client
(
ipv6 | default(false)
and
':' in api_client
)
or
(
not ipv6 | default(false)
and
'.' in api_client
)
)
or
(
not ipv6 | default(false)
and
'.' in api_client
)
)
-%}
-%}
{#- Hosts allowed to access API -#}
{#- Hosts allowed to access API -#}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + api_client + ' -m comment --comment "host: ' + api_client_dns_name | default(api_client) + '" -j ACCEPT'] -%}
{%- set data.firewall_rules = data.firewall_rules + ['-I kubernetes-api -s ' + api_client + ' -m comment --comment "host: ' + api_client_dns_name | default(api_client) + '" -j ACCEPT'] -%}
{%- endif -%}
{%- endif -%}
{%- endfor %}
{%- endfor %}
{%- endif %}
*filter

View File

@ -6,24 +6,223 @@
# Dont edit this file directly as it will be overwritten.
#
flannel-backend: none
cluster-cidr: "{{ KubernetesPodSubnet }}"
cluster-init: true
{% if not Kubernetes_Prime | default(false) | bool -%}server: https://{{ hostvars[kubernetes_config.cluster.prime.name].ansible_host }}:6443{% endif %}
service-cidr: "{{ KubernetesServiceSubnet }}"
disable-network-policy: true
disable:
- traefik
kube-apiserver-arg:
- audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log
- audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml
# - admission-control-config-file=/var/lib/rancher/k3s/server/psa.yaml
{% if kubernetes_oidc.enabled | default(false) | bool -%}
- oidc-issuer-url={{ kubernetes_oidc.issuer_url }}
- oidc-client-id={{ kubernetes_oidc.client_id }}
- oidc-username-claim={{ kubernetes_oidc.username_claim }}
{% if kubernetes_oidc.oidc_username_prefix | default('') != '' -%} - oidc-username-prefix={{ kubernetes_oidc.oidc_username_prefix }}{% endif %}
- oidc-groups-claim={{ kubernetes_oidc.groups_claim }}
{% if kubernetes_oidc.groups_prefix | default('') != '' %} - oidc-groups-prefix={{ kubernetes_oidc.groups_prefix }}{% endif %}
{% endif %}
{% if host_external_ip | default('') %} node-external-ip: "{{ host_external_ip }}"{% endif %}
{%- if inventory_hostname in groups['kubernetes_master'] -%}
{%
set kube_apiserver_arg = [
"audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log",
"audit-log-maxage=" + kube_apiserver_arg_audit_log_maxage | string,
"audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml",
]
-%}
{%
set servers_config = {
"cluster-cidr": KubernetesPodSubnet,
"disable": [
"traefik"
],
"disable-network-policy": true,
"etcd-snapshot-retention": kubernetes_etcd_snapshot_retention | int,
"etcd-snapshot-schedule-cron": kubernetes_etcd_snapshot_cron_schedule | string,
"flannel-backend": "none",
"service-cidr": KubernetesServiceSubnet
}
-%}
{%- if
kubernetes_config.cluster.domain_name is defined
and
kubernetes_config.cluster.domain_name | default('') != ''
-%}
{%- set servers_config = servers_config | combine({
"cluster-domain": kubernetes_config.cluster.domain_name
}) -%}
{%- endif -%}
{%- if kubernetes_config.cluster.oidc.enabled | default(false) | bool -%}
{%-
set kube_apiserver_arg = kube_apiserver_arg + [
"oidc-client-id=" + kubernetes_config.cluster.oidc.client_id,
"oidc-groups-claim=" + kubernetes_config.cluster.oidc.groups_claim,
"oidc-issuer-url=" + kubernetes_config.cluster.oidc.issuer_url,
"oidc-username-claim=" + kubernetes_config.cluster.oidc.username_claim
] -%}
{%- if kubernetes_config.cluster.oidc.oidc_username_prefix | default('') != '' -%}
{%- set kube_apiserver_arg = kube_apiserver_arg + [
"oidc-username-prefix=" + kubernetes_config.cluster.oidc.oidc_username_prefix
] -%}
{%- endif -%}
{%- if kubernetes_config.cluster.oidc.groups_prefix | default('') != '' -%}
{%- set kube_apiserver_arg = kube_apiserver_arg + [
"oidc-groups-prefix=" + kubernetes_config.cluster.oidc.groups_prefix
]
-%}
{%- endif -%}
{%- endif -%}
{%- if (
nfc_kubernetes_enable_metallb | default(false)
or
not nfc_kubernetes_enable_servicelb | default(false)
) -%}
{%- set disable = servers_config.disable + [ "servicelb" ] -%}
{%
set servers_config = servers_config | combine({
"disable": disable
})
-%}
{%- endif -%}
{%- if (
not nfc_kubernetes_enable_metallb | default(false)
and
nfc_kubernetes_enable_servicelb | default(false)
) -%}
{%- set servers_config = servers_config | combine({
"servicelb-namespace": kubernetes_config.cluster.networking.service_load_balancer_namespace | default('kube-system')
}) -%}
{%- endif -%}
{# Combine Remaining Server Objects #}
{%
set servers_config = servers_config | combine({
"kube-apiserver-arg": kube_apiserver_arg
})
-%}
{%- endif -%}
{# Eof Server Nodes #}
{# SoF All Nodes #}
{%
set all_nodes_config = {
"kubelet-arg": [
"system-reserved=cpu=" + kubelet_arg_system_reserved_cpu + ",memory=" + kubelet_arg_system_reserved_memory +
",ephemeral-storage=" + kubelet_arg_system_reserved_storage
],
"node-name": inventory_hostname,
}
-%}
{%- if groups[kubernetes_config.cluster.group_name] | default([]) | list | length > 0 -%}
{%- if k3s_installed.rc == 0 -%}
{%- set ns = namespace(server=[]) -%}
{%- for cluster_node in groups[kubernetes_config.cluster.group_name] -%}
{%- if cluster_node in groups['kubernetes_master'] -%}
{%- if hostvars[cluster_node].host_external_ip is defined -%}
{%- if
hostvars[cluster_node].host_external_ip != ansible_default_ipv4.address
and
cluster_node == inventory_hostname
-%} {# Server self, use internal ip if external ip exists #}
{%- set server_node = ansible_default_ipv4.address -%}
{%- else -%}
{%- set server_node = hostvars[cluster_node].host_external_ip -%}
{%- endif -%}
{%- else -%}
{%- set server_node = hostvars[cluster_node].ansible_host -%}
{%- endif -%}
{%- set ns.server = (ns.server | default([])) + [
"https://" + server_node + ":6443"
] -%}
{%- endif -%}
{%- endfor -%}
{%- set all_nodes_config = all_nodes_config | combine({
"server": ns.server,
}) -%}
{%- elif
kubernetes_config.cluster.prime.name != inventory_hostname
and
k3s_installed.rc == 1
-%}
{%- set server = (server | default([])) + [
"https://" + hostvars[kubernetes_config.cluster.prime.name].ansible_host + ":6443"
] -%}
{%- set all_nodes_config = all_nodes_config | combine({
"server": server,
}) -%}
{%- endif -%}
{%- endif -%}
{%- if
host_external_ip is defined
and
ansible_default_ipv4.address != host_external_ip
-%}
{%- set all_nodes_config = all_nodes_config | combine({
"node-external-ip": host_external_ip
}) -%}
{%- else -%}
{%- set all_nodes_config = all_nodes_config | combine({
"node-ip": ansible_default_ipv4.address
}) -%}
{%- endif -%}
{# EoF All Nodes #}
{%- if inventory_hostname in groups['kubernetes_master'] -%}
{%- set servers_config = servers_config | combine( all_nodes_config ) -%}
{{ servers_config | to_nice_yaml(indent=2) }}
{%- else -%}
{{ all_nodes_config | to_nice_yaml(indent=2) }}
{%- endif -%}

View File

@ -90,16 +90,14 @@ metadata:
app.kubernetes.io/version: ''
name: authorization:namespace:owner
rules:
- apiGroups: # Read-only access to resrouces
- apiGroups: # Read-Write access to resrouces
- "*"
resources:
- awx
- cronjobs
- daemonset
- deployments
- helmcharts
- helmchartconfigs
- ingress
- jobs
- pods
- pvc
@ -109,7 +107,6 @@ rules:
- serviceaccount
- services
- statefuleset
- storageclasses
- configmap
verbs:
- create
@ -117,6 +114,49 @@ rules:
- list
- watch
- delete
- apiGroups: # Read-Remove access
- "*"
resources:
- ingress
verbs:
- get
- list
- watch
- delete
- apiGroups: # Read access
- "*"
resources:
- storageclasses
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
authorization/description: |-
Provide access for adding/editing/removing Ingress'.
This role is designed for a user who is responsible for the
cluster ingress.
authorization/target: namespace
name: authorization:cluster:ingress-admin
rules:
- apiGroups:
- "*"
resources:
- pods
- nodes
verbs:
- create
- get
- list
- watch
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
@ -171,6 +211,20 @@ subjects:
- kind: Group
name: technician
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: authorization:ingress-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: authorization:cluster:ingress-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: administrators
# ---
# kind: ClusterRoleBinding