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/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 21e9e28..cdc4e06 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ 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 @@ -34,6 +38,8 @@ This role has been tested against the following Linux Distributions: :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 k3s is being used in production, however at the @@ -46,71 +52,111 @@ 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_state` | State of k3s: installed, started, stopped, restarted, downloaded, uninstalled, validated. | 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` @@ -119,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 @@ -129,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 ``` @@ -196,47 +241,6 @@ 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_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 @@ -244,9 +248,9 @@ do not set a host as a control node, this role will automatically delegate 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. @@ -254,7 +258,7 @@ 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 +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 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 b32f696..534dfd8 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -49,22 +49,20 @@ k3s_etcd_datastore: false # Server Configuration ## +k3s_server: {} # k3s_server: # listen-port: 6443 -k3s_server: null - ## # Agent Configuration ## +k3s_agent: {} # k3s_agent: # node-label: # - "foo=bar" # - "bish=bosh" -k3s_agent: null - ## # Ansible Controller configuration ## diff --git a/meta/main.yml b/meta/main.yml index 80714b1..475851d 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/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/converge.yml b/molecule/default/converge.yml index 2a437a2..aa6404d 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -5,6 +5,5 @@ vars: molecule_is_test: true k3s_install_hard_links: true - k3s_release_version: latest roles: - role: xanmanning.k3s diff --git a/molecule/highavailabilitydb/converge.yml b/molecule/highavailabilitydb/converge.yml index 8bf8aa1..bf02a66 100644 --- a/molecule/highavailabilitydb/converge.yml +++ b/molecule/highavailabilitydb/converge.yml @@ -1,4 +1,5 @@ --- + - name: Converge hosts: node* become: true diff --git a/molecule/highavailabilityetcd/converge.yml b/molecule/highavailabilityetcd/converge.yml index b23c043..41cd30f 100644 --- a/molecule/highavailabilityetcd/converge.yml +++ b/molecule/highavailabilityetcd/converge.yml @@ -1,10 +1,10 @@ --- + - name: Converge hosts: node* become: true vars: molecule_is_test: true - k3s_release_version: latest k3s_use_experimental: true k3s_etcd_datastore: true k3s_server: diff --git a/molecule/nodeploy/converge.yml b/molecule/nodeploy/converge.yml index 28e4f48..954e451 100644 --- a/molecule/nodeploy/converge.yml +++ b/molecule/nodeploy/converge.yml @@ -4,23 +4,7 @@ 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 + 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/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.yml b/tasks/build/install-k3s.yml index 1fc5ff0..0da9195 100644 --- a/tasks/build/install-k3s.yml +++ b/tasks/build/install-k3s.yml @@ -21,6 +21,7 @@ - meta: flush_handlers - 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 7fae4b5..1a9d869 100644 --- a/tasks/build/preconfigure-k3s.yml +++ b/tasks/build/preconfigure-k3s.yml @@ -77,12 +77,12 @@ - name: Ensure k3s_runtime_config is set for control plane set_fact: - k3s_runtime_config: "{{ (k3s_server | default('None')) | combine (k3s_agent | default('None')) }}" - when: k3s_server is defined + 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('None') }}" + 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/state-installed.yml b/tasks/state-installed.yml index e1f30e4..a6fc95a 100644 --- a/tasks/state-installed.yml +++ b/tasks/state-installed.yml @@ -28,6 +28,8 @@ 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 - import_tasks: build/preconfigure-k3s-auto-deploying-manifests.yml diff --git a/tasks/validate/check-control-count.yml b/tasks/validate/check-control-count.yml index 59c5614..88e3642 100644 --- a/tasks/validate/check-control-count.yml +++ b/tasks/validate/check-control-count.yml @@ -10,6 +10,7 @@ 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: @@ -20,6 +21,7 @@ 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: @@ -31,3 +33,4 @@ 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-experimental-variables.yml b/tasks/validate/check-experimental-variables.yml index 6b4c1d0..d01419b 100644 --- a/tasks/validate/check-experimental-variables.yml +++ b/tasks/validate/check-experimental-variables.yml @@ -6,7 +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: ("rootless" in k3s_runtime_config and k3s_runtime_config['rootless']) - or (k3s_etcd_datastore is defined and k3s_etcd_datastore) - or ("secrets-encryption" in k3s_runtime_config and k3s_runtime_config['secrets-encryption']) - or ("selinux" in k3s_runtime_config and k3s_runtime_config['selinux']) + loop: "{{ k3s_experimental_config }}" + when: k3s_etcd_datastore is defined and k3s_etcd_datastore + +- name: Check if any experimental variables are configure and if they are enabled with k3s_use_experimental + assert: + that: + - 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-variables.yml b/tasks/validate/check-variables.yml index 5237bff..265a2b7 100644 --- a/tasks/validate/check-variables.yml +++ b/tasks/validate/check-variables.yml @@ -1,13 +1,13 @@ --- -- name: Check that k3s_release_version >= 1.19.0 +- name: "Check that k3s_release_version >= {{ k3s_min_version }}" assert: that: - - (k3s_release_version | replace('v', '')) is version_compare('1.19.0', '>=') + - (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 configuration in k3s_server and k3s_agent +- name: Check configuration in k3s_server and k3s_agent that needs special configuration. assert: that: - (item.setting not in k3s_runtime_config) @@ -15,5 +15,12 @@ fail_msg: "{{ item.setting }} found in server/agent config. Please set {{ item.correction }} to use this option." loop: "{{ k3s_config_exclude }}" -# Due to the v2 role now only supporting k3s v1.19+ - this file is intentionlly -# blank until new configuration options are added. +- name: Check configuration in k3s_server and k3s_agent against release version + assert: + that: + - (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 index 3eb9dad..30d1c1a 100644 --- a/tasks/validate/generate-check-config.yml +++ b/tasks/validate/generate-check-config.yml @@ -2,4 +2,4 @@ - name: Ensure k3s_runtime_config is set for validation set_fact: - k3s_runtime_config: "{{ (k3s_server | default('None')) | combine (k3s_agent | default('None')) }}" + 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/pre-flight.yml b/tasks/validate/pre-flight.yml index a1495d8..d4b3744 100644 --- a/tasks/validate/pre-flight.yml +++ b/tasks/validate/pre-flight.yml @@ -12,3 +12,6 @@ - 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/vars/main.yml b/vars/main.yml index 8428ad9..5cd4635 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,5 +1,8 @@ --- +# Minimum supported version +k3s_min_version: 1.19.3 + # Valid states for this role k3s_valid_states: - installed @@ -66,7 +69,19 @@ k3s_token_location: "/etc/rancher" # https://rancher.com/docs/k3s/latest/en/advanced/#auto-deploying-manifests k3s_server_manifests_dir: /var/lib/rancher/k3s/server/manifests -# Items that should not appear in k3s_server or k3s_agent +# Config items that should not appear in k3s_server or k3s_agent k3s_config_exclude: - setting: "cluster-init" correction: "k3s_etcd_datastore" + +# Config items and the versions that they were introduced +# k3s_config_version_check: +# - setting: example +# version: 1.19.3 + +# Config items that should be marked as experimental +k3s_experimental_config: + - setting: selinux + until: 1.19.4 + - setting: rootless + - setting: secrets-encryption