From ae90b3dff9757a287a8551930ac3341a3b10eb1c Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 2 Feb 2026 14:40:46 +0300 Subject: [PATCH 01/11] docs(install): add documentation for generic Kubernetes deployment Add comprehensive guide for deploying Cozystack on non-Talos Kubernetes distributions (k3s, kubeadm, RKE2) using the isp-full-generic bundle. Documentation includes: - Host and sysctl requirements - Kubernetes configuration for each distribution - Step-by-step installation instructions - Example Ansible playbooks - Troubleshooting section Related: cozystack/cozystack#1950 Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/_index.md | 18 +- content/en/docs/install/kubernetes/generic.md | 402 ++++++++++++++++++ 2 files changed, 416 insertions(+), 4 deletions(-) create mode 100644 content/en/docs/install/kubernetes/generic.md diff --git a/content/en/docs/install/kubernetes/_index.md b/content/en/docs/install/kubernetes/_index.md index d908726c..70f71469 100644 --- a/content/en/docs/install/kubernetes/_index.md +++ b/content/en/docs/install/kubernetes/_index.md @@ -1,7 +1,7 @@ --- -title: "Installing and Configuring Kubernetes Cluster on Talos Linux" +title: "Installing and Configuring Kubernetes Cluster" linkTitle: "2. Install Kubernetes" -description: "Step 2: Installing and configuring a Kubernetes cluster on Talos Linux nodes, ready for Cozystack installation." +description: "Step 2: Installing and configuring a Kubernetes cluster ready for Cozystack installation." weight: 20 aliases: - /docs/operations/talos/configuration @@ -10,14 +10,18 @@ aliases: --- -**The second step** in deploying a Cozystack cluster is to install and configure a Kubernetes cluster on Talos Linux nodes. -A prerequisite to this step is having [installed Talos Linux]({{% ref "/docs/install/talos" %}}). +**The second step** in deploying a Cozystack cluster is to install and configure a Kubernetes cluster. The result is a Kubernetes cluster installed, configured, and ready to install Cozystack. If this is your first time installing Cozystack, [start with the Cozystack tutorial]({{% ref "/docs/getting-started" %}}). ## Installation Options +### Talos Linux (Recommended) + +For production deployments, Cozystack recommends [Talos Linux]({{% ref "/docs/guides/talos" %}}) as the underlying operating system. +A prerequisite to using these methods is having [installed Talos Linux]({{% ref "/docs/install/talos" %}}). + There are several methods to configure Talos nodes and bootstrap a Kubernetes cluster: - **Recommended**: [using Talm]({{% ref "./talm" %}}), a declarative CLI tool, which has ready presets for Cozystack and uses the power of Talos API under the hood. @@ -25,6 +29,12 @@ There are several methods to configure Talos nodes and bootstrap a Kubernetes cl - [Using talosctl]({{% ref "./talosctl" %}}), a specialized command line tool for managing Talos. - [Air-gapped installation]({{% ref "./air-gapped" %}}) is possible with Talm or talosctl. +### Generic Kubernetes + +Cozystack can also be deployed on other Kubernetes distributions: + +- [Generic Kubernetes]({{% ref "./generic" %}}) — deploy Cozystack on k3s, kubeadm, RKE2, or other distributions. + If you encounter problems with installation, refer to the [Troubleshooting section]({{% ref "./troubleshooting" %}}). ## Further Steps diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md new file mode 100644 index 00000000..6ac10e5d --- /dev/null +++ b/content/en/docs/install/kubernetes/generic.md @@ -0,0 +1,402 @@ +--- +title: "Deploying Cozystack on Generic Kubernetes" +linkTitle: "Generic Kubernetes" +description: "How to deploy Cozystack on k3s, kubeadm, RKE2, or other Kubernetes distributions without Talos Linux" +weight: 50 +--- + +This guide explains how to deploy Cozystack on generic Kubernetes distributions such as k3s, kubeadm, or RKE2. +While Talos Linux remains the recommended platform for production deployments, Cozystack supports deployment on other Kubernetes distributions using the `isp-full-generic` bundle. + +## When to Use Generic Kubernetes + +Consider using generic Kubernetes instead of Talos Linux when: + +- You have an existing Kubernetes cluster you want to enhance with Cozystack +- Your infrastructure doesn't support Talos Linux (certain cloud providers, embedded systems) +- You need specific Linux features or packages not available in Talos + +For new production deployments, [Talos Linux]({{% ref "/docs/guides/talos" %}}) is recommended due to its security and operational benefits. + +## Prerequisites + +### Supported Distributions + +Cozystack has been tested on: + +- **k3s** v1.32+ (recommended for single-node and edge deployments) +- **kubeadm** v1.28+ +- **RKE2** v1.28+ + +### Host Requirements + +- **Operating System**: Ubuntu 22.04+ or Debian 12+ (kernel 5.x+ with systemd) +- **Architecture**: amd64 or arm64 +- **Hardware**: See [hardware requirements]({{% ref "/docs/install/hardware-requirements" %}}) + +### Required Packages + +Install the following packages on all nodes: + +```bash +apt-get update +apt-get install -y nfs-common open-iscsi multipath-tools +``` + +### Required Services + +Enable and start required services: + +```bash +systemctl enable --now iscsid +systemctl enable --now multipathd +``` + +## Sysctl Configuration + +{{% alert color="warning" %}} +:warning: **Critical**: The sysctl settings below are mandatory for Cozystack to function properly. +Without these settings, Kubernetes components will fail due to insufficient inotify watches. +{{% /alert %}} + +Create `/etc/sysctl.d/99-cozystack.conf` with the following content: + +```ini +# Inotify limits (critical for Cozystack) +fs.inotify.max_user_watches = 2099999999 +fs.inotify.max_user_instances = 2099999999 +fs.inotify.max_queued_events = 2099999999 + +# Filesystem limits +fs.file-max = 2097152 +fs.aio-max-nr = 1048576 + +# Network forwarding (required for Kubernetes) +net.ipv4.ip_forward = 1 +net.ipv4.conf.all.forwarding = 1 +net.bridge.bridge-nf-call-iptables = 1 +net.bridge.bridge-nf-call-ip6tables = 1 + +# VM tuning +vm.swappiness = 1 +``` + +Apply the settings: + +```bash +sysctl --system +``` + +## Kubernetes Configuration + +Cozystack manages its own networking (Cilium/KubeOVN), storage (LINSTOR), and ingress (NGINX). +Your Kubernetes distribution must be configured to **not** install these components. + +### Required Configuration + +| Component | Requirement | +|-----------|-------------| +| CNI | **Disabled** — Cozystack deploys Cilium or KubeOVN | +| Ingress Controller | **Disabled** — Cozystack deploys NGINX | +| Storage Provisioner | **Disabled** — Cozystack deploys LINSTOR | +| kube-proxy | **Disabled** — Cilium replaces it | +| Cluster Domain | Must be `cozy.local` | + +### k3s Configuration + +When installing k3s, use the following flags: + +```bash +curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \ + --disable=traefik \ + --disable=servicelb \ + --disable=local-storage \ + --disable-network-policy \ + --disable-kube-proxy \ + --flannel-backend=none \ + --cluster-domain=cozy.local \ + --tls-san= \ + --kubelet-arg=max-pods=220" sh - +``` + +Replace `` with your node's IP address. + +### kubeadm Configuration + +Create a kubeadm configuration file: + +```yaml +apiVersion: kubeadm.k8s.io/v1beta3 +kind: ClusterConfiguration +networking: + podSubnet: "10.244.0.0/16" + serviceSubnet: "10.96.0.0/16" + dnsDomain: "cozy.local" +--- +apiVersion: kubeproxy.config.k8s.io/v1alpha1 +kind: KubeProxyConfiguration +mode: "none" # Cilium will replace kube-proxy +``` + +Initialize the cluster without the default CNI: + +```bash +kubeadm init --config kubeadm-config.yaml --skip-phases=addon/kube-proxy +``` + +### RKE2 Configuration + +Create `/etc/rancher/rke2/config.yaml`: + +```yaml +cni: none +disable: + - rke2-ingress-nginx + - rke2-metrics-server +cluster-domain: cozy.local +disable-kube-proxy: true +``` + +## Installing Cozystack + +### 1. Apply CRDs + +Download and apply Custom Resource Definitions: + +```bash +kubectl apply -f https://github.com/cozystack/cozystack/releases/latest/download/cozystack-crds.yaml +``` + +### 2. Create Namespace + +```bash +kubectl create namespace cozy-system +``` + +### 3. Create ConfigMap + +Create `cozystack-config.yaml` with your cluster configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cozystack + namespace: cozy-system +data: + bundle-name: "isp-full-generic" + root-host: "example.com" + api-server-endpoint: "https://:6443" + ipv4-pod-cidr: "10.42.0.0/16" + ipv4-pod-gateway: "10.42.0.1" + ipv4-svc-cidr: "10.43.0.0/16" + ipv4-join-cidr: "100.64.0.0/16" +``` + +Adjust the values: + +| Field | Description | +|-------|-------------| +| `bundle-name` | Must be `isp-full-generic` for non-Talos clusters | +| `root-host` | Your domain for Cozystack services | +| `api-server-endpoint` | Kubernetes API endpoint URL | +| `ipv4-pod-cidr` | Pod network CIDR (must match your k8s config) | +| `ipv4-svc-cidr` | Service network CIDR (must match your k8s config) | +| `ipv4-join-cidr` | Network for nested cluster communication | + +Apply the ConfigMap: + +```bash +kubectl apply -f cozystack-config.yaml +``` + +### 4. Deploy Cozystack Operator + +Apply the generic operator manifest: + +```bash +kubectl apply -f https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml +``` + +### 5. Monitor Installation + +Watch the installation progress: + +```bash +kubectl logs -n cozy-system deploy/cozystack -f +``` + +Check HelmRelease status: + +```bash +kubectl get hr -A +``` + +When complete, all releases will show `READY: True`. + +## Example: Ansible Playbook + +Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. + +### Node Preparation Playbook + +```yaml +--- +- name: Prepare nodes for Cozystack + hosts: all + become: true + tasks: + - name: Install required packages + ansible.builtin.apt: + name: + - nfs-common + - open-iscsi + - multipath-tools + state: present + update_cache: true + + - name: Configure sysctl for Cozystack + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + state: present + reload: true + loop: + - { name: fs.inotify.max_user_watches, value: "2099999999" } + - { name: fs.inotify.max_user_instances, value: "2099999999" } + - { name: fs.inotify.max_queued_events, value: "2099999999" } + - { name: net.ipv4.ip_forward, value: "1" } + - { name: net.ipv4.conf.all.forwarding, value: "1" } + + - name: Enable iscsid service + ansible.builtin.systemd: + name: iscsid + enabled: true + state: started + + - name: Enable multipathd service + ansible.builtin.systemd: + name: multipathd + enabled: true + state: started +``` + +### Cozystack Deployment Playbook + +```yaml +--- +- name: Deploy Cozystack + hosts: localhost + connection: local + vars: + cozystack_root_host: "example.com" + cozystack_api_endpoint: "https://10.0.0.1:6443" + cozystack_pod_cidr: "10.42.0.0/16" + cozystack_svc_cidr: "10.43.0.0/16" + tasks: + - name: Apply Cozystack CRDs + kubernetes.core.k8s: + src: https://github.com/cozystack/cozystack/releases/latest/download/cozystack-crds.yaml + state: present + + - name: Create cozy-system namespace + kubernetes.core.k8s: + state: present + definition: + apiVersion: v1 + kind: Namespace + metadata: + name: cozy-system + + - name: Create Cozystack ConfigMap + kubernetes.core.k8s: + state: present + definition: + apiVersion: v1 + kind: ConfigMap + metadata: + name: cozystack + namespace: cozy-system + data: + bundle-name: "isp-full-generic" + root-host: "{{ cozystack_root_host }}" + api-server-endpoint: "{{ cozystack_api_endpoint }}" + ipv4-pod-cidr: "{{ cozystack_pod_cidr }}" + ipv4-pod-gateway: "{{ cozystack_pod_cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" + ipv4-svc-cidr: "{{ cozystack_svc_cidr }}" + ipv4-join-cidr: "100.64.0.0/16" + + - name: Apply Cozystack operator + kubernetes.core.k8s: + src: https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml + state: present +``` + +## Troubleshooting + +### linstor-scheduler Image Tag Invalid + +**Symptom**: `InvalidImageName` error for linstor-scheduler pod. + +**Cause**: k3s version format (e.g., `v1.35.0+k3s1`) contains `+` which is invalid in Docker image tags. + +**Solution**: This is fixed in Cozystack v1.0.0+. Ensure you're using the latest release. + +### KubeOVN Not Scheduling + +**Symptom**: ovn-central pods stuck in Pending state. + +**Cause**: KubeOVN uses Helm `lookup` to find control-plane nodes, which may fail on fresh clusters. + +**Solution**: Ensure your Platform Package includes explicit `MASTER_NODES` configuration: + +```yaml +spec: + components: + networking: + values: + kube-ovn: + MASTER_NODES: "" +``` + +### Cilium Cannot Reach API Server + +**Symptom**: Cilium pods in CrashLoopBackOff with API connection errors. + +**Cause**: Single-node clusters or non-standard API endpoints require explicit configuration. + +**Solution**: Verify your ConfigMap includes correct `api-server-endpoint` and ensure the Platform Package has: + +```yaml +spec: + components: + networking: + values: + cilium: + k8sServiceHost: "" + k8sServicePort: "6443" +``` + +### Inotify Limit Errors + +**Symptom**: Pods failing with "too many open files" or inotify errors. + +**Cause**: Default Linux inotify limits are too low for Kubernetes. + +**Solution**: Apply sysctl settings from the [Sysctl Configuration](#sysctl-configuration) section and reboot the node. + +## Further Steps + +After Cozystack installation completes: + +1. [Configure storage with LINSTOR]({{% ref "/docs/getting-started/install-cozystack#3-configure-storage" %}}) +2. [Set up the root tenant]({{% ref "/docs/getting-started/install-cozystack#4-access-the-dashboard" %}}) +3. [Deploy your first application]({{% ref "/docs/applications" %}}) + +## References + +- [PR #1939: Non-Talos Kubernetes Support](https://github.com/cozystack/cozystack/pull/1939) +- [Issue #1950: Complete non-Talos Support](https://github.com/cozystack/cozystack/issues/1950) +- [k3s Documentation](https://docs.k3s.io/) +- [kubeadm Documentation](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/) From 7d8260e650f02990638d4bd0532d03be1a7300cd Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 2 Feb 2026 14:46:26 +0300 Subject: [PATCH 02/11] docs(generic): clarify CIDR configuration per distribution Add explicit warning that pod/service CIDRs must match the Kubernetes distribution defaults: - k3s: 10.42.0.0/16, 10.43.0.0/16 - kubeadm: 10.244.0.0/16, 10.96.0.0/16 - RKE2: 10.42.0.0/16, 10.43.0.0/16 Note: inotify limits (2099999999) are intentional and required for Cozystack operation - standard values are insufficient. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 6ac10e5d..0c0f0ba6 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -175,7 +175,17 @@ kubectl create namespace cozy-system ### 3. Create ConfigMap -Create `cozystack-config.yaml` with your cluster configuration: +Create `cozystack-config.yaml` with your cluster configuration. + +{{% alert color="warning" %}} +:warning: **Important**: The `ipv4-pod-cidr` and `ipv4-svc-cidr` values **must match** your Kubernetes cluster configuration. +Different distributions use different defaults: +- **k3s**: `10.42.0.0/16` (pods), `10.43.0.0/16` (services) +- **kubeadm**: `10.244.0.0/16` (pods), `10.96.0.0/16` (services) +- **RKE2**: `10.42.0.0/16` (pods), `10.43.0.0/16` (services) +{{% /alert %}} + +Example for **k3s** (adjust CIDRs for other distributions): ```yaml apiVersion: v1 @@ -284,6 +294,8 @@ Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. ### Cozystack Deployment Playbook +This example uses k3s default CIDRs. Adjust for kubeadm (`10.244.0.0/16`, `10.96.0.0/16`) or your custom configuration. + ```yaml --- - name: Deploy Cozystack @@ -292,6 +304,7 @@ Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. vars: cozystack_root_host: "example.com" cozystack_api_endpoint: "https://10.0.0.1:6443" + # k3s defaults - adjust for kubeadm (10.244.0.0/16, 10.96.0.0/16) cozystack_pod_cidr: "10.42.0.0/16" cozystack_svc_cidr: "10.43.0.0/16" tasks: From ddaa642d0a4bcc9a660d7ada140e6b8f44338546 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 2 Feb 2026 14:50:29 +0300 Subject: [PATCH 03/11] docs: fix style issues from CodeRabbit review - Hyphenate "command-line" in _index.md - Add spaces to table separators (MD060) Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/_index.md | 2 +- content/en/docs/install/kubernetes/generic.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/install/kubernetes/_index.md b/content/en/docs/install/kubernetes/_index.md index 70f71469..80552f70 100644 --- a/content/en/docs/install/kubernetes/_index.md +++ b/content/en/docs/install/kubernetes/_index.md @@ -26,7 +26,7 @@ There are several methods to configure Talos nodes and bootstrap a Kubernetes cl - **Recommended**: [using Talm]({{% ref "./talm" %}}), a declarative CLI tool, which has ready presets for Cozystack and uses the power of Talos API under the hood. - [Using `talos-bootstrap`]({{% ref "./talos-bootstrap" %}}), an interactive script for bootstrapping Kubernetes clusters on Talos OS. -- [Using talosctl]({{% ref "./talosctl" %}}), a specialized command line tool for managing Talos. +- [Using talosctl]({{% ref "./talosctl" %}}), a specialized command-line tool for managing Talos. - [Air-gapped installation]({{% ref "./air-gapped" %}}) is possible with Talm or talosctl. ### Generic Kubernetes diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 0c0f0ba6..c43d9736 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -95,7 +95,7 @@ Your Kubernetes distribution must be configured to **not** install these compone ### Required Configuration | Component | Requirement | -|-----------|-------------| +| ----------- | ------------- | | CNI | **Disabled** — Cozystack deploys Cilium or KubeOVN | | Ingress Controller | **Disabled** — Cozystack deploys NGINX | | Storage Provisioner | **Disabled** — Cozystack deploys LINSTOR | @@ -206,7 +206,7 @@ data: Adjust the values: | Field | Description | -|-------|-------------| +| ------- | ------------- | | `bundle-name` | Must be `isp-full-generic` for non-Talos clusters | | `root-host` | Your domain for Cozystack services | | `api-server-endpoint` | Kubernetes API endpoint URL | From 500ba858466bae8d668e1b100a0a6ee008d79b3a Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Feb 2026 12:55:48 +0300 Subject: [PATCH 04/11] [docs] Add cozystack-operator-config ConfigMap step to generic install guide The generic operator manifest reads KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT from a ConfigMap named cozystack-operator-config. Without this ConfigMap, the operator pod fails to start with CreateContainerConfigError. Add the missing step to both the manual instructions and the Ansible playbook example. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index c43d9736..a8668611 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -220,7 +220,31 @@ Apply the ConfigMap: kubectl apply -f cozystack-config.yaml ``` -### 4. Deploy Cozystack Operator +### 4. Create Operator Configuration + +The generic operator manifest reads the Kubernetes API server address from a ConfigMap. +You **must** create this ConfigMap before deploying the operator, otherwise the operator pod will fail to start. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cozystack-operator-config + namespace: cozy-system +data: + KUBERNETES_SERVICE_HOST: "" + KUBERNETES_SERVICE_PORT: "6443" +``` + +Replace `` with the IP address of your Kubernetes API server (the same address used in `api-server-endpoint` above, without the `https://` prefix and port). + +Apply it: + +```bash +kubectl apply -f cozystack-operator-config.yaml +``` + +### 5. Deploy Cozystack Operator Apply the generic operator manifest: @@ -228,7 +252,7 @@ Apply the generic operator manifest: kubectl apply -f https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml ``` -### 5. Monitor Installation +### 6. Monitor Installation Watch the installation progress: @@ -340,6 +364,19 @@ This example uses k3s default CIDRs. Adjust for kubeadm (`10.244.0.0/16`, `10.96 ipv4-svc-cidr: "{{ cozystack_svc_cidr }}" ipv4-join-cidr: "100.64.0.0/16" + - name: Create Cozystack operator config + kubernetes.core.k8s: + state: present + definition: + apiVersion: v1 + kind: ConfigMap + metadata: + name: cozystack-operator-config + namespace: cozy-system + data: + KUBERNETES_SERVICE_HOST: "{{ cozystack_api_endpoint | urlsplit('hostname') }}" + KUBERNETES_SERVICE_PORT: "{{ cozystack_api_endpoint | urlsplit('port') | default('6443', true) }}" + - name: Apply Cozystack operator kubernetes.core.k8s: src: https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml From d35d7ae49dffdff07cd9f66f648a8dfacc9a6d6e Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Feb 2026 13:11:43 +0300 Subject: [PATCH 05/11] [docs] Use industry-standard inotify limits in generic install guide Replace extreme inotify values (2099999999) with proven industry defaults: max_user_watches=524288, max_user_instances=8192, max_queued_events=65536. Updated both the sysctl configuration example and the Ansible playbook. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index a8668611..a774389b 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -63,9 +63,9 @@ Create `/etc/sysctl.d/99-cozystack.conf` with the following content: ```ini # Inotify limits (critical for Cozystack) -fs.inotify.max_user_watches = 2099999999 -fs.inotify.max_user_instances = 2099999999 -fs.inotify.max_queued_events = 2099999999 +fs.inotify.max_user_watches = 524288 +fs.inotify.max_user_instances = 8192 +fs.inotify.max_queued_events = 65536 # Filesystem limits fs.file-max = 2097152 @@ -297,9 +297,9 @@ Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. state: present reload: true loop: - - { name: fs.inotify.max_user_watches, value: "2099999999" } - - { name: fs.inotify.max_user_instances, value: "2099999999" } - - { name: fs.inotify.max_queued_events, value: "2099999999" } + - { name: fs.inotify.max_user_watches, value: "524288" } + - { name: fs.inotify.max_user_instances, value: "8192" } + - { name: fs.inotify.max_queued_events, value: "65536" } - { name: net.ipv4.ip_forward, value: "1" } - { name: net.ipv4.conf.all.forwarding, value: "1" } From 78e3fa4100ab0916d74322ef9837615900539e0a Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Feb 2026 15:00:08 +0300 Subject: [PATCH 06/11] fix(docs): add missing sysctl values to Ansible playbook example The Node Preparation Playbook was missing fs.file-max, fs.aio-max-nr, and vm.swappiness sysctl values that are listed in the Sysctl Configuration section of the same document. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index a774389b..5977e759 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -300,8 +300,11 @@ Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. - { name: fs.inotify.max_user_watches, value: "524288" } - { name: fs.inotify.max_user_instances, value: "8192" } - { name: fs.inotify.max_queued_events, value: "65536" } + - { name: fs.file-max, value: "2097152" } + - { name: fs.aio-max-nr, value: "1048576" } - { name: net.ipv4.ip_forward, value: "1" } - { name: net.ipv4.conf.all.forwarding, value: "1" } + - { name: vm.swappiness, value: "1" } - name: Enable iscsid service ansible.builtin.systemd: From 5bf19d4c144b82b8c848559a326a3dbbbe51e614 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Feb 2026 16:28:20 +0300 Subject: [PATCH 07/11] fix(docs): add missing Platform Package creation step The documentation was missing the step to create the Package resource after deploying the operator. Without this step, Cozystack components are never installed. Added step 6 to the manual instructions and corresponding tasks to the Ansible playbook example. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 5977e759..789f55d5 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -252,7 +252,31 @@ Apply the generic operator manifest: kubectl apply -f https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml ``` -### 6. Monitor Installation +### 6. Create Platform Package + +After the operator starts and reconciles the `PackageSource`, create a `Package` resource to trigger the platform installation: + +```yaml +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.cozystack-platform +spec: + variant: isp-full-generic +``` + +Apply it: + +```bash +kubectl apply -f cozystack-platform-package.yaml +``` + +{{% alert color="info" %}} +The Package name **must** match the PackageSource name (`cozystack.cozystack-platform`). +You can verify available PackageSources with `kubectl get packagesource`. +{{% /alert %}} + +### 7. Monitor Installation Watch the installation progress: @@ -384,6 +408,27 @@ This example uses k3s default CIDRs. Adjust for kubeadm (`10.244.0.0/16`, `10.96 kubernetes.core.k8s: src: https://github.com/cozystack/cozystack/releases/latest/download/cozystack-operator-generic.yaml state: present + + - name: Wait for PackageSource to be ready + kubernetes.core.k8s_info: + api_version: cozystack.io/v1alpha1 + kind: PackageSource + name: cozystack.cozystack-platform + register: pkg_source + until: pkg_source.resources | length > 0 and (pkg_source.resources[0].status.conditions | selectattr('type', 'equalto', 'Ready') | first).status == "True" + retries: 30 + delay: 10 + + - name: Create Platform Package + kubernetes.core.k8s: + state: present + definition: + apiVersion: cozystack.io/v1alpha1 + kind: Package + metadata: + name: cozystack.cozystack-platform + spec: + variant: isp-full-generic ``` ## Troubleshooting From 2c462968676dfe431f5b255486093c440f59d830 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Feb 2026 20:55:12 +0300 Subject: [PATCH 08/11] fix(docs): add --disable=metrics-server to k3s configuration Cozystack deploys its own metrics-server. The k3s built-in metrics-server addon controller overwrites the RBAC RoleBinding, breaking Cozystack's metrics-server with a permission error on the extension-apiserver-authentication configmap in kube-system. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 789f55d5..3ef8417a 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -111,6 +111,7 @@ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \ --disable=traefik \ --disable=servicelb \ --disable=local-storage \ + --disable=metrics-server \ --disable-network-policy \ --disable-kube-proxy \ --flannel-backend=none \ From cea9bb61d42cc90707cffcf786f776f55212c650 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Tue, 10 Feb 2026 00:25:45 +0300 Subject: [PATCH 09/11] fix(docs): correct operator deployment name and add reconciliation note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix incorrect deployment name in monitoring step (deploy/cozystack → deploy/cozystack-operator) and add info alert about expected transient errors during initial Cilium reconciliation. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 3ef8417a..81a7049e 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -282,7 +282,7 @@ You can verify available PackageSources with `kubectl get packagesource`. Watch the installation progress: ```bash -kubectl logs -n cozy-system deploy/cozystack -f +kubectl logs -n cozy-system deploy/cozystack-operator -f ``` Check HelmRelease status: @@ -291,6 +291,10 @@ Check HelmRelease status: kubectl get hr -A ``` +{{% alert color="info" %}} +During initial deployment, HelmReleases may show errors such as `ExternalArtifact not found` or `dependency is not ready` for the first few minutes while Cilium and other core components are being reconciled. This is expected — wait a few minutes and check again. +{{% /alert %}} + When complete, all releases will show `READY: True`. ## Example: Ansible Playbook From 35c37c27b7708d27ec23e6c5a140d824cbab38a6 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Tue, 10 Feb 2026 00:43:12 +0300 Subject: [PATCH 10/11] fix(docs): improve monitoring step with node readiness check Replace vague "all releases will show READY: True" with an actionable kubectl wait command to verify Cilium deployment and node networking. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/generic.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 81a7049e..5d325408 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -295,7 +295,11 @@ kubectl get hr -A During initial deployment, HelmReleases may show errors such as `ExternalArtifact not found` or `dependency is not ready` for the first few minutes while Cilium and other core components are being reconciled. This is expected — wait a few minutes and check again. {{% /alert %}} -When complete, all releases will show `READY: True`. +You can verify that Cilium has been deployed and nodes are networked by waiting for them to become Ready: + +```bash +kubectl wait --for=condition=Ready nodes --all --timeout=300s +``` ## Example: Ansible Playbook From 94bbd19cf29999db1d7714a2d4b8299d7920cb6a Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Tue, 10 Feb 2026 00:48:07 +0300 Subject: [PATCH 11/11] fix(docs): align ansible sysctl with manual section and fix Talos-only text Add missing net.bridge.bridge-nf-call-iptables and net.bridge.bridge-nf-call-ip6tables to the Ansible playbook sysctl entries to match the manual configuration section. Update _index.md "Further Steps" to be distribution-agnostic instead of referencing Talos Linux specifically. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin --- content/en/docs/install/kubernetes/_index.md | 2 +- content/en/docs/install/kubernetes/generic.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/docs/install/kubernetes/_index.md b/content/en/docs/install/kubernetes/_index.md index 80552f70..84f97c9e 100644 --- a/content/en/docs/install/kubernetes/_index.md +++ b/content/en/docs/install/kubernetes/_index.md @@ -39,5 +39,5 @@ If you encounter problems with installation, refer to the [Troubleshooting secti ## Further Steps -- After installing and configuring Kubernetes on top of Talos Linux nodes, you will have a Kubernetes cluster ready to +- After installing and configuring a Kubernetes cluster, you will have it ready to [install and configure Cozystack]({{% ref "/docs/install/cozystack" %}}). diff --git a/content/en/docs/install/kubernetes/generic.md b/content/en/docs/install/kubernetes/generic.md index 5d325408..5fa4460d 100644 --- a/content/en/docs/install/kubernetes/generic.md +++ b/content/en/docs/install/kubernetes/generic.md @@ -337,6 +337,8 @@ Below is a minimal Ansible playbook for preparing nodes and deploying Cozystack. - { name: fs.aio-max-nr, value: "1048576" } - { name: net.ipv4.ip_forward, value: "1" } - { name: net.ipv4.conf.all.forwarding, value: "1" } + - { name: net.bridge.bridge-nf-call-iptables, value: "1" } + - { name: net.bridge.bridge-nf-call-ip6tables, value: "1" } - { name: vm.swappiness, value: "1" } - name: Enable iscsid service