# Сеть и доступ ## ingress-nginx HTTP/S Ingress controller, точка входа для всех веб-приложений кластера. Подробнее: [addons/ingress-nginx/README.md](../addons/ingress-nginx/README.md). ```yaml addon_ingress_nginx: true ingress_nginx_load_balancer_ip: "" # авто от kube-vip ``` Базовый Ingress: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: ingressClassName: nginx tls: - hosts: [myapp.example.com] secretName: myapp-tls rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app port: number: 80 ``` --- ## cert-manager — TLS сертификаты Автоматические TLS сертификаты от Let's Encrypt или самоподписанного CA. Подробнее: [addons/cert-manager/README.md](../addons/cert-manager/README.md). ```yaml addon_cert_manager: true cert_manager_issuer: "letsencrypt" cert_manager_acme_email: "admin@example.com" ``` --- ## Istio — Service Mesh mTLS между сервисами, traffic management, observability. Подробнее: [addons/istio/README.md](../addons/istio/README.md). ```yaml addon_istio: true istio_mtls_mode: "STRICT" kiali_enabled: true ``` ### Включить sidecar injection ```bash kubectl label namespace my-app istio-injection=enabled ``` ### VirtualService routing ```yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: my-app spec: hosts: ["myapp.local"] gateways: ["istio-system/istio-ingressgateway"] http: - route: - destination: host: my-app port: number: 80 ``` --- ## NetBird VPN Self-hosted WireGuard VPN с управляемым сервером. Клиенты из любой точки мира получают доступ к подсетям кластера. Подробнее: [addons/netbird/README.md](../addons/netbird/README.md). ### Быстрый старт ```yaml addon_netbird: true netbird_domain: "netbird.example.com" # Subnet Router — доступ к локальной сети из VPN netbird_subnet_router_enabled: true netbird_subnet_routes: - "192.168.1.0/24" # локальная сеть - "10.42.0.0/16" # pod CIDR - "10.43.0.0/16" # service CIDR # Exit Node — интернет через кластер netbird_exit_node_enabled: false ``` ### Архитектура ``` VPN Client │ WireGuard ├──→ Management (gRPC LoadBalancer IP) ├──→ Signal (WebRTC signaling) └──→ Coturn (STUN/TURN для NAT traversal) │ └──→ Subnet Router Pod ──→ 192.168.1.0/24 └──→ 10.42.0.0/16 (pods) ``` ### Подключение клиентов ```bash netbird up --management-url grpc://netbird.example.com:80 ``` --- ## ingress-add-domains — добавить домены к сервисам кластера Позволяет быстро открыть дополнительные домены для уже существующих K8s сервисов без изменения их шаблонов. Создаёт **только Ingress** в namespace целевого сервиса. Подробнее: [addons/ingress-add-domains/README.md](../addons/ingress-add-domains/README.md). ```yaml # group_vars/all/addons.yml addon_ingress_add_domains: true ingress_add_domains_entries: # Внутренний домен без TLS - name: gitea-local hosts: [gitea.local] service: name: gitea-http namespace: gitea port: 3000 # Внешний домен с TLS + basic auth - name: grafana-home hosts: [grafana.home.ru] service: name: prometheus-stack-grafana namespace: monitoring port: 80 tls: enabled: true certManager: enabled: true issuer: letsencrypt-prod auth: enabled: true username: admin password: "{{ vault_grafana_proxy_password }}" ``` ```bash make addon-ingress-add-domains ``` | Сценарий | Инструмент | |---|---| | Открыть K8s-сервис по новому домену | **ingress-add-domains** | | Проксировать сервис вне кластера (по IP) | ingress-proxypass | --- ## ingress-proxypass — проксировать внешние сервисы Позволяет открыть по домену любой сервис, работающий **вне кластера** (роутер, NAS, Plex на отдельной машине и т.д.), через тот же ingress-nginx VIP. Для каждой записи создаётся: `Service (ClusterIP, без selector)` + `Endpoints` + `Ingress`. Подробнее: [addons/ingress-proxypass/README.md](../addons/ingress-proxypass/README.md). ```yaml # group_vars/all/addons.yml addon_ingress_proxypass: true ingress_proxypass_proxies: - name: router hosts: [router.home.ru] ips: [192.168.1.1] port: 8080 - name: nas hosts: [nas.home.ru] ips: [192.168.1.20] port: 5000 tls: enabled: true secretName: wildcard-tls - name: grafana-ext hosts: [grafana.home.ru] ips: [192.168.1.60] port: 3000 auth: enabled: true username: admin password: "{{ vault_proxy_password }}" # хэш генерируется автоматически ``` ```bash make addon-ingress-proxypass ``` Маршрут трафика: `kube-vip VIP → ingress-nginx → Service → Endpoints → внешний IP:PORT` --- ## splitgw — прозрачный split-tunnel gateway Устанавливает `sing-box` с TPROXY-перехватом на хосте или K3S DaemonSet. Трафик с указанных устройств (Smart TV и т.п.) маршрутизируется по правилам: YouTube/Google → Hysteria2 VPN, RU-сервисы и частные сети → прямой маршрут. Подробнее: [addons/splitgw/README.md](../addons/splitgw/README.md). ```yaml # group_vars/all/addons.yml (+ group [splitgw] в inventory) addon_splitgw: true splitgw_tv_sources: - "192.168.1.100/32" # Smart TV splitgw_router_ip: "192.168.1.1" # vault_hysteria2_url задаётся в vault.yml ``` ```bash # Режим systemd на хосте (по умолчанию): make addon-splitgw # Режим K8s DaemonSet: make addon-splitgw ARGS="-e splitgw_deploy_mode=k8s" ``` Маршрут: `Smart TV → шлюз splitgw (TPROXY:7893) → sing-box → YouTube/Google: Hysteria2 VPN | остальное: прямой` --- ## hysteria2-server — VPN-сервер на удалённом VPS Устанавливает Hysteria2-сервер на внешний VPS (не часть кластера). Сервер нужен для `splitgw` и `mediaserver` (Prowlarr sidecar). Подробнее: [addons/hysteria2-server/README.md](../addons/hysteria2-server/README.md). ```yaml # inventory/hosts.ini [hysteria2_server] myvps ansible_host=1.2.3.4 ansible_user=root # group_vars/all/vault.yml vault_hysteria2_server_password: "мойпароль" ``` ```bash # По SSH-ключу: make addon-hysteria2-server # По SSH-паролю (интерактивный ввод): make addon-hysteria2-server ARGS="-k" ``` После установки выводится готовая URL-строка для Shadowrocket / NekoBox / Hiddify: ``` hysteria2://пароль@1.2.3.4:443?insecure=1#MyVPS ``` --- ## kube-vip LoadBalancer kube-vip обрабатывает все `LoadBalancer` сервисы — каждый сервис с `type: LoadBalancer` автоматически получает IP из подсети кластера. ```yaml apiVersion: v1 kind: Service metadata: name: my-tcp-service annotations: kube-vip.io/loadbalancerIPs: "192.168.1.150" # статический IP (опционально) spec: type: LoadBalancer ports: - port: 8080 targetPort: 8080 selector: app: my-app ``` --- ## DNS внутри кластера Паттерны DNS для сервисов: ``` ..svc.cluster.local # Примеры: postgresql.postgresql.svc.cluster.local:5432 minio.minio.svc.cluster.local:9000 vault.vault.svc.cluster.local:8200 loki.loki.svc.cluster.local:3100 smtp-relay.smtp-relay.svc.cluster.local:25 tempo.tempo.svc.cluster.local:4317 ``` --- ## Network Policies (Calico/Cilium) Требует `k3s_cni: "calico"` или `k3s_cni: "cilium"`. ```yaml # Запретить весь трафик в namespace: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: my-app spec: podSelector: {} policyTypes: [Ingress, Egress] --- # Разрешить только из ingress-nginx: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress namespace: my-app spec: podSelector: matchLabels: app: my-app ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: ingress-nginx ports: - port: 8080 --- # Разрешить DNS (CoreDNS): apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns namespace: my-app spec: podSelector: {} egress: - ports: - port: 53 protocol: UDP - port: 53 protocol: TCP ``` --- ## Cilium — дополнительные возможности ```yaml k3s_cni: "cilium" cilium_hubble_enabled: true # observability cilium_hubble_ui_enabled: false # Hubble UI ``` L7 Network Policy (только Cilium): ```yaml apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: allow-http-get spec: endpointSelector: matchLabels: app: my-api ingress: - fromEndpoints: - matchLabels: app: frontend toPorts: - ports: - port: "8080" protocol: TCP rules: http: - method: GET path: "/api/.*" ```