Развертывание Cozystack на Generic Kubernetes

Как развернуть Cozystack на k3s, kubeadm, RKE2 или других дистрибутивах Kubernetes без Talos Linux

В этом руководстве описано, как развернуть Cozystack на generic-дистрибутивах Kubernetes, таких как k3s, kubeadm или RKE2. Хотя Talos Linux остается рекомендуемой платформой для production-развертываний, Cozystack поддерживает развертывание на других дистрибутивах Kubernetes с помощью bundle isp-full-generic.

Когда использовать Generic Kubernetes

Рассмотрите использование generic Kubernetes вместо Talos Linux, если:

  • У вас уже есть кластер Kubernetes, который вы хотите дополнить Cozystack
  • Ваша инфраструктура не поддерживает Talos Linux (некоторые облачные провайдеры, embedded-системы)
  • Вам нужны специфические функции или пакеты Linux, недоступные в Talos

Для новых production-развертываний рекомендуется Talos Linux благодаря его преимуществам в безопасности и эксплуатации.

Предварительные требования

Supported Distributions

Cozystack протестирован на:

  • k3s v1.32+ (рекомендуется для single-node и edge-развертываний)
  • kubeadm v1.28+
  • RKE2 v1.28+

Требования к хостам

Обязательные пакеты

Установите следующие пакеты на всех узлах:

apt-get update
apt-get install -y nfs-common open-iscsi multipath-tools

Обязательные модули ядра

Загрузите модуль br_netfilter (требуется для sysctl-настроек bridge netfilter):

modprobe br_netfilter
echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf

Обязательные сервисы

Включите и запустите обязательные сервисы:

systemctl enable --now iscsid
systemctl enable --now multipathd

Настройка sysctl

Создайте /etc/sysctl.d/99-cozystack.conf со следующим содержимым:

# Inotify limits (critical for Cozystack)
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 8192
fs.inotify.max_queued_events = 65536

# 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

Примените настройки:

sysctl --system

Настройка Kubernetes

Cozystack самостоятельно управляет сетью (Cilium/KubeOVN), хранилищем (LINSTOR) и ingress (NGINX). Ваш дистрибутив Kubernetes должен быть настроен так, чтобы не устанавливать эти компоненты.

Обязательная конфигурация

КомпонентТребование
CNIОтключен — Cozystack развертывает Cilium или KubeOVN
Ingress ControllerОтключен — Cozystack развертывает NGINX
Storage ProvisionerОтключен — Cozystack развертывает LINSTOR
kube-proxyОтключен — его заменяет Cilium
Cluster DomainДолжен быть cozy.local

При установке k3s используйте следующие флаги:

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 \
  --cluster-domain=cozy.local \
  --tls-san=<YOUR_NODE_IP> \
  --kubelet-arg=max-pods=220" sh -

Замените <YOUR_NODE_IP> на IP-адрес вашего узла.

Создайте конфигурационный файл kubeadm:

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 заменит kube-proxy

Инициализируйте кластер без стандартного CNI:

kubeadm init --config kubeadm-config.yaml --skip-phases=addon/kube-proxy

Не устанавливайте CNI-плагин после kubeadm init — Cozystack автоматически развернет Kube-OVN и Cilium.

Создайте /etc/rancher/rke2/config.yaml:

cni: none
disable:
  - rke2-ingress-nginx
  - rke2-metrics-server
cluster-domain: cozy.local
disable-kube-proxy: true

Установка Cozystack

1. Применение CRD

Скачайте и примените Custom Resource Definitions:

kubectl apply -f https://github.com/cozystack/cozystack/releases/download/v1.4.0/cozystack-crds.yaml

2. Развертывание Cozystack Operator

Скачайте generic-манифест operator, замените placeholder адреса API server и примените его:

curl -fsSL https://github.com/cozystack/cozystack/releases/download/v1.4.0/cozystack-operator-generic.yaml \
  | sed 's/REPLACE_ME/<YOUR_NODE_IP>/' \
  | kubectl apply -f -

Замените <YOUR_NODE_IP> на IP-адрес вашего Kubernetes API server (только IP, без протокола и порта).

Манифест включает deployment operator, ConfigMap cozystack-operator-config с адресом API server и ресурс PackageSource.

3. Создание Platform Package

После запуска operator и reconciliation ресурса PackageSource создайте ресурс Package, чтобы запустить установку платформы.

Пример для k3s (для других дистрибутивов скорректируйте CIDR):

apiVersion: cozystack.io/v1alpha1
kind: Package
metadata:
  name: cozystack.cozystack-platform
  # Package имеет cluster scope — namespace не нужен
spec:
  variant: isp-full-generic
  components:
    platform:
      values:
        publishing:
          host: "example.com"
          apiServerEndpoint: "https://<YOUR_NODE_IP>:6443"
        networking:
          podCIDR: "10.42.0.0/16"
          podGateway: "10.42.0.1"
          serviceCIDR: "10.43.0.0/16"
          joinCIDR: "100.64.0.0/16"

Скорректируйте значения:

