diff --git a/.ansible-lint b/.ansible-lint index 327f909..02a3822 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,2 +1,4 @@ +--- + skip_list: - '106' diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..7891547 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,54 @@ +--- +name: Bug report +about: Create a report to help us improve +--- + + + + +### Summary + + + +### Issue Type + +- Bug Report + +### Controller Environment and Configuration + + + + + +```text + +``` + + +### Steps to Reproduce + + + + + +```yaml + +``` + +### Expected Result + + + +```text + +``` + +### Actual Result + + + + + +```text + +``` diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8b76b04 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,3 @@ +--- + +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d3f15a6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,33 @@ +--- +name: Feature request +about: Suggest an idea for this project +--- + + + + +### Summary + + + +### Issue Type + +- Feature Request + +### User Story + + + + +_As a_ \ +_I want to_ \ +_So that_ + +### Additional Information + + + + +```yaml + +``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..292df4a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,37 @@ +## TITLE + +### Summary + + + + + +### Issue type + + +- Bugfix +- Documentation +- Feature + +### Test instructions + + + +### Acceptance Criteria + + + + + +### Additional Information + + + + + +```text + +``` diff --git a/.gitignore b/.gitignore index 5b9289d..f76aefa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ vagramt/fetch vagrant/ubuntu-*.log __pycache__ ansible.cfg +pyratlabs-issue-dump.txt diff --git a/.travis.yml b/.travis.yml index c96143f..7364f0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,40 +13,35 @@ env: - MOLECULE_SCENARIO: default matrix: - MOLECULE_DISTRO: geerlingguy/docker-debian10-ansible:latest + - MOLECULE_DISTRO: geerlingguy/docker-ubuntu2004-ansible:latest # Test installing docker - MOLECULE_DISTRO: geerlingguy/docker-centos7-ansible:latest - MOLECULE_PLAYBOOK: playbook-docker.yml + MOLECULE_SCENARIO: docker - MOLECULE_DISTRO: geerlingguy/docker-ubuntu1804-ansible:latest - MOLECULE_PLAYBOOK: playbook-docker.yml + MOLECULE_SCENARIO: docker - MOLECULE_DISTRO: geerlingguy/docker-amazonlinux2-ansible:latest - MOLECULE_PLAYBOOK: playbook-docker.yml - - # Test using alternate port and using wireguard as the flannel backend - - MOLECULE_DISTRO: geerlingguy/docker-centos7-ansible:latest - MOLECULE_PLAYBOOK: playbook-docker-altport-wireguard.yml + MOLECULE_SCENARIO: docker # Test disabling all deployments - MOLECULE_DISTRO: geerlingguy/docker-fedora31-ansible:latest - MOLECULE_PLAYBOOK: playbook-no-deploy.yml + MOLECULE_SCENARIO: nodeploy - # Test multiple controllers in control plane with PostgreSQL + # Test multiple control nodes in control plane with PostgreSQL - MOLECULE_DISTRO: geerlingguy/docker-fedora29-ansible:latest - MOLECULE_SCENARIO: highavailability + MOLECULE_SCENARIO: highavailabilitydb - # Test multiple controllers with auto deploying manifests + # Test multiple control nodes with auto deploying manifests - MOLECULE_DISTRO: geerlingguy/docker-fedora30-ansible:latest - MOLECULE_SCENARIO: highavailability - MOLECULE_PLAYBOOK: playbook-auto-deploying-manifests.yml + MOLECULE_SCENARIO: autodeploy - # Test multiple controllers in control plane with Etcd + # Test multiple control nodes in control plane with Etcd - MOLECULE_DISTRO: geerlingguy/docker-centos8-ansible:latest - MOLECULE_SCENARIO: highavailability - MOLECULE_PLAYBOOK: playbook-etcd.yml + MOLECULE_SCENARIO: highavailabilityetcd install: # Install test dependencies. - - pip install molecule[docker] docker jmespath ansible-lint + - pip install -r molecule/requirements.txt before_script: # Use actual Ansible Galaxy role name for the project directory. diff --git a/.yamllint b/.yamllint index 60ffbc3..8827676 100644 --- a/.yamllint +++ b/.yamllint @@ -1,5 +1,5 @@ --- - +# Based on ansible-lint config extends: default rules: @@ -9,5 +9,25 @@ rules: brackets: max-spaces-inside: 1 level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable truthy: disable diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..045141c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Change Log + + + +## 2020-11-29, v2.0.0 + +### Notable changes + + - #64 - Initial release of v2.0.0 of + [ansible-role-k3s](https://github.com/PyratLabs/ansible-role-k3s). + - Minimum supported k3s version now: v1.19.1+k3s1 + - Minimum supported Ansible version now: v2.10.0 + - #62 - Remove all references to the word "master". + - #53 - Move to file-based configuration. + - Refactored to avoid duplication in code and make contribution easier. + - Validation checks moved to using variables defined in `vars/` + +### Breaking changes + +#### File based configuration + +Issue #53 + +With the release of v1.19.1+k3s1, this role has moved to file-based +configuration of k3s. This requires manuall translation of v1 configuration +variables into configuration file format. + +Please see: https://rancher.com/docs/k3s/latest/en/installation/install-options/#configuration-file + +#### Minimum supported k3s version + +As this role now relies on file-based configuration, the v2.x release of this +role will only support v1.19+ of k3s. If you are not in a position to update +k3s you will need to continue using the v1.x release of this role, which will +be supported until March 2021. + +#### Minimum supported ansible version + +This role now only supports Ansible v2.10+, this is because it has moved on to +using FQDNs, with the exception of `set_fact` tasks which have +[been broken](https://github.com/ansible/ansible/issues/72319) and the fixes +have [not yet been backported to v2.10](https://github.com/ansible/ansible/pull/71824). + +The use of FQDNs allows for custom modules to be introduced to override task +behavior. If this role requires a custom ansible module to be introduced then +this can be added as a dependency and targeted specifically by using the +correct FQDN. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..da7f6ac --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,46 @@ +# Contribution Guidelines + +Thank you for taking time to contribute to this Ansible role. + +There are a number of ways that you can contribute to this project, not all of +them requiring you to be able to write code. Below is a list of suggested +contributions welcomed by the community: + + - Submit bug reports in GitHub issues + - Comment on bug reports with futher information or suggestions + - Suggest new features + - Create Pull Requests fixing bugs or adding new features + - Update and improve documentation + - Review the role on Ansible Galaxy + - Write a blog post reviewing the role + - Sponsor me. + +## Issue guidelines + +Issues are the best way to capture an bug in the role, or suggest new features. +This is due to issues being visible to the entire community and allows for +other contributors to pick up the work, so is a better communication medium +than email. + +A good bug issue will include as much information as possible about the +environment Ansible is running in, as well as the role configuration. If there +are any relevant pieces of documentation from upstream projects, this should +be included. + +New feature requests are also best captured in issues, these should include +as much relevant information as possible and if possible include a "user story" +(don't sweat if you don't know how to write one). If there are any relevant +pieces of documentation from upstream projects, this should be included. + +## Pull request guidelines + +PRs should only contain 1 issue fix at a time to limit the scope of testing +required. The smaller the scope of the PR, the easier it is for it to be +reviewed. + +PRs should include the keyword `Fixes` before an issue number if the PR will +completely close the issue. This is because automation will close the issue +once the PR is merged. + +PRs are preferred to be merged in as a single commit, so rebasing before +pushing is recommended, however this isn't a strict rule. diff --git a/README.md b/README.md index 190ed72..cdc4e06 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,23 @@ -# Ansible Role: k3s (v1.x) +# Ansible Role: k3s (v2.x) Ansible role for installing [Rancher Labs k3s](https://k3s.io/) ("Lightweight Kubernetes") as either a standalone server or cluster. -[![Build Status](https://www.travis-ci.org/PyratLabs/ansible-role-k3s.svg?branch=main)](https://www.travis-ci.org/PyratLabs/ansible-role-k3s) +[![Build Status](https://www.travis-ci.org/PyratLabs/ansible-role-k3s.svg?branch=master)](https://www.travis-ci.org/PyratLabs/ansible-role-k3s) + +## Release notes + +Please see [CHANGELOG.md](CHANGELOG.md). ## Requirements The host you're running Ansible from requires the following Python dependencies: - - - - `jmespath >= 0.9.0` + - `ansible >= 2.10` + - `jmespath >= 0.10.0` + +You can install dependencies using the requirements.txt file in this repository: +`pip3 install -r requirements.txt`. This role has been tested against the following Linux Distributions: @@ -29,87 +35,128 @@ This role has been tested against the following Linux Distributions: - Ubuntu 18.04 LTS - Ubuntu 20.04 LTS - - +:warning: The v2 releases of this role only supports `k3s >= v1.19`, for +`k3s < v1.19` please consider updating or use the v1.x releases of this role. + +Before upgrading, see [CHANGELOG](CHANGELOG.md) for breaking chnages. ## Disclaimer -Rancher Labs is awesome and has released k3s as v1.0.0, however at the time of -creating this role I do not have a k3s cluster in production nor am I unlikely -to ever have one. Please ensure you practice extreme caution and operational -rigor before using this role for any serious workloads. +Rancher Labs is awesome and k3s is being used in production, however at the +time of creating this role I do not have a k3s cluster in production nor am I +likely to ever have one. Please ensure you practice extreme caution and +operational rigor before using this role for any serious workloads. If you have any problems please create a GitHub issue, I maintain this role in my spare time so I cannot promise a speedy fix delivery. ## Role Variables -### Group Variables +Since K3s [v1.19.1+k3s1](https://github.com/rancher/k3s/releases/tag/v1.19.1%2Bk3s1) +you can now configure K3s using a +[configuration file](https://rancher.com/docs/k3s/latest/en/installation/install-options/#configuration-file) +rather than environment variables or command line arguments. The v2 release of +this role has moved to the configuration file method rather than populating a +systemd unit file with command-line arguments. There may be exceptions that are +defined in [Group/Cluste Variables](#group-cluster-variables), however you will +be configuring k3s by configuration files using the `k3s_server` and `k3s_agent` +variables. + +See "_Server (Control Plane) Configuration_" and "_Agent (Worker) Configuraion_" +below. + +### Group/Cluster Variables Below are variables that are set against all of the play hosts for environment -consistency. +consistency. These are generally cluster-level configuration. -| Variable | Description | Default Value | -|------------------------------------------|-------------------------------------------------------------------------------------|--------------------------------------------| -| `k3s_cluster_state` | State of cluster: installed, started, stopped, restarted, downloaded, uninstalled. | installed | -| `k3s_release_version` | Use a specific version of k3s, eg. `v0.2.0`. Specify `false` for stable. | `false` | -| `k3s_build_cluster` | When multiple `play_hosts` are available, attempt to cluster. Read notes below. | `true` | -| `k3s_github_url` | Set the GitHub URL to install k3s from. | https://github.com/rancher/k3s | -| `k3s_skip_validation` | Skip all tasks that validate configuration. | `false` | -| `k3s_install_dir` | Installation directory for k3s. | `/usr/local/bin` | -| `k3s_install_hard_links` | Install using hard links rather than symbolic links. | `false` | -| `k3s_server_manifests_dir` | Path for place the `k3s_server_manifests_templates`. | `/var/lib/rancher/k3s/server/manifests` | -| `k3s_server_manifests_templates` | A list of Auto-Deploying Manifests Templates. | [] | -| `k3s_use_experimental` | Allow the use of experimental features in k3s. | `false` | -| `k3s_use_unsupported_config` | Allow the use of unsupported configurations in k3s. | `false` | -| `k3s_non_root` | Install k3s as non-root user. See notes below. | `false` | -| `k3s_cluster_cidr` | Network CIDR to use for pod IPs | 10.42.0.0/16 | -| `k3s_service_cidr` | Network CIDR to use for service IPs | 10.43.0.0/16 | -| `k3s_control_node_address` | Use a specific control node address. IP or FQDN. | _NULL_ | -| `k3s_control_token` | Use a specific control token, please read notes below. | _NULL_ | -| `k3s_private_registry` | Private registry configuration file (default: "/etc/rancher/k3s/registries.yaml") | _NULL_ | -| `k3s_https_port` | HTTPS port listening port. | 6443 | -| `k3s_use_docker` | Use Docker rather than Containerd? | `false` | -| `k3s_no_flannel` | Do not use Flannel | `false` | -| `k3s_flannel_backend` | Flannel backend ('none', 'vxlan', 'ipsec', 'host-gw' or 'wireguard') | vxlan | -| `k3s_no_coredns` | Do not use CoreDNS | `false` | -| `k3s_cluster_dns` | Cluster IP for CoreDNS service. Should be in your service-cidr range. | _NULL_ | -| `k3s_cluster_domain` | Cluster Domain. | cluster.local | -| `k3s_resolv_conf` | Kubelet resolv.conf file | _NULL_ | -| `k3s_no_traefik` | Do not use Traefik | `false` | -| `k3s_no_servicelb` | Do not use ServiceLB, necessary for using something like MetalLB. | `false` | -| `k3s_no_local_storage` | Do not use Local Storage | `false` | -| `k3s_default_local_storage_path` | Set Local Storage Path. Specify `false` for default. | `false` | -| `k3s_no_metrics_server` | Do not deploy metrics server | `false` | -| `k3s_kube_apiserver_args` | Customized flag for kube-apiserver process | [] | -| `k3s_kube_scheduler_args` | Customized flag for kube-scheduler process | [] | -| `k3s_kube_controller_manager_args` | Customized flag for kube-controller-manager process | [] | -| `k3s_kube_cloud_controller_manager_args` | Customized flag for kube-cloud-controller-manager process | [] | -| `k3s_disable_scheduler` | Disable Kubernetes default scheduler | `false` | -| `k3s_disable_cloud_controller` | Disable k3s default cloud controller manager. | `false` | -| `k3s_disable_network_policy` | Disable k3s default network policy controller. | `false` | -| `k3s_disable_kube_proxy` | Disable k3s default kube proxy. | `false` | -| `k3s_write_kubeconfig_mode` | Define the file mode from the generated KubeConfig, eg. `644` | _NULL_ | -| `k3s_datastore_endpoint` | Define the database or etcd cluster endpoint for HA. | _NULL_ | -| `k3s_datastore_cafile` | Define the database TLS CA file. | _NULL_ | -| `k3s_datastore_certfile` | Define the database TLS Cert file. | _NULL_ | -| `k3s_datastore_keyfile` | Define the database TLS Key file. | _NULL_ | -| `k3s_become_for_all` | Enable become for all (where value for `k3s_become_for_*` is _NULL_ | `false` | -| `k3s_become_for_systemd` | Enable become for systemd commands. | _NULL_ | -| `k3s_become_for_install_dir` | Enable become for writing to `k3s_install_dir`. | _NULL_ | -| `k3s_become_for_usr_local_bin` | Enable become for writing to `/usr/local/bin/`. | _NULL_ | -| `k3s_become_for_package_install` | Enable become for installing prerequisite packages. | _NULL_ | -| `k3s_become_for_kubectl` | Enable become for kubectl commands. | _NULL_ | -| `k3s_become_for_uninstall` | Enable become for running uninstall scripts. | _NULL_ | -| `k3s_etcd_datastore` | Use Embedded Etcd as the database backend for HA. (EXPERIMENTAL) | `false` | -| `k3s_etcd_disable_snapshots` | Disable Etcd snapshots. | `false` | -| `k3s_etcd_snapshot_schedule_cron` | Etcd snapshot cron schedule. | "`* */12 * * *`" | -| `k3s_etcd_snapshot_retention` | Etcd snapshot retention. | 5 | -| `k3s_etcd_snapshot_directory` | Etcd snapshot directory. | `/var/lib/rancher/k3s/server/db/snapshots` | -| `k3s_secrets_encryption` | Use secrets encryption at rest. (EXPERIMENTAL) | `false` | -| `k3s_debug` | Enable debug logging on the k3s service | `false` | -| `k3s_enable_selinux` | Enable SELinux in containerd. (EXPERIMENTAL) | `false` | +| Variable | Description | Default Value | +|----------------------------------|---------------------------------------------------------------------------------|-----------------------------------------| +| `k3s_state` | State of k3s: installed, started, stopped, downloaded, uninstalled, validated. | installed | +| `k3s_release_version` | Use a specific version of k3s, eg. `v0.2.0`. Specify `false` for stable. | `false` | +| `k3s_config_file` | Loction of the k3s configuration file. | `/etc/rancher/k3s/config.yaml` | +| `k3s_build_cluster` | When multiple `play_hosts` are available, attempt to cluster. Read notes below. | `true` | +| `k3s_control_node_address` | Use a specific control node address. IP or FQDN. | NULL | +| `k3s_github_url` | Set the GitHub URL to install k3s from. | https://github.com/rancher/k3s | +| `k3s_skip_validation` | Skip all tasks that validate configuration. | `false` | +| `k3s_install_dir` | Installation directory for k3s. | `/usr/local/bin` | +| `k3s_install_hard_links` | Install using hard links rather than symbolic links. | `false` | +| `k3s_server_manifests_dir` | Path for place the `k3s_server_manifests_templates`. | `/var/lib/rancher/k3s/server/manifests` | +| `k3s_server_manifests_templates` | A list of Auto-Deploying Manifests Templates. | [] | +| `k3s_use_experimental` | Allow the use of experimental features in k3s. | `false` | +| `k3s_use_unsupported_config` | Allow the use of unsupported configurations in k3s. | `false` | +| `k3s_etcd_datastore` | Enable etcd embedded datastore (EXPERIMENTAL, read notes below). | `false` | +| `k3s_debug` | Enable debug logging on the k3s service. | `false` | + +### Ansible Controller Configuration Variables + +The below variables are used to change the way the role executes in Ansible, +particularly with regards to privilege escalation. + +| Variable | Description | Default Value | +|----------------------------------|---------------------------------------------------------------------|---------------| +| `k3s_become_for_all` | Escalate user privileges for all tasks. Overrides all of the below. | `false` | +| `k3s_become_for_systemd` | Escalate user privileges for systemd tasks. | NULL | +| `k3s_become_for_install_dir` | Escalate user privileges for creating installation directories. | NULL | +| `k3s_become_for_usr_local_bin` | Escalate user privileges for writing to `/usr/local/bin`. | NULL | +| `k3s_become_for_package_install` | Escalate user privileges for installing k3s. | NULL | +| `k3s_become_for_kubectl` | Escalate user privileges for running `kubectl`. | NULL | +| `k3s_become_for_uninstall` | Escalate user privileges for uninstalling k3s. | NULL | + +### Server (Control Plane) Configuration + +The control plane is configured with the `k3s_server` dict variable. Please +refer to the below documentation for configuration options: + +https://rancher.com/docs/k3s/latest/en/installation/install-options/server-config/ + +The `k3s_server` dictionary variable will contain flags from the above +(removing the `--` prefix). Below is an example: + +```yaml +k3s_server: + datastore-endpoint: postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable + docker: true + cluster-cidr: 172.20.0.0/16 + flannel-backend: 'none' # This needs to be in quotes + disable: + - traefik + - coredns +``` + +Alternatively, you can create a .yaml file and read it in to the `k3s_server` +variable as per the below example: + +```yaml +k3s_server: "{{ lookup('file', 'path/to/k3s_server.yml') | from_yaml }}" +``` + +See examples + +### Agent (Worker) Configuraion + +Workers are configured with the `k3s_agent` dict variable. Please refer to the +below documentation for configuration options: + +https://rancher.com/docs/k3s/latest/en/installation/install-options/agent-config + +The `k3s_agent` dictionary variable will contain flags from the above +(removing the `--` prefix). Below is an example: + +```yaml +k3s_agent: + with-node-id: true + node-label: + - "foo=bar" + - "hello=world" +``` + +Alternatively, you can create a .yaml file and read it in to the `k3s_agent` +variable as per the below example: + +```yaml +k3s_agent: "{{ lookup('file', 'path/to/k3s_agent.yml') | from_yaml }}" +``` #### Important note about `k3s_release_version` @@ -118,7 +165,7 @@ channel of k3s will be installed. If you are developing against a specific version of k3s you must ensure this is set in your Ansible configuration, eg: ```yaml -k3s_release_version: v1.16.9+k3s1 +k3s_release_version: v1.19.3+k3s1 ``` It is also possible to install specific K3s "Channels", below are some @@ -128,12 +175,11 @@ examples for `k3s_release_version`: k3s_release_version: false # defaults to 'stable' channel k3s_release_version: stable # latest 'stable' release k3s_release_version: testing # latest 'testing' release -k3s_release_version: v1.18 # latest v1.18 release -k3s_release_version: v1.17-testing # latest v1.17 testing release -k3s_release_version: v1.19.2-k3s1 # specific release +k3s_release_version: v1.19 # latest 'v1.19' release +k3s_release_version: v1.19.3+k3s3 # specific release -# specific commit -# caution - only used for tesing - must be 40 characters +# Specific commit +# CAUTION - only used for tesing - must be 40 characters k3s_release_version: 48ed47c4a3e420fa71c18b2ec97f13dc0659778b ``` @@ -195,66 +241,24 @@ a cluster of 25 nodes. To do this we'd use a playbook similar to the below: - xanmanning.k3s ``` -#### Important note about `k3s_non_root` - -To install k3s as non root you must not use `become: true`. The intention of -this variable is to run a single node development environment. At the time -of release v1.0.1, rootless is still experimental. - -You must also ensure that you set both `k3s_use_experimental` -and `k3s_use_unsupported_config` to `true`. - -Additionally `k3s_install_dir` must be writable by your user. - -#### Important notes about `k3s_control_node_address` and `k3s_control_token` - -If you set this, you are explicitly specifying the control host that agents -should connect to, the value should be an IP address or FQDN. - -If the control host is not configured by this role, then you need to also -specify the `k3s_control_token`. - -Please note that this may potentially break setting up agents. - -### Host Variables - -Below are variables that are set against specific hosts in your inventory. - -| Variable | Description | Default Value | -|-----------------------------|----------------------------------------------------------------------------------|------------------------| -| `k3s_control_node` | Define the host as a control plane node, (True/False). | `false` | -| `k3s_node_name` | Define the name of this node. | `$(hostname)` | -| `k3s_node_id` | Define the ID of this node. | _NULL_ | -| `k3s_flannel_interface` | Define the flannel proxy interface for this node. | _NULL_ | -| `k3s_advertise_address` | Define the advertise address for this node. | _NULL_ | -| `k3s_bind_address` | Define the bind address for this node. | localhost | -| `k3s_node_ip_address` | IP Address to advertise for this node. | _NULL_ | -| `k3s_node_external_address` | External IP Address to advertise for this node. | _NULL_ | -| `k3s_node_labels` | List of node labels. | _NULL_ | -| `k3s_kubelet_args` | A list of kubelet args to pass to the server. | [] | -| `k3s_kube_proxy_args` | A list of kube proxy args to pass to the server. | [] | -| `k3s_node_taints` | List of node taints. | _NULL_ | -| `k3s_node_data_dir` | Folder to hold state. | `/var/lib/rancher/k3s` | -| `k3s_tls_san` | A list of additional hosnames or IPs as Subject Alternate Name in the TLS cert. | [] | - #### Important note about `k3s_control_node` and High Availability (HA) By default only one host will be defined as a control node by Ansible, If you do not set a host as a control node, this role will automatically delegate -the first play host as a primary control node. This is not suitable for use in +the first play host as a control node. This is not suitable for use within a Production workload. -If multiple hosts have `k3s_control_node` set to true, you must also set -`k3s_datastore_endpoint` as the connection string to a MySQL or PostgreSQL -database, or external Etcd cluster else the play will fail. +If multiple hosts have `k3s_control_node` set to `true`, you must also set +`datastore-endpoint` in `k3s_server` as the connection string to a MySQL or +PostgreSQL database, or external Etcd cluster else the play will fail. If using TLS, the CA, Certificate and Key need to already be available on the play hosts. See: [High Availability with an External DB](https://rancher.com/docs/k3s/latest/en/installation/ha/) -It is also possible, though not supported, to run a single K3s control node with a -`k3s_datastore_endpoint` defined. As this is not a typically supported +It is also possible, though not supported, to run a single K3s control node +with a `datastore-endpoint` defined. As this is not a typically supported configuration you will need to set `k3s_use_unsupported_config` to `true`. Since K3s v1.19.1 it is possible to use Etcd as the backend database, and this @@ -266,83 +270,29 @@ ensure a majority in the event of a network partition. If you want to use 2 members or an even number of members, please set `k3s_use_unsupported_config` to `true`. -#### Important note about `k3s_flannel_interface` - -If you are running k3s on systems with multiple network interfaces, it is -necessary to have the flannel interface on a network interface that is routable -to the control plane node(s). - -#### Notes about `_args`, `_labels` and `_taints` variables - -Affected variables: - - - `k3s_kube_apiserver_args` - - `k3s_kube_scheduler_args` - - `k3s_kube_controller_manager_args` - - `k3s_kube_cloud_controller_manager_args` - - `k3s_kubelet_args` - - `k3s_kube_proxy_args` - -These parameters allow for assigning additional args to K3s during runtime. -For instance, to use the Azure Cloud Controller, assign the below to -the control node's configuration in your host file. - -**YAML**: - -```yaml -k3s_kubelet_args: - - cloud-provider: external - - provider-id: azure -``` - -_Note, when using an external cloud controller as above, ensure that the native -k3s cloud controller is disabled by setting the_ `k3s_disable_cloud_controller` -_to_ `true`. - -Ultimately these variables are lists of key-value pairs that will be iterated -on. The below example will output the following: - -**YAML**: - -```yaml -k3s_node_labels: - - foo: bar - - hello: world - -k3s_node_taints: - - key1: value1:NoExecute -``` - -**K3S ARGS**: - -```text ---node-label foo=bar \ ---node-label hello=world \ ---node-taint key1=value1:NoExecute -``` - ## Dependencies No dependencies on other roles. ## Example Playbooks -Example playbook, single control node running v0.10.2: +Example playbook, single control node running `testing` channel k3s: ```yaml - hosts: k3s_nodes roles: - - { role: xanmanning.k3s, k3s_release_version: v0.10.2 } + - { role: xanmanning.k3s, k3s_release_version: testing } ``` -Example playbook, Highly Available running the latest release: +Example playbook, Highly Available with PostgreSQL database running the latest +stable release: ```yaml - hosts: k3s_nodes vars: - molecule_is_test: true - k3s_control_node_address: loadbalancer - k3s_datastore_endpoint: "postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable" + k3s_control_node_address: loadbalancer # Typically a load balancer. + k3s_server: + datastore-endpoint: "postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable" pre_tasks: - name: Set each node to be a control node set_fact: @@ -356,6 +306,15 @@ Example playbook, Highly Available running the latest release: [BSD 3-clause](LICENSE.txt) +## Contributors + +Contributions from the community are very welcome, but please read the +[contributing guidelines](CONTRIBUTING.md) before doing so, this will help +make things as streamlined as possible. + +Also, please check out the awesome +[list of contributors](https://github.com/PyratLabs/ansible-role-k3s/graphs/contributors). + ## Author Information [Xan Manning](https://xan.manning.io/) diff --git a/defaults/main.yml b/defaults/main.yml index d823b49..534dfd8 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,13 +1,20 @@ --- -# k3s cluster state, options: installed, started, stopped, restarted, uninstalled +## +# Global/Cluster Configuration +## + +# k3s state, options: installed, started, stopped, restarted, uninstalled, validated # (default: installed) -k3s_cluster_state: installed +k3s_state: installed # Use a specific k3s version, if set to "false" we will get the latest -# k3s_release_version: v0.1.0 +# k3s_release_version: v1.19.3 k3s_release_version: false +# Loction of the k3s configuration file +k3s_config_file: /etc/rancher/k3s/config.yaml + # When multiple play_hosts are present, attempt to cluster the nodes. # Using false will create multiple standalone nodes. # (default: true) @@ -25,10 +32,6 @@ k3s_install_dir: /usr/local/bin # Install using hard links rather than symbolic links k3s_install_hard_links: false -# Path for additional Kubernetes Manifests -# https://rancher.com/docs/k3s/latest/en/advanced/#auto-deploying-manifests -k3s_server_manifests_dir: /var/lib/rancher/k3s/server/manifests - # A list of templates used for preconfigure the cluster. k3s_server_manifests_templates: [] @@ -38,97 +41,33 @@ k3s_use_experimental: false # Allow for unsupported configurations in k3s? k3s_use_unsupported_config: false -# Use a database or etcd cluster to enable HA. Examples below: -# MySQL: -# k3s_datastore_endpoint "mysql://username:password@tcp(hostname:3306)/database-name" -# PostgreSQL: -# k3s_datastore_endpoint: "postgres://username:password@hostname:port/database-name" -# Etcd: -# k3s_datastore_endpoint: "https://etcd-host-1:2379,https://etcd-host-2:2379,https://etcd-host-3:2379" -k3s_datastore_endpoint: false - -# If using a database endpoint for HA, you can optionally set the CA file, -# Cert file and Key file for connecting to the database using TLS. -# -# These need to already be present on the play hosts. -# -# k3s_datastore_cafile: /path/to/ca.crt -# k3s_datastore_certfile: /path/to/cert.crt -# k3s_datastore_keyfile: /path/to/key.pem - -# Use embedded Etcd for HA Datastore? (EXPERIMENTAL) +# Enable etcd embedded datastore (EXPERIMENTAL) k3s_etcd_datastore: false -# Disable Etcd snapshots -k3s_etcd_disable_snapshots: false -# Etcd snapshot cron schedule. Example below is every 12 hours. -# k3s_etcd_snapshot_schedule_cron: "* */12 * * *" +## +# Server Configuration +## -# Etcd snapshot retention -# k3s_etcd_snapshot_retention: 5 +k3s_server: {} +# k3s_server: +# listen-port: 6443 -# Etcd snapshot directory -# k3s_etcd_snapshot_directory: /server/db/snapshots +## +# Agent Configuration +## -# HTTPS Listening port -k3s_https_port: 6443 +k3s_agent: {} +# k3s_agent: +# node-label: +# - "foo=bar" +# - "bish=bosh" -# Ensure Docker is installed on nodes -k3s_use_docker: false +## +# Ansible Controller configuration +## -# Disable flannel, you will need to install your own CNI driver. -k3s_no_flannel: false - -# Flannel backend ('none', 'vxlan', 'ipsec', 'host-gw' or 'wireguard') -# k3s_flannel_backend: vxlan - -# Disable CoreDNS, you will need to install your own DNS provider. -k3s_no_coredns: false - -# Cluster IP for CoreDNS service. Should be in your service-cidr range. -# Use `false` to use default -k3s_cluster_dns: false - -# Cluster Domain (default: "cluster.local") -# k3s_cluster_domain: cluster.local - -# Disable Traefik -k3s_no_traefik: false - -# Disable Service Load Balancer, you will need to install your own -# load balancer, such as MetalLB. Must be disabled if using your own -# load balancer service. -k3s_no_servicelb: false - -# Do not use local storage -k3s_no_local_storage: false - -# Do not deploy metrics server -k3s_no_metrics_server: false - -# Disable default k3s scheduler -k3s_disable_scheduler: false - -# Disable k3s cloud controller -k3s_disable_cloud_controller: false - -# Disable k3s network policy controller -k3s_disable_network_policy: false - -# Disable k3s default kube proxy. -k3s_disable_kube_proxy: false - -# Default local storage path for local provisioner storage class, if set to "false" we will use the default -k3s_default_local_storage_path: false - -# Use secret encryption at rest (EXPERIMENTAL) -k3s_secrets_encryption: false - -# Enable SELinux in containerd (EXPERIMENTAL) -k3s_enable_selinux: false - -# with become privileges for +# Use become privileges for k3s_become_for_all: false k3s_become_for_systemd: null k3s_become_for_install_dir: null diff --git a/meta/main.yml b/meta/main.yml index 2b20d38..c14c443 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -19,7 +19,7 @@ galaxy_info: # - CC-BY license: BSD - min_ansible_version: 2.7 + min_ansible_version: 2.10 # If this a Container Enabled role, provide the minimum Ansible Container version. # min_ansible_container_version: diff --git a/molecule/default/playbook-auto-deploying-manifests.yml b/molecule/autodeploy/converge.yml similarity index 56% rename from molecule/default/playbook-auto-deploying-manifests.yml rename to molecule/autodeploy/converge.yml index 72b26be..a03f036 100644 --- a/molecule/default/playbook-auto-deploying-manifests.yml +++ b/molecule/autodeploy/converge.yml @@ -1,10 +1,11 @@ --- - name: Converge - hosts: all + hosts: node* become: true vars: molecule_is_test: true + k3s_build_cluster: false k3s_server_manifests_templates: - - "molecule/default/templates/00-ns-monitoring.yml.j2" + - "molecule/autodeploy/templates/00-ns-monitoring.yml.j2" roles: - role: xanmanning.k3s diff --git a/molecule/autodeploy/molecule.yml b/molecule/autodeploy/molecule.yml new file mode 100644 index 0000000..af6a516 --- /dev/null +++ b/molecule/autodeploy/molecule.yml @@ -0,0 +1,44 @@ +--- + +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint -s . + ansible-lint +platforms: + - name: node1 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node2 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node3 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet +provisioner: + name: ansible + options: + verbose: true +verifier: + name: ansible diff --git a/molecule/default/templates/00-ns-monitoring.yml.j2 b/molecule/autodeploy/templates/00-ns-monitoring.yml.j2 similarity index 100% rename from molecule/default/templates/00-ns-monitoring.yml.j2 rename to molecule/autodeploy/templates/00-ns-monitoring.yml.j2 diff --git a/molecule/autodeploy/verify.yml b/molecule/autodeploy/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/molecule/autodeploy/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/molecule/debug/converge.yml b/molecule/debug/converge.yml new file mode 100644 index 0000000..78e8bed --- /dev/null +++ b/molecule/debug/converge.yml @@ -0,0 +1,12 @@ +--- +- name: Converge + hosts: all + become: true + vars: + pyratlabs_issue_controller_dump: true + pre_tasks: + - name: Ensure k3s_debug is set + set_fact: + k3s_debug: true + roles: + - xanmanning.k3s diff --git a/molecule/debug/molecule.yml b/molecule/debug/molecule.yml new file mode 100644 index 0000000..af6a516 --- /dev/null +++ b/molecule/debug/molecule.yml @@ -0,0 +1,44 @@ +--- + +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint -s . + ansible-lint +platforms: + - name: node1 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node2 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node3 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet +provisioner: + name: ansible + options: + verbose: true +verifier: + name: ansible diff --git a/molecule/debug/verify.yml b/molecule/debug/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/molecule/debug/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/molecule/default/playbook.yml b/molecule/default/converge.yml similarity index 80% rename from molecule/default/playbook.yml rename to molecule/default/converge.yml index c3454bd..aa6404d 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/converge.yml @@ -4,7 +4,6 @@ become: true vars: molecule_is_test: true - k3s_release_version: v1.18.6+k3s1 k3s_install_hard_links: true roles: - role: xanmanning.k3s diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index de61737..af6a516 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -6,7 +6,7 @@ driver: name: docker lint: | set -e - yamllint . + yamllint -s . ansible-lint platforms: - name: node1 @@ -40,6 +40,5 @@ provisioner: name: ansible options: verbose: true - playbooks: - prepare: ${MOLECULE_PREPARE_PLAYBOOK:-prepare.yml} - converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +verifier: + name: ansible diff --git a/molecule/default/playbook-docker-altport-wireguard.yml b/molecule/default/playbook-docker-altport-wireguard.yml deleted file mode 100644 index 3700ddc..0000000 --- a/molecule/default/playbook-docker-altport-wireguard.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Converge - hosts: all - become: true - vars: - molecule_is_test: true - k3s_use_docker: true - k3s_https_port: 26443 - k3s_cluster_domain: examplecluster.local - roles: - - role: xanmanning.k3s diff --git a/molecule/default/playbook-docker.yml b/molecule/default/playbook-docker.yml deleted file mode 100644 index a780b33..0000000 --- a/molecule/default/playbook-docker.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Converge - hosts: all - become: true - vars: - molecule_is_test: true - k3s_use_docker: true - roles: - - role: xanmanning.k3s diff --git a/molecule/default/playbook-no-deploy.yml b/molecule/default/playbook-no-deploy.yml deleted file mode 100644 index 28e4f48..0000000 --- a/molecule/default/playbook-no-deploy.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- name: Converge - hosts: all - become: true - vars: - molecule_is_test: true - k3s_no_coredns: true - k3s_no_traefik: true - k3s_no_servicelb: true - k3s_no_flannel: true - k3s_no_local_storage: true - k3s_default_local_storage_path: false - k3s_no_metrics_server: true - k3s_disable_scheduler: true - k3s_disable_cloud_controller: true - k3s_disable_network_policy: true - k3s_node_labels: - - foo: bar - - hello: world - k3s_node_taints: - - key1: value1:NoExecute - k3s_kubelet_args: - - cloud-provider: external - - provider-id: azure - roles: - - role: xanmanning.k3s diff --git a/molecule/default/playbook-rootless.yml b/molecule/default/playbook-rootless.yml index ef6beff..b5f1cf4 100644 --- a/molecule/default/playbook-rootless.yml +++ b/molecule/default/playbook-rootless.yml @@ -5,8 +5,11 @@ become_user: k3suser vars: molecule_is_test: true - k3s_non_root: true k3s_use_experimental: true + k3s_server: + rootless: true + k3s_agent: + rootless: true k3s_install_dir: "/home/{{ ansible_user_id }}/bin" roles: - role: xanmanning.k3s diff --git a/molecule/default/playbook-uninstall-cluster.yml b/molecule/default/playbook-uninstall-cluster.yml index 0e42556..a756578 100644 --- a/molecule/default/playbook-uninstall-cluster.yml +++ b/molecule/default/playbook-uninstall-cluster.yml @@ -5,6 +5,5 @@ vars: molecule_is_test: true k3s_cluster_state: uninstalled - k3s_use_docker: true roles: - role: xanmanning.k3s diff --git a/molecule/default/playbook-version.yml b/molecule/default/playbook-version.yml deleted file mode 100644 index 740d9c9..0000000 --- a/molecule/default/playbook-version.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Converge - hosts: all - become: true - vars: - molecule_is_test: true - k3s_release_version: v0.4.0 - roles: - - role: xanmanning.k3s diff --git a/molecule/docker/converge.yml b/molecule/docker/converge.yml new file mode 100644 index 0000000..529f932 --- /dev/null +++ b/molecule/docker/converge.yml @@ -0,0 +1,13 @@ +--- +- name: Converge + hosts: all + become: true + vars: + molecule_is_test: true + k3s_server: + https-listen-port: 26443 + cluster-domain: examplecluster.local + k3s_agent: + docker: true + roles: + - role: xanmanning.k3s diff --git a/molecule/docker/molecule.yml b/molecule/docker/molecule.yml new file mode 100644 index 0000000..85427b3 --- /dev/null +++ b/molecule/docker/molecule.yml @@ -0,0 +1,44 @@ +--- + +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint -s . + ansible-lint +platforms: + - name: node1 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-ubuntu2004-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node2 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-ubuntu2004-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node3 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-ubuntu2004-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet +provisioner: + name: ansible + options: + verbose: true +verifier: + name: ansible diff --git a/molecule/docker/prepare.yml b/molecule/docker/prepare.yml new file mode 100644 index 0000000..7ad302a --- /dev/null +++ b/molecule/docker/prepare.yml @@ -0,0 +1,8 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Ensure apt cache is updated + apt: + update_cache: true + when: ansible_pkg_mgr == 'apt' diff --git a/molecule/highavailability/playbook-auto-deploying-manifests.yml b/molecule/highavailability/playbook-auto-deploying-manifests.yml deleted file mode 100644 index 055d3d2..0000000 --- a/molecule/highavailability/playbook-auto-deploying-manifests.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Converge - hosts: node* - become: true - vars: - molecule_is_test: true - k3s_control_node_address: loadbalancer - k3s_datastore_endpoint: "postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable" - k3s_server_manifests_templates: - - "molecule/highavailability/templates/00-ns-monitoring.yml.j2" - pre_tasks: - - name: Set each node to be a control node - set_fact: - k3s_control_node: true - when: inventory_hostname in ['node2', 'node3'] - roles: - - role: xanmanning.k3s diff --git a/molecule/highavailability/playbook-dqlite.yml b/molecule/highavailability/playbook-dqlite.yml deleted file mode 100644 index 9116912..0000000 --- a/molecule/highavailability/playbook-dqlite.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: Converge - hosts: node* - become: true - vars: - molecule_is_test: true - k3s_release_version: v1.18 - k3s_dqlite_datastore: true - k3s_secrets_encryption: true - k3s_use_experimental: true - k3s_use_unsupported_config: true - pre_tasks: - - name: Set each node to be a control node - set_fact: - k3s_control_node: true - when: inventory_hostname in ['node2', 'node3'] - roles: - - role: xanmanning.k3s diff --git a/molecule/highavailability/templates/00-ns-monitoring.yml.j2 b/molecule/highavailability/templates/00-ns-monitoring.yml.j2 deleted file mode 100644 index d325236..0000000 --- a/molecule/highavailability/templates/00-ns-monitoring.yml.j2 +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: monitoring diff --git a/molecule/highavailability/Dockerfile.j2 b/molecule/highavailabilitydb/Dockerfile.j2 similarity index 100% rename from molecule/highavailability/Dockerfile.j2 rename to molecule/highavailabilitydb/Dockerfile.j2 diff --git a/molecule/highavailability/INSTALL.rst b/molecule/highavailabilitydb/INSTALL.rst similarity index 100% rename from molecule/highavailability/INSTALL.rst rename to molecule/highavailabilitydb/INSTALL.rst diff --git a/molecule/highavailability/playbook.yml b/molecule/highavailabilitydb/converge.yml similarity index 73% rename from molecule/highavailability/playbook.yml rename to molecule/highavailabilitydb/converge.yml index fcc3562..bf02a66 100644 --- a/molecule/highavailability/playbook.yml +++ b/molecule/highavailabilitydb/converge.yml @@ -1,11 +1,13 @@ --- + - name: Converge hosts: node* become: true vars: molecule_is_test: true k3s_control_node_address: loadbalancer - k3s_datastore_endpoint: "postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable" + k3s_server: + datastore-endpoint: "postgres://postgres:verybadpass@database:5432/postgres?sslmode=disable" pre_tasks: - name: Set each node to be a control node set_fact: diff --git a/molecule/highavailability/haproxy-loadbalancer.conf.j2 b/molecule/highavailabilitydb/haproxy-loadbalancer.conf.j2 similarity index 100% rename from molecule/highavailability/haproxy-loadbalancer.conf.j2 rename to molecule/highavailabilitydb/haproxy-loadbalancer.conf.j2 diff --git a/molecule/highavailability/molecule.yml b/molecule/highavailabilitydb/molecule.yml similarity index 91% rename from molecule/highavailability/molecule.yml rename to molecule/highavailabilitydb/molecule.yml index 9b147d7..7028ac9 100644 --- a/molecule/highavailability/molecule.yml +++ b/molecule/highavailabilitydb/molecule.yml @@ -6,7 +6,7 @@ driver: name: docker lint: | set -e - yamllint . + yamllint -s . ansible-lint platforms: - name: node1 @@ -55,6 +55,3 @@ provisioner: name: ansible options: verbose: true - playbooks: - prepare: ${MOLECULE_PREPARE_PLAYBOOK:-prepare.yml} - converge: ${MOLECULE_PLAYBOOK:-playbook.yml} diff --git a/molecule/highavailability/prepare.yml b/molecule/highavailabilitydb/prepare.yml similarity index 100% rename from molecule/highavailability/prepare.yml rename to molecule/highavailabilitydb/prepare.yml diff --git a/molecule/highavailability/tests/test_default.py b/molecule/highavailabilitydb/tests/test_default.py similarity index 100% rename from molecule/highavailability/tests/test_default.py rename to molecule/highavailabilitydb/tests/test_default.py diff --git a/molecule/highavailability/tests/test_default.pyc b/molecule/highavailabilitydb/tests/test_default.pyc similarity index 100% rename from molecule/highavailability/tests/test_default.pyc rename to molecule/highavailabilitydb/tests/test_default.pyc diff --git a/molecule/highavailability/playbook-etcd.yml b/molecule/highavailabilityetcd/converge.yml similarity index 81% rename from molecule/highavailability/playbook-etcd.yml rename to molecule/highavailabilityetcd/converge.yml index 3b63df2..41cd30f 100644 --- a/molecule/highavailability/playbook-etcd.yml +++ b/molecule/highavailabilityetcd/converge.yml @@ -1,13 +1,14 @@ --- + - name: Converge hosts: node* become: true vars: molecule_is_test: true - k3s_release_version: v1.19 - k3s_etcd_datastore: true - k3s_secrets_encryption: true k3s_use_experimental: true + k3s_etcd_datastore: true + k3s_server: + secrets-encryption: true pre_tasks: - name: Set each node to be a control node set_fact: diff --git a/molecule/highavailabilityetcd/haproxy-loadbalancer.conf.j2 b/molecule/highavailabilityetcd/haproxy-loadbalancer.conf.j2 new file mode 100644 index 0000000..78fe9d3 --- /dev/null +++ b/molecule/highavailabilityetcd/haproxy-loadbalancer.conf.j2 @@ -0,0 +1,13 @@ +frontend loadbalancer + bind *:6443 + mode tcp + default_backend control_nodes + timeout client 1m + +backend control_nodes + mode tcp + balance roundrobin + server node2 node2:6443 + server node3 node3:6443 + timeout connect 30s + timeout server 30m diff --git a/molecule/highavailabilityetcd/molecule.yml b/molecule/highavailabilityetcd/molecule.yml new file mode 100644 index 0000000..2a32b15 --- /dev/null +++ b/molecule/highavailabilityetcd/molecule.yml @@ -0,0 +1,49 @@ +--- + +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint -s . + ansible-lint +platforms: + - name: node1 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node2 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node3 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: loadbalancer + image: geerlingguy/docker-centos8-ansible:latest + pre_build_image: true + ports: + - "6443:6443" + networks: + - name: k3snet +provisioner: + name: ansible + options: + verbose: true diff --git a/molecule/highavailabilityetcd/prepare.yml b/molecule/highavailabilityetcd/prepare.yml new file mode 100644 index 0000000..86d8f25 --- /dev/null +++ b/molecule/highavailabilityetcd/prepare.yml @@ -0,0 +1,30 @@ +--- +- name: Prepare + hosts: loadbalancer + tasks: + - name: Ensure apt cache is updated + apt: + update_cache: true + when: ansible_pkg_mgr == 'apt' + + - name: Ensure HAProxy is installed + package: + name: haproxy + state: present + + - name: Ensure HAProxy config directory exists + file: + path: /usr/local/etc/haproxy + state: directory + mode: 0755 + + - name: Ensure HAProxy is configured + template: + src: haproxy-loadbalancer.conf.j2 + dest: /usr/local/etc/haproxy/haproxy.cfg + mode: 0644 + + - name: Ensure HAProxy service is started + command: haproxy -D -f /usr/local/etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid + args: + creates: /var/run/haproxy.pid diff --git a/molecule/nodeploy/converge.yml b/molecule/nodeploy/converge.yml new file mode 100644 index 0000000..954e451 --- /dev/null +++ b/molecule/nodeploy/converge.yml @@ -0,0 +1,10 @@ +--- +- name: Converge + hosts: all + become: true + vars: + molecule_is_test: true + k3s_server: "{{ lookup('file', 'k3s_server.yml') | from_yaml }}" + k3s_agent: "{{ lookup('file', 'k3s_agent.yml') | from_yaml }}" + roles: + - role: xanmanning.k3s diff --git a/molecule/nodeploy/k3s_agent.yml b/molecule/nodeploy/k3s_agent.yml new file mode 100644 index 0000000..58fa21e --- /dev/null +++ b/molecule/nodeploy/k3s_agent.yml @@ -0,0 +1,8 @@ +--- + +node-label: + - "foo=bar" + - "hello=world" +kubelet-arg: + - "cloud-provider=external" + - "provider-id=azure" diff --git a/molecule/nodeploy/k3s_server.yml b/molecule/nodeploy/k3s_server.yml new file mode 100644 index 0000000..4c16bd5 --- /dev/null +++ b/molecule/nodeploy/k3s_server.yml @@ -0,0 +1,14 @@ +--- + +flannel-backend: 'host-gw' +disable-scheduler: true +disable-cloud-controller: true +disable-network-policy: true +disable: + - coredns + - traefik + - servicelb + - local-storage + - metrics-server +node-taint: + - "k3s-controlplane=true:NoExecute" diff --git a/molecule/nodeploy/molecule.yml b/molecule/nodeploy/molecule.yml new file mode 100644 index 0000000..af6a516 --- /dev/null +++ b/molecule/nodeploy/molecule.yml @@ -0,0 +1,44 @@ +--- + +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint -s . + ansible-lint +platforms: + - name: node1 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node2 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet + - name: node3 + image: "${MOLECULE_DISTRO:-geerlingguy/docker-centos8-ansible:latest}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: ${MOLECULE_PREBUILT:-true} + networks: + - name: k3snet +provisioner: + name: ansible + options: + verbose: true +verifier: + name: ansible diff --git a/molecule/nodeploy/verify.yml b/molecule/nodeploy/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/molecule/nodeploy/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/molecule/requirements.txt b/molecule/requirements.txt new file mode 100644 index 0000000..980f8ac --- /dev/null +++ b/molecule/requirements.txt @@ -0,0 +1,6 @@ +-r ../requirements.txt + +molecule[docker]>=3.1.2 +docker>=4.3.1 +yamllint>=1.25.0 +ansible-lint>=4.3.5 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4862083 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +jmespath>=0.10.0 +ansible>=2.10.3 diff --git a/tasks/build/configure-k3s-cluster.yml b/tasks/build/configure-k3s-cluster.yml index b33c4d1..bd1f5ea 100644 --- a/tasks/build/configure-k3s-cluster.yml +++ b/tasks/build/configure-k3s-cluster.yml @@ -31,7 +31,7 @@ src: cluster-token.j2 dest: "{{ k3s_token_location }}/cluster-token" mode: 0600 - become: "{{ k3s_become_for_systemd | ternary(true, false, k3s_become_for_all) }}" + become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" when: (k3s_control_node and not k3s_primary_control_node) or not k3s_control_node notify: @@ -47,6 +47,16 @@ - reload systemd - restart k3s +- name: Ensure k3s config file exists + template: + src: config.yaml.j2 + dest: "{{ k3s_config_file }}" + mode: 0644 + notify: + - reload systemd + - restart k3s + become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" + - name: Ensure secondary controllers are started service: name: k3s @@ -59,25 +69,10 @@ when: k3s_control_node and not k3s_primary_control_node become: "{{ k3s_become_for_systemd | ternary(true, false, k3s_become_for_all) }}" -- name: Wait for control plane to be ready to accept connections - wait_for: - port: "{{ k3s_https_port }}" - host: "{{ k3s_bind_address | default('127.0.0.1') }}" - delay: 5 - sleep: 5 - timeout: 300 - when: k3s_control_node +- import_tasks: ../validate/check-control-plane.yml + when: not k3s_skip_validation - meta: flush_handlers -- name: Wait for all nodes to be ready - command: "{{ k3s_install_dir }}/kubectl get nodes" - changed_when: false - failed_when: false - register: kubectl_get_nodes_result - until: kubectl_get_nodes_result.rc == 0 - and kubectl_get_nodes_result.stdout.find("NotReady") == -1 - retries: 30 - delay: 20 - when: k3s_control_node and not k3s_no_flannel and not ansible_check_mode - become: "{{ k3s_become_for_kubectl | ternary(true, false, k3s_become_for_all) }}" +- import_tasks: ../validate/check-cluster-nodes-ready.yml + when: not k3s_skip_validation diff --git a/tasks/build/install-docker.yml b/tasks/build/install-docker.yml index 707d8ff..d46445b 100644 --- a/tasks/build/install-docker.yml +++ b/tasks/build/install-docker.yml @@ -14,5 +14,3 @@ notify: - restart docker become: "{{ k3s_become_for_package_install | ternary(true, false, k3s_become_for_all) }}" - -- meta: flush_handlers diff --git a/tasks/build/install-k3s-node.yml b/tasks/build/install-k3s-node.yml new file mode 100644 index 0000000..ef0c390 --- /dev/null +++ b/tasks/build/install-k3s-node.yml @@ -0,0 +1,52 @@ +--- + +- name: Ensure k3s is linked into the installation destination + file: + src: "{{ k3s_install_dir }}/k3s-{{ k3s_release_version }}" + dest: "{{ k3s_install_dir }}/{{ item }}" + state: "{{ 'hard' if k3s_install_hard_links else 'link' }}" + force: "{{ k3s_install_hard_links }}" + mode: 0755 + loop: + - k3s + - kubectl + - crictl + - ctr + when: not ansible_check_mode + notify: + - restart k3s + become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" + +- name: Ensure k3s config file exists + template: + src: config.yaml.j2 + dest: "{{ k3s_config_file }}" + mode: 0644 + notify: + - reload systemd + - restart k3s + become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" + +- name: Ensure k3s service unit file is present + template: + src: k3s.service.j2 + dest: "{{ k3s_systemd_unit_directory }}/k3s.service" + mode: 0644 + notify: + - reload systemd + - restart k3s + become: "{{ k3s_become_for_systemd | ternary(true, false, k3s_become_for_all) }}" + +- name: Ensure k3s killall script is present + template: + src: k3s-killall.sh.j2 + dest: "/usr/local/bin/k3s-killall.sh" + mode: 0700 + become: "{{ k3s_become_for_usr_local_bin | ternary(true, false, k3s_become_for_all) }}" + +- name: Ensure k3s uninstall script is present + template: + src: k3s-uninstall.sh.j2 + dest: "/usr/local/bin/k3s-uninstall.sh" + mode: 0700 + become: "{{ k3s_become_for_usr_local_bin | ternary(true, false, k3s_become_for_all) }}" diff --git a/tasks/build/install-k3s.yml b/tasks/build/install-k3s.yml index 4f9f990..0da9195 100644 --- a/tasks/build/install-k3s.yml +++ b/tasks/build/install-k3s.yml @@ -1,21 +1,10 @@ --- -- name: Ensure k3s is linked into the installation destination on the contol plane +- name: Ensure config directory exists file: - src: "{{ k3s_install_dir }}/k3s-{{ k3s_release_version }}" - dest: "{{ k3s_install_dir }}/{{ item }}" - state: "{{ 'hard' if k3s_install_hard_links else 'link' }}" - force: "{{ k3s_install_hard_links }}" + path: "{{ k3s_config_file | dirname }}" + state: directory mode: 0755 - loop: - - k3s - - kubectl - - crictl - - ctr - when: ((k3s_control_node and k3s_controller_count | length == 1) - or (k3s_primary_control_node and k3s_controller_count | length > 1)) and not ansible_check_mode - notify: - - restart k3s become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" - name: Ensure systemd unit file directory exists @@ -23,51 +12,16 @@ path: "{{ k3s_systemd_unit_directory }}" state: directory mode: 0755 - -- name: Ensure k3s service unit file is present on control plane - template: - src: k3s.service.j2 - dest: "{{ k3s_systemd_unit_directory }}/k3s.service" - mode: 0644 - when: (k3s_control_node and k3s_controller_count | length == 1) - or (k3s_primary_control_node and k3s_controller_count | length > 1) - notify: - - reload systemd - - restart k3s become: "{{ k3s_become_for_systemd | ternary(true, false, k3s_become_for_all) }}" +- include_tasks: install-k3s-node.yml + when: ((k3s_control_node and k3s_controller_count | length == 1) + or (k3s_primary_control_node and k3s_controller_count | length > 1)) and not ansible_check_mode + - meta: flush_handlers -- name: Ensure k3s killall script is present on all nodes - template: - src: k3s-killall.sh.j2 - dest: "/usr/local/bin/k3s-killall.sh" - mode: 0700 - become: "{{ k3s_become_for_usr_local_bin | ternary(true, false, k3s_become_for_all) }}" - -- name: Ensure k3s uninstall script is present on all nodes - template: - src: k3s-uninstall.sh.j2 - dest: "/usr/local/bin/k3s-uninstall.sh" - mode: 0700 - become: "{{ k3s_become_for_usr_local_bin | ternary(true, false, k3s_become_for_all) }}" - -- name: Ensure k3s is linked into the installation destinations across all nodes - file: - src: "{{ k3s_install_dir }}/k3s-{{ k3s_release_version }}" - dest: "{{ k3s_install_dir }}/{{ item }}" - state: "{{ 'hard' if k3s_install_hard_links else 'link' }}" - force: "{{ k3s_install_hard_links }}" - mode: 0755 - notify: - - restart k3s - loop: - - k3s - - kubectl - - crictl - - ctr - when: not ansible_check_mode - become: "{{ k3s_become_for_install_dir | ternary(true, false, k3s_become_for_all) }}" +- include_tasks: install-k3s-node.yml + when: k3s_build_cluster - name: Ensure k3s control plane is started systemd: diff --git a/tasks/build/preconfigure-k3s.yml b/tasks/build/preconfigure-k3s.yml index a8e87dd..1a9d869 100644 --- a/tasks/build/preconfigure-k3s.yml +++ b/tasks/build/preconfigure-k3s.yml @@ -5,7 +5,7 @@ k3s_control_node: "{{ 'false' if k3s_build_cluster else 'true' }}" when: k3s_control_node is not defined -- name: Ensure k3s control node fact is set +- name: Ensure k3s primary control node fact is set set_fact: k3s_primary_control_node: "{{ 'false' if k3s_build_cluster else 'true' }}" when: k3s_primary_control_node is not defined @@ -52,7 +52,7 @@ check_mode: false when: hostvars[item].k3s_control_node is defined -- name: Delegate a primary control plane node +- name: Delegate a control plane node block: - name: Lookup control node from file command: "grep '{{ 'P_True' if (k3s_controller_count | length > 1) else 'C_True' }}' /tmp/inventory.txt" @@ -74,3 +74,15 @@ when: k3s_control_node_address is not defined or k3s_control_delegate is not defined + +- name: Ensure k3s_runtime_config is set for control plane + set_fact: + k3s_runtime_config: "{{ (k3s_server | default({})) | combine((k3s_agent | default({}))) }}" + when: (k3s_server is defined or k3s_agent is defined) + and (k3s_control_node is defined and k3s_control_node) + +- name: Ensure k3s_runtime_config is set for agents + set_fact: + k3s_runtime_config: "{{ (k3s_agent | default({})) }}" + when: k3s_agent is defined + and (k3s_control_node is not defined or not k3s_control_node) diff --git a/tasks/main.yml b/tasks/main.yml index 10646b3..bcefc18 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,11 +1,5 @@ --- -- name: Check to see if k3s_cluster_state is a supported value - assert: - that: - - k3s_cluster_state in ['installed', 'started', 'stopped', 'restarted', 'downloaded', 'uninstalled'] - fail_msg: "k3s_cluster_state not valid. Check README.md for details." - success_msg: "k3s_cluster_state is valid." - when: k3s_cluster_state is defined +- import_tasks: validate/pre-flight.yml -- include_tasks: state-{{ (k3s_cluster_state | lower) | default('installed') }}.yml +- include_tasks: state-{{ (k3s_state | lower) | default('installed') }}.yml diff --git a/tasks/state-installed.yml b/tasks/state-installed.yml index d8c0dde..a6fc95a 100644 --- a/tasks/state-installed.yml +++ b/tasks/state-installed.yml @@ -1,8 +1,5 @@ --- -- import_tasks: validate/check-environment.yml - when: not k3s_skip_validation - - import_tasks: build/preconfigure-k3s.yml - import_tasks: teardown/drain-and-remove-nodes.yml @@ -17,19 +14,21 @@ - import_tasks: build/get-systemd-context.yml -- include_tasks: build/install-docker-prerequisites-{{ ansible_os_family | lower }}.yml - when: k3s_use_docker - and (k3s_non_root is not defined or not k3s_non_root) +- name: Ensure docker installation tasks are run + block: -- import_tasks: build/install-docker.yml - when: k3s_use_docker - and ansible_distribution | replace(" ", "-") | lower not in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] - and (k3s_non_root is not defined or not k3s_non_root) + - include_tasks: build/install-docker-prerequisites-{{ ansible_os_family | lower }}.yml -- include_tasks: build/install-docker-{{ ansible_distribution | replace(" ", "-") | lower }}.yml - when: k3s_use_docker - and ansible_distribution | replace(" ", "-") | lower in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] - and (k3s_non_root is not defined or not k3s_non_root) + - import_tasks: build/install-docker.yml + when: ansible_distribution | replace(" ", "-") | lower not in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] + + - include_tasks: build/install-docker-{{ ansible_distribution | replace(" ", "-") | lower }}.yml + when: ansible_distribution | replace(" ", "-") | lower in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] + + when: ('docker' in k3s_runtime_config and k3s_runtime_config.docker) + and ('rootless' not in k3s_runtime_config or not k3s_runtime_config.rootless) + +- meta: flush_handlers - import_tasks: build/download-k3s.yml diff --git a/tasks/state-restarted.yml b/tasks/state-restarted.yml index aaa5d76..85186a8 100644 --- a/tasks/state-restarted.yml +++ b/tasks/state-restarted.yml @@ -1,4 +1,5 @@ --- - import_tasks: operate/stop-k3s.yml + - import_tasks: operate/start-k3s.yml diff --git a/tasks/state-uninstalled.yml b/tasks/state-uninstalled.yml index 30033cf..11d1d6c 100644 --- a/tasks/state-uninstalled.yml +++ b/tasks/state-uninstalled.yml @@ -6,19 +6,19 @@ - import_tasks: teardown/uninstall-k3s.yml -- import_tasks: teardown/uninstall-docker.yml - when: k3s_use_docker - and ansible_distribution | replace(" ", "-") | lower not in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] - and (k3s_non_root is not defined or not k3s_non_root) +- name: Ensure docker uninstall tasks are run + block: -- include_tasks: teardown/uninstall-docker-{{ ansible_distribution | replace(" ", "-") | lower }}.yml - when: k3s_use_docker - and ansible_distribution | replace(" ", "-") | lower in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] - and (k3s_non_root is not defined or not k3s_non_root) + - import_tasks: teardown/uninstall-docker.yml + when: ansible_distribution | replace(" ", "-") | lower not in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] -- include_tasks: teardown/uninstall-docker-prerequisites-{{ ansible_os_family | lower }}.yml - when: k3s_use_docker - and (k3s_non_root is not defined or not k3s_non_root) + - include_tasks: teardown/uninstall-docker-{{ ansible_distribution | replace(" ", "-") | lower }}.yml + when: ansible_distribution | replace(" ", "-") | lower in ['amazon', 'suse', 'opensuse-leap', 'archlinux'] + + - include_tasks: teardown/uninstall-docker-prerequisites-{{ ansible_os_family | lower }}.yml + + when: ('docker' in k3s_runtime_config and k3s_runtime_config.docker) + and ('rootless' not in k3s_runtime_config or not k3s_runtime_config.rootless) - import_tasks: validate/check-uninstalled.yml when: not k3s_skip_validation diff --git a/tasks/state-validated.yml b/tasks/state-validated.yml new file mode 100644 index 0000000..a94e0b3 --- /dev/null +++ b/tasks/state-validated.yml @@ -0,0 +1,7 @@ +--- + +- import_tasks: validate/pre-flight.yml + +- import_tasks: validate/main.yml + +- import_tasks: validate/post-install.yml diff --git a/tasks/teardown/uninstall-k3s.yml b/tasks/teardown/uninstall-k3s.yml index e9c5217..4064bee 100644 --- a/tasks/teardown/uninstall-k3s.yml +++ b/tasks/teardown/uninstall-k3s.yml @@ -34,4 +34,5 @@ - name: Clean up Docker command: docker system prune -a --force - when: k3s_use_docker and check_k3s_docker_path.rc == 0 + when: ("docker" in k3s_runtime_config and k3s_runtime_config.docker) + and check_k3s_docker_path.rc == 0 diff --git a/tasks/validate/check-cluster-nodes-ready.yml b/tasks/validate/check-cluster-nodes-ready.yml new file mode 100644 index 0000000..c9c49fe --- /dev/null +++ b/tasks/validate/check-cluster-nodes-ready.yml @@ -0,0 +1,17 @@ +--- + +- name: Check that all nodes to be ready + command: "{{ k3s_install_dir }}/kubectl get nodes" + changed_when: false + failed_when: kubectl_get_nodes_result.stdout.find("was refused") != -1 or + kubectl_get_nodes_result.stdout.find("ServiceUnavailable") != -1 + register: kubectl_get_nodes_result + until: kubectl_get_nodes_result.rc == 0 + and kubectl_get_nodes_result.stdout.find("NotReady") == -1 + retries: 30 + delay: 20 + when: k3s_control_node + and (("disable" not in k3s_runtime_config) + or ("disable" in k3s_runtime_config and "flannel" not in k3s_runtime_config.disable)) + and not ansible_check_mode + become: "{{ k3s_become_for_kubectl | ternary(true, false, k3s_become_for_all) }}" diff --git a/tasks/validate/check-controller-count.yml b/tasks/validate/check-control-count.yml similarity index 71% rename from tasks/validate/check-controller-count.yml rename to tasks/validate/check-control-count.yml index b80d165..88e3642 100644 --- a/tasks/validate/check-controller-count.yml +++ b/tasks/validate/check-control-count.yml @@ -4,24 +4,24 @@ assert: that: - (k3s_controller_count | length == 1) - and (k3s_datastore_endpoint is not defined or not k3s_datastore_endpoint) - and (k3s_dqlite_datastore is not defined or not k3s_dqlite_datastore) + and ("datastore-endpoint" not in k3s_runtime_config or not k3s_runtime_config['datastore-endpoint']) and (k3s_etcd_datastore is not defined or not k3s_etcd_datastore) success_msg: "Control plane configuration is valid." fail_msg: "Control plane configuration is invalid. Please see notes about k3s_control_node and HA in README.md." when: k3s_controller_count | length == 1 and not k3s_use_unsupported_config + and k3s_control_node - name: Check the conditions when multiple controllers are defined assert: that: - (k3s_controller_count | length >= 2) - and ((k3s_datastore_endpoint is defined and k3s_datastore_endpoint) - or (k3s_dqlite_datastore is defined and k3s_dqlite_datastore) - or (k3s_etcd_datastore is defined and k3s_etcd_datastore)) + and (("datastore-endpoint" in k3s_runtime_config and k3s_runtime_config['datastore-endpoint']) + or (k3s_etcd_datastore is defined and k3s_etcd_datastore)) success_msg: "Control plane configuration is valid." fail_msg: "Control plane configuration is invalid. Please see notes about k3s_control_node and HA in README.md." when: k3s_controller_count | length >= 2 + and k3s_control_node - name: Check the conditions when embedded etcd is defined assert: @@ -30,4 +30,7 @@ and (((k3s_controller_count | length) % 2) == 1) success_msg: "Control plane configuration is valid." fail_msg: "Etcd should have a minimum of 3 defined members and the number of members should be odd. Please see notes about HA in README.md" - when: k3s_etcd_datastore and not k3s_use_unsupported_config + when: k3s_etcd_datastore is defined + and k3s_etcd_datastore + and not k3s_use_unsupported_config + and k3s_control_node diff --git a/tasks/validate/check-control-plane.yml b/tasks/validate/check-control-plane.yml new file mode 100644 index 0000000..fa69258 --- /dev/null +++ b/tasks/validate/check-control-plane.yml @@ -0,0 +1,10 @@ +--- + +- name: Check that the control plane to is available to accept connections + wait_for: + port: "{{ k3s_runtime_config['https-listen-port'] | default('6443') }}" + host: "{{ k3s_runtime_config['bind-address'] | default('127.0.0.1') }}" + delay: 5 + sleep: 5 + timeout: 300 + when: k3s_control_node diff --git a/tasks/validate/check-experimental-variables.yml b/tasks/validate/check-experimental-variables.yml index 8e2dab6..d01419b 100644 --- a/tasks/validate/check-experimental-variables.yml +++ b/tasks/validate/check-experimental-variables.yml @@ -6,19 +6,16 @@ - k3s_use_experimental is defined and k3s_use_experimental success_msg: "Experimental variables are defined and enabled." fail_msg: "Experimental variables have been configured. If you want to use them ensure you set k3s_use_experimental" - when: (k3s_non_root is defined and k3s_non_root) - or (k3s_dqlite_datastore is defined and k3s_dqlite_datastore) - or (k3s_etcd_datastore is defined and k3s_etcd_datastore) - or (k3s_secrets_encryption is defined and k3s_secrets_encryption) - or (k3s_enable_selinux is defined and k3s_enable_selinux) + loop: "{{ k3s_experimental_config }}" + when: k3s_etcd_datastore is defined and k3s_etcd_datastore -- name: Check if experimental dqlite is being used and k3s_use_unsupported_config is configured +- name: Check if any experimental variables are configure and if they are enabled with k3s_use_experimental assert: that: - - k3s_use_unsupported_config is defined and k3s_use_unsupported_config - success_msg: "Unsupported use of dqlite backend is enabled." - fail_msg: | - Embedded DQLite is no longer supported and there is no upgrade path to use Etcd! - If you're sure you want to use it set k3s_use_unsupported_config. This will break in v1.19! - when: k3s_use_experimental - and (k3s_dqlite_datastore is defined and k3s_dqlite_datastore) + - k3s_use_experimental is defined and k3s_use_experimental + success_msg: "Experimental variables are defined and enabled." + fail_msg: "Experimental variable {{ item.setting }} has been configured. If you want to use this ensure you set k3s_use_experimental" + loop: "{{ k3s_experimental_config }}" + when: (item.setting in k3s_runtime_config and k3s_runtime_config[item.setting]) + and ((item.until is not defined) or + (item.until is defined and (k3s_release_version | replace('v', '')) is version_compare(item.until, '<'))) diff --git a/tasks/validate/check-uninstalled.yml b/tasks/validate/check-uninstalled.yml index f5c3e0a..d1c33ba 100644 --- a/tasks/validate/check-uninstalled.yml +++ b/tasks/validate/check-uninstalled.yml @@ -16,12 +16,12 @@ ignore_errors: true changed_when: false register: check_k3s_docker_process - when: k3s_use_docker is defined and k3s_use_docker + when: ("docker" in k3s_runtime_config and k3s_runtime_config.docker) - name: Fail if docker is still running fail: msg: docker is still running, uninstall script failed. Please investigate. - when: k3s_use_docker is defined and k3s_use_docker and check_k3s_docker_process.rc == 0 + when: ("docker" in k3s_runtime_config and k3s_runtime_config.docker) - name: Fail if k3s binaries have not been removed stat: diff --git a/tasks/validate/check-variables.yml b/tasks/validate/check-variables.yml index 4bad3cc..265a2b7 100644 --- a/tasks/validate/check-variables.yml +++ b/tasks/validate/check-variables.yml @@ -1,288 +1,26 @@ --- -- name: Check k3s_no_flannel against k3s version +- name: "Check that k3s_release_version >= {{ k3s_min_version }}" assert: that: - - (k3s_release_version | replace('v', '')) is version_compare('0.2.0', '>=') - success_msg: "--no-flannel is supported in {{ k3s_release_version }}" - fail_msg: "--no-flannel is not supported in {{ k3s_release_version }}" - when: k3s_no_flannel is defined and k3s_no_flannel + - (k3s_release_version | replace('v', '')) is version_compare(k3s_min_version, '>=') + success_msg: "{{ k3s_release_version }} is supported by this role." + fail_msg: "{{ k3s_release_version }} is not supported by this role, please use xanmanning.k3s v1.x." -- name: Check k3s_service_cidr against k3s version +- name: Check configuration in k3s_server and k3s_agent that needs special configuration. assert: that: - - (k3s_release_version | replace('v', '')) is version_compare('0.2.0', '>=') - success_msg: "--service-cidr is supported in {{ k3s_release_version }}" - fail_msg: "--service-cidr is not supported in {{ k3s_release_version }}" - when: k3s_service_cidr is defined + - (item.setting not in k3s_runtime_config) + success_msg: "{{ item.setting }} not found in server/agent config" + fail_msg: "{{ item.setting }} found in server/agent config. Please set {{ item.correction }} to use this option." + loop: "{{ k3s_config_exclude }}" -- name: Check k3s_cluster_dns against k3s version +- name: Check configuration in k3s_server and k3s_agent against release version assert: that: - - (k3s_release_version | replace('v', '')) is version_compare('0.2.0', '>=') - success_msg: "--cluster-dns is supported in {{ k3s_release_version }}" - fail_msg: "--cluster-dns is not supported in {{ k3s_release_version }}" - when: k3s_cluster_dns is defined and k3s_cluster_dns - -- name: Check k3s_use_docker against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.2.0', '>=') - success_msg: "--docker is supported in {{ k3s_release_version }}" - fail_msg: "--docker is not supported in {{ k3s_release_version }}" - when: k3s_use_docker is defined and k3s_use_docker - -- name: Check k3s_no_traefik against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.2.0', '>=') - success_msg: "--no-deploy traefik is supported in {{ k3s_release_version }}" - fail_msg: "--no-deploy traefik is not supported in {{ k3s_release_version }}" - when: k3s_no_traefik is defined and k3s_no_traefik - -- name: Check k3s_non_root against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - - ansible_user_id != "root" - - play_hosts | length == 1 - success_msg: "k3s_non_root is supported in {{ k3s_release_version }}" - fail_msg: "k3s_non_root only works in >= v0.4.0, on a single node and must not be installed as root." - when: k3s_non_root is defined and k3s_non_root - -- name: Check k3s_resolv_conf against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.3.0', '>=') - success_msg: "--resolv-conf is supported in {{ k3s_release_version }}" - fail_msg: "--resolv-conf is not supported in {{ k3s_release_version }}" - when: k3s_resolv_conf is defined and k3s_resolv_conf - -- name: Check k3s_tls_san against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.3.0', '>=') - success_msg: "--tls-san is supported in {{ k3s_release_version }}" - fail_msg: "--tls-san is not supported in {{ k3s_release_version }}" - when: k3s_tls_san is defined and k3s_tls_san - -- name: Check k3s_flannel_interface against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "--flannel-iface is supported in {{ k3s_release_version }}" - fail_msg: "--flannel-iface is not supported in {{ k3s_release_version }}" - when: k3s_flannel_interface is defined and k3s_flannel_interface - -- name: Check k3s_cluster_domain against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "--cluster-domain is supported in {{ k3s_release_version }}" - fail_msg: "--cluster-domain is not supported in {{ k3s_release_version }}" - when: k3s_cluster_domain is defined and k3s_cluster_domain - -- name: Check k3s_bind_address against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "--bind-address is supported in {{ k3s_release_version }}" - fail_msg: "--bind-address is not supported in {{ k3s_release_version }}" - when: k3s_bind_address is defined and k3s_bind_address - -- name: Check k3s_bind_address against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.5.0', '>=') - success_msg: "Auto deploy manifests is supported in {{ k3s_release_version }}" - fail_msg: | - Auto deploy manifests supported is limited in {{ k3s_release_version }}. - To disable this message ensure k3s_use_experimental is set to true. - when: k3s_server_manifests_templates is defined - and k3s_server_manifests_templates | length > 0 - and (k3s_use_experimental is not defined or not k3s_use_experimental) - -- name: Check k3s_node_labels against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.6.0', '>=') - success_msg: "Node Labels supported in {{ k3s_release_version }}" - fail_msg: "Node Labels are not supported in {{ k3s_release_version }}" - when: k3s_node_labels is defined and k3s_node_labels - -- name: Check k3s_node_taints against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.6.0', '>=') - success_msg: "Node Taints supported in {{ k3s_release_version }}" - fail_msg: "Node Taints are not supported in {{ k3s_release_version }}" - when: k3s_node_taints is defined and k3s_node_taints - -- name: Check k3s_kubelet_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "Kubelet args supported in {{ k3s_release_version }}" - fail_msg: "Kubelet args are not supported in {{ k3s_release_version }}" - when: k3s_kubelet_args is defined and k3s_kubelet_args | length > 0 - -- name: Check k3s_kube_proxy_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "Kube proxy args supported in {{ k3s_release_version }}" - fail_msg: "Kube proxy args are not supported in {{ k3s_release_version }}" - when: k3s_kube_proxy_args is defined and k3s_kube_proxy_args | length > 0 - -- name: Check k3s_kube_apiserver_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "Kube API Server supported in {{ k3s_release_version }}" - fail_msg: "Kube API Server args are not supported in {{ k3s_release_version }}" - when: k3s_kube_apiserver_args is defined and k3s_kube_apiserver_args | length > 0 - -- name: Check k3s_kube_scheduler_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "Kube Scheduler supported in {{ k3s_release_version }}" - fail_msg: "Kube Scheduler args are not supported in {{ k3s_release_version }}" - when: k3s_kube_scheduler_args is defined and k3s_kube_scheduler_args | length > 0 - -- name: Check k3s_kube_controller_manager_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.4.0', '>=') - success_msg: "Kube Controller Manager supported in {{ k3s_release_version }}" - fail_msg: "Kube Controller Manager args are not supported in {{ k3s_release_version }}" - when: k3s_kube_controller_manager_args is defined and k3s_kube_controller_manager_args | length > 0 - -- name: Check k3s_kube_cloud_controller_manager_args against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "Kube Cloud Controller Manager supported in {{ k3s_release_version }}" - fail_msg: "Kube Cloud Controller Manager args are not supported in {{ k3s_release_version }}" - when: k3s_kube_cloud_controller_manager_args is defined and k3s_kube_cloud_controller_manager_args | length > 0 - -- name: Check k3s_flannel_backend against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.10.0', '>=') - success_msg: "Alternate flannel backends supported in {{ k3s_release_version }}" - fail_msg: "Alternate flannel backends are not supported in {{ k3s_release_version }}" - when: k3s_flannel_backend is defined and k3s_flannel_backend - -- name: Check k3s_flannel_backend 'host-gw' configuration against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.17.2', '>=') - success_msg: "host-gw flannel backend supported in {{ k3s_release_version }}" - fail_msg: "host-gw flannel backend is not supported in {{ k3s_release_version }}" - when: k3s_flannel_backend is defined and k3s_flannel_backend == 'host-gw' - -- name: Check k3s_disable_network_policy against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.10.0', '>=') - success_msg: "--disable-network-policy supported in {{ k3s_release_version }}" - fail_msg: "--disable-network-policy not supported in {{ k3s_release_version }}" - when: k3s_disable_network_policy is defined and k3s_disable_network_policy - -- name: Check k3s_private_registry against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('0.10.0', '>=') - success_msg: "--private-registry supported in {{ k3s_release_version }}" - fail_msg: "--private-registry not supported in {{ k3s_release_version }}" - when: k3s_private_registry is defined and k3s_private_registry - -- name: Check k3s_disable_cloud_controller against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--disable-cloud-controller supported in {{ k3s_release_version }}" - fail_msg: "--disable-cloud-controller not supported in {{ k3s_release_version }}" - when: k3s_disable_cloud_controller is defined and k3s_disable_cloud_controller - -- name: Check k3s_disable_scheduler against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--disable-scheduler supported in {{ k3s_release_version }}" - fail_msg: "--disable-scheduler not supported in {{ k3s_release_version }}" - when: k3s_disable_scheduler is defined and k3s_disable_scheduler - -- name: Check k3s_datastore_endpoint against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--datastore-endpoint supported in {{ k3s_release_version }}" - fail_msg: "--datastore-endpoint not supported in {{ k3s_release_version }}" - when: k3s_datastore_endpoint is defined and k3s_datastore_endpoint - -- name: Check k3s_dqlite_datastore against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - - (k3s_release_version | replace('v', '')) is version_compare('1.19.0', '<') - success_msg: "--cluster-init (dqlite) supported in {{ k3s_release_version }}" - fail_msg: "--cluster-init (dqlite) not supported in {{ k3s_release_version }}" - when: k3s_dqlite_datastore is defined and k3s_dqlite_datastore - -- name: Check k3s_etcd_datastore against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.19.1', '>=') - success_msg: "--cluster-init (etcd) supported in {{ k3s_release_version }}" - fail_msg: "--cluster-init (etcd) not supported in {{ k3s_release_version }}" - when: k3s_etcd_datastore is defined and k3s_etcd_datastore - -- name: Check k3s_datastore_cafile against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--datastore-endpoint supported in {{ k3s_release_version }}" - fail_msg: "--datastore-endpoint not supported in {{ k3s_release_version }}" - when: k3s_datastore_cafile is defined and k3s_datastore_cafile - -- name: Check k3s_datastore_certfile against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--datastore-endpoint supported in {{ k3s_release_version }}" - fail_msg: "--datastore-endpoint not supported in {{ k3s_release_version }}" - when: k3s_datastore_certfile is defined and k3s_datastore_certfile - -- name: Check k3s_datastore_keyfile against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "--datastore-endpoint supported in {{ k3s_release_version }}" - fail_msg: "--datastore-endpoint not supported in {{ k3s_release_version }}" - when: k3s_datastore_keyfile is defined and k3s_datastore_keyfile - -- name: Check k3s_default_local_storage_path against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') - success_msg: "Local storage path supported in {{ k3s_release_version }}" - fail_msg: "Local storage path are not supported in {{ k3s_release_version }}" - when: k3s_default_local_storage_path is defined and k3s_default_local_storage_path - -- name: Check k3s_secrets_encryption against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.17.4', '>=') - success_msg: "Secrets encryption at rest supported in {{ k3s_release_version }}" - fail_msg: "Secrets encryption at rest is not supported in {{ k3s_release_version }}" - when: k3s_secrets_encryption is defined and k3s_secrets_encryption - -- name: Check k3s_enable_selinux against k3s version - assert: - that: - - (k3s_release_version | replace('v', '')) is version_compare('1.17.4', '>=') - success_msg: "SELinux supported in {{ k3s_release_version }}" - fail_msg: "SELinux is not supported in {{ k3s_release_version }}" - when: k3s_enable_selinux is defined and k3s_enable_selinux + - (k3s_release_version | replace('v', '')) is version_compare(item.version, '>=') + success_msg: "{{ item.setting }} is supported by {{ k3s_release_version }}" + fail_msg: "{{ item.setting }} is not supported in {{ k3s_release_version }}. Please update to v{{ item.version }} to use this option." + loop: "{{ k3s_config_version_check }}" + when: k3s_config_version_check is defined + and item.setting in k3s_runtime_config diff --git a/tasks/validate/generate-check-config.yml b/tasks/validate/generate-check-config.yml new file mode 100644 index 0000000..30d1c1a --- /dev/null +++ b/tasks/validate/generate-check-config.yml @@ -0,0 +1,5 @@ +--- + +- name: Ensure k3s_runtime_config is set for validation + set_fact: + k3s_runtime_config: "{{ (k3s_server | default({})) | combine (k3s_agent | default({})) }}" diff --git a/tasks/validate/issue-data.yml b/tasks/validate/issue-data.yml new file mode 100644 index 0000000..eede106 --- /dev/null +++ b/tasks/validate/issue-data.yml @@ -0,0 +1,65 @@ +--- + +- name: Ensure facts are gathered + ansible.builtin.setup: + +- name: Ensure Ansible version is captured + command: ansible --version + failed_when: false + changed_when: false + register: check_ansible_version + delegate_to: localhost + run_once: true + become: false + +- name: Ensure Ansible config is captured + command: ansible-config dump --only-changed + failed_when: false + changed_when: false + register: check_ansible_config + delegate_to: localhost + run_once: true + become: false + +- name: Ensure facts are written to disk + ansible.builtin.copy: + dest: pyratlabs-issue-dump.txt + content: | + # Begin ANSIBLE VERSION + {{ check_ansible_version.stdout }} + # End ANSIBLE VERSION + + # Begin ANSIBLE CONFIG + {{ check_ansible_config.stdout }} + # End ANSIBLE CONFIG + + # Begin PLAY HOSTS + {{ play_hosts | to_json }} + # End PLAY HOSTS + + # Begin K3S ROLE CONFIG + {% for host in play_hosts %} + ## {{ host }} + {% for config_key in hostvars[host] | to_json | from_json | json_query('keys(@)[?starts_with(@, `k3s_`)]') %} + {{ config_key }}: {{ hostvars[host][config_key] | to_json }} + {% endfor %} + + {% endfor %} + # End K3S ROLE CONFIG + + # Begin K3S RUNTIME CONFIG + {% for host in play_hosts %} + ## {{ host }} + {{ hostvars[host].k3s_runtime_config }} + {% endfor %} + # End K3S RUNTIME CONFIG + mode: 0600 + delegate_to: localhost + run_once: true + become: false + +- name: Fail the play + ansible.builtin.fail: + msg: Please include the output of pyrat-issue-dump.txt in your bug report. + delegate_to: localhost + run_once: true diff --git a/tasks/validate/main.yml b/tasks/validate/main.yml index 9954a4e..d6fc4f1 100644 --- a/tasks/validate/main.yml +++ b/tasks/validate/main.yml @@ -1,10 +1,13 @@ --- - import_tasks: check-variables.yml + - import_tasks: check-experimental-variables.yml + - import_tasks: check-unsupported-rootless.yml - when: k3s_non_root is defined - and k3s_non_root + when: ("rootless" in k3s_runtime_config) + and k3s_runtime_config.rootless and k3s_use_unsupported_config -- import_tasks: check-controller-count.yml + +- import_tasks: check-control-count.yml when: k3s_build_cluster is defined and k3s_build_cluster diff --git a/tasks/validate/post-install.yml b/tasks/validate/post-install.yml new file mode 100644 index 0000000..dc6aefb --- /dev/null +++ b/tasks/validate/post-install.yml @@ -0,0 +1,5 @@ +--- + +- import_tasks: check-control-plane.yml + +- import_tasks: check-cluster-nodes-ready.yml diff --git a/tasks/validate/pre-flight.yml b/tasks/validate/pre-flight.yml new file mode 100644 index 0000000..d4b3744 --- /dev/null +++ b/tasks/validate/pre-flight.yml @@ -0,0 +1,17 @@ +--- + +- name: Check to see if k3s_state is a supported value + assert: + that: + - k3s_state in k3s_valid_states + fail_msg: "k3s_state not valid. Check README.md for details." + success_msg: "k3s_state is valid." + when: k3s_state is defined + +- import_tasks: generate-check-config.yml + +- import_tasks: check-environment.yml + when: not k3s_skip_validation + +- include_tasks: issue-data.yml + when: pyratlabs_issue_controller_dump is defined and pyratlabs_issue_controller_dump diff --git a/templates/config.yaml.j2 b/templates/config.yaml.j2 new file mode 100644 index 0000000..3a17499 --- /dev/null +++ b/templates/config.yaml.j2 @@ -0,0 +1,8 @@ +--- + +{% if k3s_etcd_datastore and (k3s_control_node is defined and k3s_control_node) and (k3s_primary_control_node is defined and k3s_primary_control_node) %} +cluster-init: true +{% endif %} +{% if k3s_runtime_config is defined and k3s_runtime_config | length > 0 %} +{{ k3s_runtime_config | to_nice_yaml(indent=2) }} +{% endif %} diff --git a/templates/k3s-killall.sh.j2 b/templates/k3s-killall.sh.j2 index 0a1f0e2..98c67a4 100644 --- a/templates/k3s-killall.sh.j2 +++ b/templates/k3s-killall.sh.j2 @@ -62,7 +62,7 @@ do_unmount() { } do_unmount '/run/k3s' -do_unmount '{{ k3s_node_data_dir | default('/var/lib/rancher/k3s') }}' +do_unmount '{{ k3s_runtime_config['data-dir'] | default('/var/lib/rancher/k3s') }}' do_unmount '/var/lib/kubelet/pods' do_unmount '/run/netns/cni-' diff --git a/templates/k3s-uninstall.sh.j2 b/templates/k3s-uninstall.sh.j2 index b660ec1..e85c64b 100644 --- a/templates/k3s-uninstall.sh.j2 +++ b/templates/k3s-uninstall.sh.j2 @@ -55,7 +55,7 @@ for bin in {{ k3s_install_dir }}/k3s*; do done [ -d /etc/rancher/k3s ] && rm -rf /etc/rancher/k3s -[ -d {{ k3s_node_data_dir | default('/var/lib/rancher/k3s') }} ] && rm -rf {{ k3s_node_data_dir | default('/var/lib/rancher/k3s') }} +[ -d {{ k3s_runtime_config['data-dir'] | default('/var/lib/rancher/k3s') }} ] && rm -rf {{ k3s_runtime_config['data-dir'] | default('/var/lib/rancher/k3s') }} [ -d /var/lib/kubelet ] && rm -rf /var/lib/kubelet [ -f /usr/local/bin/k3s-killall.sh ] && rm -f /usr/local/bin/k3s-killall.sh diff --git a/templates/k3s.service.j2 b/templates/k3s.service.j2 index 308c13c..1ce9119 100644 --- a/templates/k3s.service.j2 +++ b/templates/k3s.service.j2 @@ -16,195 +16,21 @@ ExecStart={{ k3s_install_dir }}/k3s {% endif %} {% if k3s_control_node %} server - {% if k3s_bind_address is defined %} - --bind-address {{ k3s_bind_address }} + {% if (k3s_etcd_datastore is defined and k3s_etcd_datastore) and (k3s_primary_control_node is not defined or not k3s_primary_control_node) %} + --server https://{{ k3s_control_node_address }}:{{ k3s_runtime_config['https-listen-port'] | default(6443) }} + --token-file {{ k3s_token_location }}/cluster-token {% endif %} - {% if k3s_advertise_address is defined %} - --advertise-address {{ k3s_advertise_address }} - {% endif %} - {% if k3s_non_root is defined and k3s_non_root %} - --rootless - {% endif %} - {% if k3s_https_port != 6443 %} - --https-listen-port {{ k3s_https_port }} - {% endif %} - {% if k3s_disable_scheduler %} - --disable-scheduler - {% endif %} - {% if k3s_disable_cloud_controller %} - --disable-cloud-controller - {% endif %} - {% if k3s_disable_network_policy %} - --disable-network-policy - {% endif %} - {% if k3s_disable_kube_proxy %} - --disable-kube-proxy - {% endif %} - {% if k3s_no_flannel %} - {% if (k3s_release_version | replace('v', '')) is version_compare('1.0.0', '>=') %} - --flannel-backend none - {% else %} - --no-flannel - {% endif %} - {% endif %} - {% if k3s_cluster_cidr is defined %} - --cluster-cidr {{ k3s_cluster_cidr }} - {% endif %} - {% if k3s_service_cidr is defined %} - --service-cidr {{ k3s_service_cidr }} - {% endif %} - {% if k3s_flannel_backend is defined and not k3s_no_flannel %} - --flannel-backend {{ k3s_flannel_backend }} - {% endif %} - {% if k3s_private_registry is defined and k3s_private_registry %} - --private-registry {{ k3s_private_registry }} - {% endif %} - {{ ' --disable coredns' if k3s_no_coredns else '' }}{{ ' --disable servicelb' if k3s_no_servicelb else '' }}{{ ' --disable traefik' if k3s_no_traefik else '' }}{{ ' --disable local-storage' if k3s_no_local_storage else '' }}{{ ' --disable metrics-server' if k3s_no_metrics_server else '' }} - {% if not k3s_no_local_storage and k3s_default_local_storage_path is defined and k3s_default_local_storage_path %} - --default-local-storage-path {{ k3s_default_local_storage_path }} - {% endif %} - {% if k3s_cluster_dns is defined and k3s_cluster_dns %} - --cluster-dns {{ k3s_cluster_dns }} - {% endif %} - {% if k3s_cluster_domain is defined and k3s_cluster_domain != "cluster.local" %} - --cluster-domain {{ k3s_cluster_domain }} - {% endif %} - {% if k3s_datastore_endpoint is defined and k3s_datastore_endpoint %} - --datastore-endpoint "{{ k3s_datastore_endpoint }}" - {% if k3s_datastore_cafile is defined and k3s_datastore_cafile %} - --datastore-cafile {{ k3s_datastore_cafile }} - {% endif %} - {% if k3s_datastore_certfile is defined and k3s_datastore_certfile %} - --datastore-certfile {{ k3s_datastore_certfile }} - {% endif %} - {% if k3s_datastore_keyfile is defined and k3s_datastore_keyfile %} - --datastore-keyfile {{ k3s_datastore_keyfile }} - {% endif %} - {% endif %} - {% if (k3s_dqlite_datastore is defined and k3s_dqlite_datastore) or (k3s_etcd_datastore is defined and k3s_etcd_datastore) %} - {% if k3s_primary_control_node is defined and k3s_primary_control_node %} - --cluster-init - {% else %} - --server https://{{ k3s_control_node_address }}:{{ k3s_https_port }} - --token-file {{ k3s_token_location }}/cluster-token - {% endif %} - {% if k3s_etcd_disable_snapshots %} - --etcd-disable-snapshots - {% else %} - {% if k3s_etcd_snapshot_schedule_cron is defined %} - --etcd-snapshot-schedule-cron "{{ k3s_etcd_snapshot_schedule_cron }}" - {% endif %} - {% if k3s_etcd_snapshot_retention is defined %} - --etcd-snapshot-retention {{ k3s_etcd_snapshot_retention }} - {% endif %} - {% if k3s_etcd_snapshot_directory is defined %} - --etcd-snapshot-dir {{ k3s_etcd_snapshot_directory }} - {% endif %} - {% endif %} - {% endif %} - {% if k3s_secrets_encryption is defined and k3s_secrets_encryption %} - --secrets-encryption - {% endif %} - {% if k3s_kube_apiserver_args is defined and k3s_kube_apiserver_args is iterable %} - {% for arg in k3s_kube_apiserver_args %} - {% for key, value in arg.items() %} - --kube-apiserver-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} - {% endif %} - {% if k3s_kube_scheduler_args is defined and k3s_kube_scheduler_args is iterable %} - {% for arg in k3s_kube_scheduler_args %} - {% for key, value in arg.items() %} - --kube-scheduler-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} - {% endif %} - {% if k3s_kube_controller_manager_args is defined and k3s_kube_controller_manager_args is iterable %} - {% for arg in k3s_kube_controller_manager_args %} - {% for key, value in arg.items() %} - --kube-controller-manager-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} - {% endif %} - {% if k3s_kube_cloud_controller_manager_args is defined and k3s_kube_cloud_controller_manager_args is iterable %} - {% for arg in k3s_kube_cloud_controller_manager_args %} - {% for key, value in arg.items() %} - --kube-cloud-controller-manager-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} + {% if k3s_server is defined %} + --config {{ k3s_config_file }} {% endif %} {% else %} agent - --server https://{{ k3s_control_node_address }}:{{ k3s_https_port }} + --server https://{{ k3s_control_node_address }}:{{ k3s_runtime_config['https-listen-port'] | default(6443) }} --token-file {{ k3s_token_location }}/cluster-token -{% endif %} -{% if k3s_enable_selinux %} - --selinux -{% endif %} -{% if k3s_resolv_conf is defined and k3s_resolv_conf %} - --resolv-conf {{ k3s_resolv_conf }} -{% endif %} -{% if k3s_tls_san is defined and k3s_tls_san is iterable %} - {% for san in k3s_tls_san %} - --tls-san {{ san }} - {% endfor %} -{% else %} - {% if k3s_tls_san is defined and k3s_tls_san %} - --tls-san {{ k3s_tls_san }} + {% if k3s_agent is defined %} + --config {{ k3s_config_file }} {% endif %} {% endif %} -{% if k3s_node_data_dir is defined %} - --data-dir {{ k3s_node_data_dir }} -{% endif %} -{% if k3s_use_docker %} - --docker -{% endif %} -{% if k3s_flannel_interface is defined and not k3s_no_flannel %} - --flannel-iface {{ k3s_flannel_interface }} -{% endif %} -{% if k3s_node_name is defined %} - --node-name {{ k3s_node_name }} -{% endif %} -{% if k3s_node_id is defined %} - --with-node-id {{ k3s_node_id }} -{% endif %} -{% if k3s_node_ip_address is defined %} - --node-ip {{ k3s_node_ip_address }} -{% endif %} -{% if k3s_node_external_address is defined %} - --node-external-ip {{ k3s_node_external_address }} -{% endif %} -{% if k3s_write_kubeconfig_mode is defined %} - --write-kubeconfig-mode {{ k3s_write_kubeconfig_mode }} -{% endif %} -{% if k3s_node_labels is defined and k3s_node_labels is iterable %} - {% for label in k3s_node_labels %} - {% for key, value in label.items() %} - --node-label {{ key }}={{ value }} - {% endfor %} - {% endfor %} -{% endif %} -{% if k3s_node_taints is defined and k3s_node_taints is iterable %} - {% for taint in k3s_node_taints %} - {% for key, value in taint.items() %} - --node-taint {{ key }}={{ value }} - {% endfor %} - {% endfor %} -{% endif %} -{% if k3s_kubelet_args is defined and k3s_kubelet_args is iterable %} - {% for arg in k3s_kubelet_args %} - {% for key, value in arg.items() %} - --kubelet-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} -{% endif %} -{% if k3s_kube_proxy_args is defined and k3s_kube_proxy_args is iterable %} - {% for arg in k3s_kube_proxy_args %} - {% for key, value in arg.items() %} - --kube-proxy-arg {{ key }}={{ value }} - {% endfor %} - {% endfor %} -{% endif %} {% endfilter %} {% endfilter %} diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile deleted file mode 100644 index c3adc2b..0000000 --- a/vagrant/Vagrantfile +++ /dev/null @@ -1,96 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -$centos_provision = <