Топология k3s: 1 мастер + 2 воркера (убран k3s-worker-3 с томом).
Vault ↔ k3s. Vault живёт в compose, вне кластера, поэтому получает
статический IP 172.28.0.13, DNS-мост в namespace vault и token reviewer
(SA vault-auth + system:auth-delegator). Ansible включает auth/kubernetes,
передавая адрес apiserver, CA и JWT ревьюера явно, и заводит политику с
ролями. Секрет token reviewer'а читается целиком в JSON: вариант
-o jsonpath={.data.ca\.crt} НЕ работает — модуль command разбирает строку
через shlex, съедает обратный слэш, kubectl возвращает пустую строку с
кодом 0, и отказ остаётся незамеченным до падения vault write.
Синхронизация репозитория в gitea. Нужное подмножество путей (замыкание
ссылок clusters/aero) едет архивом на хост и коммитится там: gitea не
публикуется дальше самого хоста, контур остаётся замкнутым. flux-bootstrap
вынесен в отдельную волну — до неё Vault получает auth/kubernetes, а
репозиторий наполняется, иначе первая реконсиляция падает на пустом репо.
Инфраструктура: vault-agent-injector (чарт vault-contour в режиме внешнего
Vault), local-path-provisioner взамен встроенного в k3s (--disable=
local-storage; путь данных прежний), rabbitmq и minio с кредами из Vault.
Выход наружу: порты 80/443 k3s-server опубликованы (istio ingressgateway
занимает эти hostPort), общий contour-gateway на wildcard-хост, сертификат
Let's Encrypt через http01. Имена в сертификате перечислены явно —
http01 не выдаёт wildcard, для них нужен dns01.
Разорваны два дедлока Flux: infra-configs больше не зависит от
infra-controllers (издатели не должны зависеть от здоровья чартов, которые
их используют), istio-config получил disableWait.
Модули ядра iptable_nat и смежные грузятся на хосте: ноды k3s —
контейнеры, istio-init правит iptables через ядро хоста, а на RED OS 8
(nf_tables) legacy-модули не загружены, из-за чего любой под с
istio-injection навсегда вставал в Init:Error.
Собственные Gateway/VirtualService/Certificate чартов rabbitmq и dashboard
отключены — маршрутизация описана централизованно. У rabbitmq это сделано
postRenderers, а не values: kustomize нормализует null в {}, а пустую карту
Helm сливает с дефолтами, возвращая их целиком.
157 lines
8.8 KiB
YAML
157 lines
8.8 KiB
YAML
apiVersion: helm.toolkit.fluxcd.io/v2
|
||
kind: HelmRelease
|
||
metadata:
|
||
name: istio-config
|
||
namespace: default
|
||
spec:
|
||
interval: 5m
|
||
timeout: 10m
|
||
# disableWait РАЗРЫВАЕТ ДЕДЛОК, не украшательство.
|
||
#
|
||
# Чарт создаёт Certificate, а Flux после установки релиза ждёт готовности его
|
||
# ресурсов — в том числе этого сертификата. Выпустить его нельзя, пока нет
|
||
# ClusterIssuer, а издатели живут в слое infra-configs, который по dependsOn
|
||
# ждёт готовности infra-controllers, где и находится этот самый релиз. Круг:
|
||
# istio-config → Certificate → ClusterIssuer → infra-configs
|
||
# → infra-controllers → istio-config
|
||
# На практике это выглядело как вечное "Running 'upgrade' action" при
|
||
# Released: True и Certificate в состоянии
|
||
# "Issuing certificate as Secret does not exist".
|
||
#
|
||
# Ждать здесь всё равно нечего: чарт разворачивает только конфигурационные
|
||
# объекты (Gateway, VirtualService, Certificate), а не рабочие нагрузки.
|
||
# Сертификат выпустится асинхронно, как только появится издатель.
|
||
install:
|
||
disableWait: true
|
||
upgrade:
|
||
disableWait: true
|
||
# Список продублирован из base целиком: для CRD kustomize заменяет списки,
|
||
# а не сливает, поэтому частичный патч потерял бы зависимости от istio.
|
||
# cert-manager добавлен сверх base — чарт istio-config рендерит Certificate,
|
||
# и без готовых CRD установка падает.
|
||
dependsOn:
|
||
- name: istio-base
|
||
namespace: istio-system
|
||
- name: istiod
|
||
namespace: istio-system
|
||
- name: ingressgateway
|
||
namespace: istio-system
|
||
- name: cert-manager
|
||
namespace: cert-manager
|
||
values:
|
||
global:
|
||
env: aero
|
||
environments:
|
||
aero:
|
||
namespaces: []
|
||
# Блок обязателен, даже пустой: шаблоны gateway.yaml и virtualservice.yaml
|
||
# разыменовывают $env.istio.gateways / .virtualServices без проверки на
|
||
# nil и падают с "nil pointer evaluating interface {}".
|
||
istio:
|
||
# Один общий Gateway на весь контур вместо отдельного на каждый сервис.
|
||
# Так сделано потому, что у контура есть wildcard-домен: сертификат и
|
||
# Gateway покрывают *.sarex.local.lonsdaleites.ru целиком, а новый
|
||
# сервис публикуется добавлением ОДНОГО VirtualService — без правки
|
||
# сертификатов и Gateway. В прод-кластерах домены выписаны поштучно,
|
||
# там wildcard'а нет.
|
||
gateways:
|
||
contour:
|
||
name: contour-gateway
|
||
namespace: gateway
|
||
servers:
|
||
# ПОРЯДОК ЗНАЧИМ: первым обязан идти хост без звёздочки.
|
||
# Чарт собирает из hosts[0] имя порта
|
||
# name: {{ printf "%s-https-443" (index $server.hosts 0 ...) }}
|
||
# и НЕ заключает результат в кавычки. Хост "*.domain" дал бы
|
||
# токен "*-domain-https-443", который YAML читает как ссылку на
|
||
# якорь, и Helm падает с
|
||
# MalformedYAMLError: yaml: unknown anchor ... referenced
|
||
# Сами hosts чарт квотирует, поэтому wildcard ниже безопасен.
|
||
- hosts:
|
||
- sarex.local.lonsdaleites.ru
|
||
- "*.sarex.local.lonsdaleites.ru"
|
||
tls:
|
||
credentialName: contour-tls
|
||
# ВНИМАНИЕ: имя ресурса VirtualService чарт берёт из КЛЮЧА map
|
||
# ({{ $vsName }}), а поле name внутри — игнорирует, в отличие от
|
||
# gateways, где .name учитывается. Поэтому здесь его нет: ключ и есть
|
||
# имя. В остальных кластерах репозитория name у virtualServices
|
||
# присутствует, но ни на что не влияет.
|
||
virtualServices:
|
||
# Kubernetes Dashboard. Свой VirtualService чарт дашборда создаёт на
|
||
# домен dashboard.preprod.sarex.io — он к контуру aero отношения не
|
||
# имеет и никуда не резолвится. Этот выводит дашборд на домен
|
||
# контура; точка входа — kong-proxy, как во всех остальных кластерах.
|
||
dashboard:
|
||
namespace: gateway
|
||
hosts:
|
||
- dashboard.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
prefix: /
|
||
service: dashboard-kong-proxy.kubernetes-dashboard.svc.cluster.local
|
||
port: 80
|
||
# Management UI RabbitMQ.
|
||
rabbitmq:
|
||
namespace: gateway
|
||
hosts:
|
||
- rabbitmq.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
prefix: /
|
||
service: rabbitmq.rabbitmq.svc.cluster.local
|
||
port: 15672
|
||
# MinIO: консоль на /console/, S3 API в корне. Порядок маршрутов
|
||
# значим — более специфичный префикс должен идти первым, иначе его
|
||
# перехватит правило для /.
|
||
minio:
|
||
namespace: gateway
|
||
hosts:
|
||
- minio.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
prefix: /console/
|
||
service: minio-console.minio.svc.cluster.local
|
||
port: 9001
|
||
- path:
|
||
prefix: /
|
||
service: minio.minio.svc.cluster.local
|
||
port: 9000
|
||
requestAuthentications: {}
|
||
authorizationPolicies: {}
|
||
certManager:
|
||
certificates:
|
||
# Издатель — внутренний CA контура, а не ACME: до Let's Encrypt
|
||
# из закрытого контура не достучаться.
|
||
# См. infrastructure/cert-manager/aero/clusterissuer-ca.yaml
|
||
#
|
||
# Домены продублированы из aero/roles/sarex_stack/defaults/main.yml
|
||
# (platform_domain и производные). Единого источника нет — так же
|
||
# захардкожено во всех остальных кластерах репозитория.
|
||
#
|
||
# Один сертификат на весь контур, общий для всех его сервисов.
|
||
contour-tls:
|
||
# Имена перечислены ЯВНО, а не wildcard'ом: решатель http01
|
||
# принципиально не выдаёт wildcard-сертификаты, для них Let's
|
||
# Encrypt требует dns01, а webhook DNS-провайдера в контуре не
|
||
# настроен. Wildcard остался в hosts Gateway — там он про
|
||
# маршрутизацию, а не про TLS.
|
||
#
|
||
# Публикуешь новый сервис — добавь его имя сюда, иначе браузер
|
||
# получит сертификат, в котором этого имени нет.
|
||
dnsNames:
|
||
- sarex.local.lonsdaleites.ru
|
||
- dashboard.sarex.local.lonsdaleites.ru
|
||
- rabbitmq.sarex.local.lonsdaleites.ru
|
||
- minio.sarex.local.lonsdaleites.ru
|
||
issuerRef:
|
||
# Боевой издатель, см. infrastructure/cert-manager/aero/configs.
|
||
name: letsencrypt-issuer-istio
|
||
kind: ClusterIssuer
|