ПолеОписание
publishing.hostВаш домен для сервисов Cozystack
publishing.apiServerEndpointURL Kubernetes API endpoint
networking.podCIDRCIDR pod-сети (должен совпадать с вашей k8s-конфигурацией)
networking.podGatewayПервый IP в pod CIDR (например, 10.42.0.1 для 10.42.0.0/16)
networking.serviceCIDRCIDR service-сети (должен совпадать с вашей k8s-конфигурацией)
networking.joinCIDRСеть для связи с nested-кластерами

Примените его:

kubectl apply -f cozystack-platform-package.yaml

4. Мониторинг установки

Следите за ходом установки:

kubectl logs -n cozy-system deploy/cozystack-operator -f

Проверьте состояние HelmRelease:

kubectl get hr -A

Можно убедиться, что Cilium развернут и сеть между узлами настроена, дождавшись, пока узлы перейдут в состояние Ready:

kubectl wait --for=condition=Ready nodes --all --timeout=300s

Пример: Ansible Playbook

Ниже приведен минимальный Ansible playbook для подготовки узлов и развертывания Cozystack.

Сначала установите необходимые Ansible collections:

ansible-galaxy collection install ansible.posix community.general kubernetes.core ansible.utils

Playbook подготовки узлов

---
- name: Prepare nodes for Cozystack
  hosts: all
  become: true
  tasks:
    - name: Load br_netfilter module
      community.general.modprobe:
        name: br_netfilter
        persistent: present

    - 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: "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: 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
      ansible.builtin.systemd:
        name: iscsid
        enabled: true
        state: started

    - name: Enable multipathd service
      ansible.builtin.systemd:
        name: multipathd
        enabled: true
        state: started

Playbook развертывания Cozystack

В этом примере используются CIDR по умолчанию для k3s. Скорректируйте их для kubeadm (10.244.0.0/16, 10.96.0.0/16) или своей пользовательской конфигурации.

---
- name: Deploy Cozystack
  hosts: localhost
  connection: local
  vars:
    cozystack_root_host: "example.com"
    cozystack_api_host: "10.0.0.1"
    cozystack_api_port: "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:
    - name: Apply Cozystack CRDs
      ansible.builtin.command:
        cmd: kubectl apply -f https://github.com/cozystack/cozystack/releases/download/v1.4.0/cozystack-crds.yaml
      changed_when: true

    - name: Download and apply Cozystack operator manifest
      ansible.builtin.shell:
        cmd: >
          curl -fsSL https://github.com/cozystack/cozystack/releases/download/v1.4.0/cozystack-operator-generic.yaml
          | sed 's/REPLACE_ME/{{ cozystack_api_host }}/'
          | kubectl apply -f -
      changed_when: true

    - 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')
          | map(attribute='status')
          | first
          | default('False')
        ) == "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
            components:
              platform:
                values:
                  publishing:
                    host: "{{ cozystack_root_host }}"
                    apiServerEndpoint: "https://{{ cozystack_api_host }}:{{ cozystack_api_port }}"
                  networking:
                    podCIDR: "{{ cozystack_pod_cidr }}"
                    podGateway: "{{ cozystack_pod_cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}"
                    serviceCIDR: "{{ cozystack_svc_cidr }}"
                    joinCIDR: "100.64.0.0/16"

Устранение неполадок

Некорректный image tag linstor-scheduler

Симптом: ошибка InvalidImageName для pod linstor-scheduler.

Причина: формат версии k3s (например, v1.35.0+k3s1) содержит +, который недопустим в Docker image tags.

Решение: это исправлено в Cozystack v1.0.0+. Убедитесь, что используете последний релиз.

KubeOVN не планируется

Симптом: pods ovn-central остаются в состоянии Pending.

Причина: KubeOVN использует Helm lookup для поиска узлов control plane, что может не сработать на свежих кластерах.

Решение: убедитесь, что ваш Platform Package содержит явную конфигурацию MASTER_NODES:

apiVersion: cozystack.io/v1alpha1
kind: Package
metadata:
  name: cozystack.cozystack-platform
spec:
  variant: isp-full-generic
  components:
    platform:
      values:
        networking:
          kubeovn:
            MASTER_NODES: "<YOUR_CONTROL_PLANE_IP>"

Ключ — kubeovn (без дефиса), он соответствует полю в packages/core/platform/values.yaml — см. также networking.kubeovn.MASTER_NODES в справочнике Platform Package.

Cilium не может подключиться к API server

Симптом: pods Cilium находятся в CrashLoopBackOff с ошибками подключения к API.

Причина: single-node кластеры или нестандартные API endpoints требуют явной конфигурации.

Решение: проверьте, что ваш Platform Package содержит корректные настройки API server:

spec:
  components:
    networking:
      values:
        cilium:
          k8sServiceHost: "<YOUR_API_HOST>"
          k8sServicePort: "6443"

Ошибки лимитов inotify

Симптом: pods завершаются с ошибками “too many open files” или ошибками inotify.

Причина: стандартные лимиты inotify в Linux слишком низкие для Kubernetes.

Решение: примените sysctl-настройки из раздела Настройка sysctl и перезагрузите узел.

Следующие шаги

После завершения установки Cozystack:

  1. Настройте хранилище с LINSTOR
  2. Настройте root tenant
  3. Разверните первое приложение

Ссылки

Last modified 2026-05-24: feat: migrate to 1.4 (0c5a079)