Files
K3S/group_vars/all/addons.yml
Sergey Antropoff aae7941416 feat: добавить аддон ext-proxy — проксировать внешние сервисы через ingress-nginx
Helm chart (один чарт создаёт Service + Endpoints + Ingress на каждый прокси):
- _helpers.tpl: хелперы ext-proxy.resourceName, ext-proxy.labels
- service.yaml: ClusterIP без selector — имя совпадает с Endpoints
- endpoints.yaml: внешние IP(s) + порт; несколько IP → round-robin через kube-proxy
- ingress.yaml: слияние аннотаций (defaults → сгенерированные → уровень прокси);
  поддержка TLS, basic auth, WebSocket, несколько хостов, маршрутизация по пути
- secret-auth.yaml: htpasswd Secret создаётся только при auth.enabled=true + credentials
- NOTES.txt: список прокси + команды проверки после установки

Ansible роль:
- defaults/main.yml: ext_proxy_namespace, ext_proxy_defaults, ext_proxy_proxies
- tasks/main.yml: валидация → namespace → копировать chart → lint → helm upgrade --install --atomic
- templates/values.yaml.j2: преобразование Ansible-переменных в Helm values через to_yaml

Интеграция: Makefile addon-ext-proxy, флаг addons.yml, playbooks/addons.yml,
            docs/addons.md, README.md (счётчик 37 аддонов)

README.md на русском языке с полной документацией:
архитектура, настройка, функции, DNS, проверка, примеры манифестов, устранение неисправностей

Дополнительно: splitgw_deploy_mode изменён на k8s
2026-04-26 07:21:41 +03:00

364 lines
24 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
# ═══════════════════════════════════════════════════════════════════════════════
# Аддоны кластера — выбери что устанавливать
# make install-full → core + все аддоны у которых true
# make addon-<name> → конкретный аддон напрямую (флаг игнорируется)
# ═══════════════════════════════════════════════════════════════════════════════
addon_nfs_server: false # NFS сервер
addon_csi_nfs: false # CSI NFS Driver + StorageClass
addon_ingress_nginx: true # ingress-nginx (Ingress controller)
addon_cert_manager: false # cert-manager (TLS через Let's Encrypt)
addon_metrics_server: true # metrics-server (kubectl top nodes/pods)
addon_prometheus_stack: true # Prometheus + Grafana + Alertmanager
addon_istio: false # Istio service mesh + Kiali UI
addon_argocd: false # ArgoCD (GitOps)
addon_longhorn: false # Longhorn (distributed block storage)
addon_kubernetes_dashboard: false # Kubernetes Dashboard
addon_postgresql: false # PostgreSQL (Bitnami)
addon_mysql: false # MySQL (Bitnami)
addon_databasus: false # Databasus (резервное копирование БД)
addon_minio: false # MinIO (S3-совместимое объектное хранилище)
addon_velero: false # Velero (резервное копирование кластера и PVC)
addon_crowdsec: false # CrowdSec (обнаружение вторжений)
addon_harbor: false # Harbor (container registry)
addon_gitea: false # Gitea (Git hosting, авто-обновление до последней версии)
addon_owncloud: false # ownCloud OCIS (файловое хранилище, авто-обновление)
addon_nextcloud: false # Nextcloud (файловое хранилище, авто-обновление)
addon_loki: false # Loki (агрегация логов)
addon_promtail: false # Promtail (агент сбора логов → Loki)
addon_tempo: false # Tempo (distributed tracing)
addon_pushgateway: false # Prometheus Pushgateway (метрики batch-задач)
addon_csi_s3: false # CSI S3 Driver (объектное хранилище как PVC, авто-MinIO)
addon_csi_ceph: false # CSI Ceph / Rook-Ceph (distributed block + filesystem storage)
addon_csi_glusterfs: false # CSI GlusterFS Driver (требует внешний GlusterFS + Heketi)
addon_vaultwarden: false # Vaultwarden (self-hosted Bitwarden-совместимый менеджер паролей)
addon_smtp_relay: false # SMTP Relay (Postfix → Yandex/другой SMTP) — для уведомлений из подов
addon_vault: false # HashiCorp Vault (секреты, PKI, динамические credentials)
addon_external_secrets: false # External Secrets Operator → Vault/AWS/GCP (k8s Secret sync)
addon_jenkins: false # Jenkins CI/CD (Helm, dynamic k8s agents, JCasC)
addon_netbird: false # NetBird VPN (управляющий сервер + subnet router + exit node)
addon_mediaserver: false # MediaServer — Plex, *arr, Transmission, Prowlarr+Hysteria2, Samba
addon_hysteria2_server: false # Hysteria2 VPN сервер на удалённый VPS (группа [hysteria2_server] в inventory)
addon_splitgw: false # Split Gateway — прозрачный прокси sing-box+Hysteria2 (группа [splitgw] в inventory)
addon_ext_proxy: false # External Services Ingress Proxy — проксировать внешние сервисы через ingress-nginx
# ─── NFS Server ───────────────────────────────────────────────────────────────
nfs_exports:
- path: /srv/nfs/k8s
options: "*(rw,sync,no_subtree_check,no_root_squash)"
nfs_allowed_network: "192.168.1.0/24"
nfs_create_export_dirs: true
nfs_export_dir_mode: "0777"
nfs_export_dir_owner: "nobody"
nfs_export_dir_group: "nogroup"
# ─── CSI NFS Driver ───────────────────────────────────────────────────────────
csi_nfs_version: "v4.8.0"
csi_nfs_namespace: "kube-system"
# IP NFS сервера — по умолчанию берётся первый мастер
# Если NFS на отдельном хосте: csi_nfs_server: "192.168.1.20"
csi_nfs_server: "{{ hostvars[groups['k3s_master'][0]]['ansible_host'] }}"
csi_nfs_share: "/srv/nfs/k8s"
csi_nfs_storageclass_default: true
csi_nfs_reclaim_policy: "Delete" # Delete | Retain
csi_nfs_on_delete: "delete" # delete | retain | archive
csi_nfs_install_client: true
# ─── ingress-nginx ────────────────────────────────────────────────────────────
ingress_nginx_version: "4.10.1"
ingress_nginx_namespace: "ingress-nginx"
# LoadBalancer получит IP от kube-vip
ingress_nginx_service_type: "LoadBalancer"
# Конкретный IP из пула kube-vip (оставь "" для автоматического)
ingress_nginx_load_balancer_ip: ""
ingress_nginx_replica_count: 1
ingress_nginx_use_daemonset: false
ingress_nginx_metrics_enabled: true
ingress_nginx_class_name: "nginx"
ingress_nginx_set_default_class: true
# Кастомная страница ошибок
ingress_nginx_custom_errors_enabled: true
ingress_nginx_error_cluster_name: "K3S Cluster"
ingress_nginx_error_cluster_domain: "" # например: cluster.example.com
ingress_nginx_resources:
requests:
cpu: 100m
memory: 90Mi
limits:
cpu: 500m
memory: 256Mi
ingress_nginx_extra_args: {}
# ─── cert-manager ─────────────────────────────────────────────────────────────
cert_manager_version: "v1.15.3"
cert_manager_namespace: "cert-manager"
# Автоматически создать ClusterIssuer:
# none — не создавать
# selfsigned — самоподписанный CA
# letsencrypt — Let's Encrypt (требует публичный домен)
cert_manager_issuer: "letsencrypt"
# Email для Let's Encrypt (обязательно для letsencrypt)
cert_manager_acme_email: "admin@example.com"
# ─── kube-prometheus-stack ────────────────────────────────────────────────────
# prometheus_stack_version: "60.3.0"
# prometheus_retention_days: 7
# prometheus_storage_size: "10Gi"
# Grafana: логин и пароль — задай в vault.yml:
# vault_grafana_user: "admin"
# vault_grafana_password: "ваш-пароль"
# prometheus_grafana_ingress_enabled: false
# prometheus_grafana_ingress_host: "grafana.example.com"
# ─── Istio ────────────────────────────────────────────────────────────────────
# istio_version: "1.22.2"
# istio_mtls_mode: "STRICT" # STRICT | PERMISSIVE | DISABLE
# istio_install_gateway: true
# Kiali (UI для Istio) — опционально вместе с Istio
# kiali_enabled: false
# kiali_ingress_host: "kiali.example.com"
# ─── PostgreSQL ───────────────────────────────────────────────────────────────
# Пароли задаются в group_vars/all/vault.yml:
# vault_postgresql_postgres_password: "..."
# vault_postgresql_password: "..."
# postgresql_auth_username: "appuser"
# postgresql_auth_database: "appdb"
# postgresql_storage_size: "8Gi"
# postgresql_storage_class: "" # "" = default StorageClass
# postgresql_replica_count: 0 # 0 = только primary
# Shared endpoint — используется другими аддонами когда addon_postgresql: true
postgresql_external_host: "postgresql.postgresql.svc.cluster.local"
postgresql_external_port: 5432
# ─── MySQL ────────────────────────────────────────────────────────────────────
# Пароли задаются в group_vars/all/vault.yml:
# vault_mysql_root_password: "..."
# vault_mysql_password: "..."
# mysql_auth_username: "appuser"
# mysql_auth_database: "appdb"
# mysql_storage_size: "8Gi"
# mysql_storage_class: "" # "" = default StorageClass
# mysql_secondary_replica_count: 0 # 0 = только primary
# Shared endpoint — используется другими аддонами когда addon_mysql: true
mysql_external_host: "mysql.mysql.svc.cluster.local"
mysql_external_port: 3306
# ─── Databasus ────────────────────────────────────────────────────────────────
# Databasus автоматически получает подключение к PostgreSQL/MySQL
# если соответствующий аддон включён (addon_postgresql/addon_mysql: true).
databasus_ingress_enabled: true
databasus_ingress_host: "backup.example.com"
# databasus_ingress_tls: false
# databasus_version: "" # "" = latest
# ─── MinIO ────────────────────────────────────────────────────────────────────
# Логин/пароль задаются в vault.yml:
# vault_minio_root_user: "admin"
# vault_minio_root_password: "..."
# minio_mode: "standalone" # standalone | distributed
# minio_storage_size: "10Gi"
# minio_storage_class: "" # "" = default StorageClass
minio_ingress_enabled: false
minio_console_ingress_host: "minio.example.com"
minio_api_ingress_host: "s3.example.com"
# minio_ingress_tls: false
# ─── Velero ───────────────────────────────────────────────────────────────────
# Credentials задаются в vault.yml:
# vault_velero_s3_access_key: "..." # логин MinIO (обычно = vault_minio_root_user)
# vault_velero_s3_secret_key: "..." # пароль MinIO
# velero_s3_url: "http://minio.minio.svc.cluster.local:9000" # endpoint addon_minio
# velero_s3_bucket: "velero"
# velero_schedule_enabled: true
# velero_schedule_cron: "0 2 * * *" # каждый день в 02:00
# velero_schedule_ttl: "720h" # хранить 30 дней
# ─── CrowdSec ─────────────────────────────────────────────────────────────────
# Ключ энролмента задаётся в vault.yml (необязательно):
# vault_crowdsec_enroll_key: "..." # с https://app.crowdsec.net
# crowdsec_instance_name: "k3s-cluster"
# crowdsec_collections: "crowdsecurity/linux crowdsecurity/nginx crowdsecurity/kubernetes"
# crowdsec_nginx_bouncer_enabled: false
# ─── Harbor ───────────────────────────────────────────────────────────────────
# Пароли задаются в vault.yml:
# vault_harbor_admin_password: "Harbor12345"
# vault_harbor_db_password: "..." # используется только при addon_postgresql: true
# harbor_ingress_host: "harbor.example.com"
# harbor_registry_storage_size: "20Gi"
# harbor_database_type: "internal" # внешняя PostgreSQL при addon_postgresql: true
# ─── Gitea ────────────────────────────────────────────────────────────────────
# Пароли задаются в vault.yml:
# vault_gitea_admin_password: "..."
# vault_gitea_db_password: "..." # используется только при addon_postgresql: true
# gitea_ingress_host: "gitea.example.com"
# gitea_version: "" # "" = автопоиск последней версии
# gitea_ssh_enabled: false # NodePort SSH для git clone
# ─── ownCloud (OCIS) ──────────────────────────────────────────────────────────
# Пароль задаётся в vault.yml:
# vault_owncloud_admin_password: "..."
# owncloud_ingress_host: "cloud.example.com"
# owncloud_version: "" # "" = автопоиск последней версии
# owncloud_storage_users_size: "20Gi"
# ─── Nextcloud ────────────────────────────────────────────────────────────────
# Пароли задаются в vault.yml:
# vault_nextcloud_admin_password: "..."
# vault_nextcloud_db_password: "..." # используется только при addon_postgresql: true
# nextcloud_ingress_host: "nextcloud.example.com"
# nextcloud_version: "" # "" = автопоиск последней версии
# nextcloud_storage_size: "20Gi"
# ─── Loki ─────────────────────────────────────────────────────────────────────
# loki_storage_type: "filesystem" # filesystem (авто: s3 если addon_minio: true)
# loki_storage_size: "10Gi"
# loki_retention_period: "720h" # 30 дней
# loki_ingress_enabled: false
# loki_ingress_host: "loki.example.com"
# ─── Promtail ─────────────────────────────────────────────────────────────────
# DaemonSet на всех нодах. Требует addon_loki: true (или внешний Loki).
# promtail_loki_url: "http://loki.loki.svc.cluster.local:3100/loki/api/v1/push"
# ─── Tempo ────────────────────────────────────────────────────────────────────
# Distributed tracing backend.
# tempo_storage_size: "10Gi"
# tempo_retention_period: "720h"
# tempo_receivers_otlp_enabled: true # порты 4317 (gRPC) и 4318 (HTTP)
# tempo_receivers_jaeger_enabled: true # порты 14268 (HTTP) и 14250 (gRPC)
# tempo_receivers_zipkin_enabled: false # порт 9411
# ─── Pushgateway ──────────────────────────────────────────────────────────────
# Для push-метрик из batch-задач, CI/CD, скриптов.
# pushgateway_ingress_enabled: false
# pushgateway_ingress_host: "pushgateway.example.com"
# pushgateway_persistence_enabled: false # сохранять метрики между рестартами
# ─── CSI S3 ───────────────────────────────────────────────────────────────────
# Монтирует S3/MinIO бакеты как PersistentVolume в поды.
# При addon_minio: true — автоматически использует внутренний MinIO.
# csi_s3_mounter: "geesefs" # geesefs | s3fs | rclone
# csi_s3_endpoint: "" # авто-MinIO если addon_minio: true
# csi_s3_access_key: "" # авто из vault_minio_root_user
# csi_s3_secret_key: "" # авто из vault_minio_root_password
# ─── CSI Ceph / Rook-Ceph ─────────────────────────────────────────────────────
# Distributed block (RWO) и filesystem (RWX) storage на базе Ceph.
# Требует минимум 3 ноды с незанятыми дисками для Ceph OSD.
# rook_ceph_mon_count: 3
# rook_ceph_block_replica_count: 3 # для single-node задай 1
# rook_ceph_block_storage_class: "rook-ceph-block"
# rook_ceph_filesystem_storage_class: "rook-ceph-filesystem"
# rook_ceph_dashboard_ingress_enabled: false
# rook_ceph_dashboard_ingress_host: "ceph.example.com"
# ─── CSI GlusterFS ────────────────────────────────────────────────────────────
# Требует внешний GlusterFS кластер + Heketi REST API.
# csi_glusterfs_heketi_url: "http://heketi.glusterfs.local:8080"
# csi_glusterfs_cluster_id: "" # heketi-cli cluster list
# csi_glusterfs_volume_type: "replicate:3"
# csi_glusterfs_endpoints: # прямое подключение без Heketi
# - name: "gluster01"
# ip: "192.168.1.10"
# ─── Vaultwarden ──────────────────────────────────────────────────────────────
# Self-hosted Bitwarden-совместимый менеджер паролей.
# Секреты задаются в vault.yml:
# vault_vaultwarden_admin_token: "..." # токен доступа к /admin
# vault_vaultwarden_smtp_password: "..." # пароль SMTP
# vaultwarden_domain: "https://vault.example.com"
# vaultwarden_signups_allowed: false
# vaultwarden_ingress_host: "vault.example.com"
# vaultwarden_smtp_enabled: false
# vaultwarden_smtp_host: "smtp.yandex.ru"
# vaultwarden_smtp_from: "vault@example.com"
# vaultwarden_smtp_port: 465
# vaultwarden_smtp_security: "force_tls" # force_tls | starttls | off
# vaultwarden_smtp_username: "user@example.com"
# ─── SMTP Relay ───────────────────────────────────────────────────────────────
# Postfix relay для отправки почты из подов через внешний SMTP (Yandex/Gmail/etc).
# Пароль задаётся в vault.yml: vault_smtp_relay_password
# Использование: SMTP_HOST=smtp-relay.smtp-relay.svc.cluster.local, SMTP_PORT=25
# smtp_relay_host: "smtp.yandex.ru"
# smtp_relay_port: 465
# smtp_relay_username: "sergey@antropoff.ru"
# smtp_relay_from: "vault@antropoff.ru"
# smtp_relay_allowed_sender_domains: "antropoff.ru"
# smtp_relay_mynetworks: "10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 127.0.0.0/8"
# ─── HashiCorp Vault ──────────────────────────────────────────────────────────
# Менеджер секретов. README: addons/vault/README.md
# vault_mode: "standalone" # standalone (1 pod) | ha (3 pods Raft)
# vault_auto_unseal_type: "none" # none | k8s | aws | gcp | azure | transit
# k8s: ключи в Secret (homelab), aws/gcp/azure/transit (production)
# vault_injector_enabled: true # Vault Agent Injector (авто-инжекция в поды)
# vault_ingress_enabled: false
# vault_ingress_host: "vault-hc.example.com"
# vault_storage_size: "10Gi"
# Для AWS KMS unseal (vault.yml): vault_aws_kms_access_key, vault_aws_kms_secret_key
# ─── External Secrets Operator ────────────────────────────────────────────────
# Синхронизирует секреты из Vault/AWS/GCP в k8s Secrets. README: addons/external-secrets/README.md
# Требует предварительно созданного AppRole в Vault (шаги в README).
# external_secrets_vault_url: "http://vault.vault.svc.cluster.local:8200"
# external_secrets_vault_kv_path: "secret"
# external_secrets_vault_role_id: "" # после создания AppRole в Vault
# external_secrets_vault_store_name: "vault-backend"
# Пароль задаётся в vault.yml: vault_eso_approle_secret_id
# ─── Jenkins ──────────────────────────────────────────────────────────────────
# CI/CD сервер с dynamic k8s pod agents.
# Пароль задаётся в vault.yml: vault_jenkins_admin_password
# jenkins_ingress_host: "jenkins.example.com"
# jenkins_storage_size: "20Gi"
# jenkins_plugins: [...] # переопределить список плагинов
# jenkins_agent_enabled: true
# ─── Gitea Actions ───────────────────────────────────────────────────────────<E29480><E29480><EFBFBD>
# GitHub Actions-совместимая CI/CD встроенная в Gitea.
# gitea_actions_enabled: false # включить Actions в Gitea (добавить в addon-gitea)
# gitea_actions_runner_enabled: false # установить act_runner Deployment (DinD)
# gitea_actions_runner_replicas: 2 # параллельных runner
# gitea_actions_runner_dind_enabled: true # Docker-in-Docker для docker build/run в jobs
# ─── NetBird VPN ──────────────────────────────────────────────────────────────
# Self-hosted WireGuard-based VPN. Management + Signal + Coturn (STUN/TURN) + kube-vip LB.
# Пароли задаются в vault.yml: vault_netbird_coturn_password, vault_netbird_router_setup_key
# netbird_domain: "netbird.example.com"
# netbird_management_lb_ip: "" # пусто = kube-vip назначит автоматически
# netbird_signal_lb_ip: ""
# netbird_coturn_lb_ip: ""
# Subnet router (доступ к подсетям кластера из VPN):
# netbird_subnet_router_enabled: false
# netbird_subnet_routes: ["192.168.1.0/24", "10.42.0.0/16"]
# Exit node (весь интернет-трафик VPN-клиентов через k3s ноду):
# netbird_exit_node_enabled: false
# После установки — настрой маршруты в Management UI
# ─── etcd backup ──────────────────────────────────────────────────────────────
etcd_backup_dir: "{{ k3s_data_dir }}/server/db/snapshots"
etcd_backup_retention: 5 # сколько снимков хранить
etcd_backup_copy_to_local: false # скопировать на Ansible-хост
etcd_backup_local_dir: "./etcd-backups"