feat(ansible): add private registry configuration for k3s and Flux with secure key handling
This commit is contained in:
parent
8a8cd66f59
commit
457f0dad41
21
.gitignore
vendored
21
.gitignore
vendored
@ -10,10 +10,23 @@ tmp
|
|||||||
snapshots/*
|
snapshots/*
|
||||||
|
|
||||||
# --- Рантайм-артефакты контура aero (создаются docker-compose на хосте) ---
|
# --- Рантайм-артефакты контура aero (создаются docker-compose на хосте) ---
|
||||||
gitea-data/ # данные gitea: репозитории, sqlite
|
# ВНИМАНИЕ: комментарии в .gitignore работают только с начала строки,
|
||||||
k3s-storage/ # PVC-данные local-path-provisioner
|
# в конце строки они становятся частью паттерна и ломают его.
|
||||||
k3s/kubeconfig.yaml # kubeconfig, который пишет k3s-server
|
|
||||||
nginx/certs/ # самоподписанные TLS-сертификаты
|
# данные gitea: репозитории, sqlite
|
||||||
|
gitea-data/
|
||||||
|
# PVC-данные local-path-provisioner
|
||||||
|
k3s-storage/
|
||||||
|
# kubeconfig, который пишет k3s-server
|
||||||
|
k3s/kubeconfig.yaml
|
||||||
|
# СОДЕРЖИТ КЛЮЧ реестра — рендерится ролью sarex_stack
|
||||||
|
k3s/registries.yaml
|
||||||
|
# СОДЕРЖИТ КЛЮЧ реестра — временный, удаляется после kubectl apply
|
||||||
|
k3s/registry-secret.yaml
|
||||||
|
# временная копия ключа реестра на хосте
|
||||||
|
registry-key.json
|
||||||
|
# самоподписанные TLS-сертификаты
|
||||||
|
nginx/certs/
|
||||||
|
|
||||||
# --- Секреты и ключи: не коммитить никогда ---
|
# --- Секреты и ключи: не коммитить никогда ---
|
||||||
*.pem
|
*.pem
|
||||||
|
|||||||
@ -36,11 +36,28 @@ secrets_store: "{{ playbook_dir }}/.secrets"
|
|||||||
jwt_private_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_private.pem"
|
jwt_private_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_private.pem"
|
||||||
jwt_public_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_public.pem"
|
jwt_public_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_public.pem"
|
||||||
|
|
||||||
# Приватный реестр образов и ключ для входа (json_key)
|
# --- Приватный реестр образов и чартов (cr.yandex, аутентификация json_key) ---
|
||||||
registry_host: cr.yandex
|
registry_host: cr.yandex
|
||||||
registry_username: json_key
|
registry_username: json_key
|
||||||
# Windows: C:\Users\user\.ssh\local\authorized_key.json → в WSL это /mnt/c/...
|
|
||||||
registry_key_src: /mnt/c/Users/user/.ssh/local/authorized_key.json
|
# Путь к ключу сервисного аккаунта НА CONTROL-NODE (ansible запускается из WSL,
|
||||||
|
# поэтому диск C: виден как /mnt/c). Это машинно-зависимое значение —
|
||||||
|
# переопределяйте, не редактируя роль:
|
||||||
|
# uv run poe platform -- -e registry_key_src=/path/to/authorized_key.json
|
||||||
|
registry_key_src: "/mnt/c/Users/user/Downloads/Telegram Desktop/authorized_key.json"
|
||||||
|
|
||||||
|
# Куда ключ кладётся на целевом хосте на время провижининга (удаляется после).
|
||||||
|
registry_key_dest: "{{ deploy_dir }}/registry-key.json"
|
||||||
|
|
||||||
|
# Секреты в кластере. Namespace создаётся вместе с секретом — он нужен раньше,
|
||||||
|
# чем чарт создаст его сам. Список пополняется по мере переезда компонентов.
|
||||||
|
# * yc-cr-auth (flux-system) — Flux тянет им OCI-ЧАРТЫ. Обязателен.
|
||||||
|
# * regcred — imagePullSecrets подов в namespace потребителя.
|
||||||
|
registry_secrets:
|
||||||
|
- {name: yc-cr-auth, namespace: flux-system}
|
||||||
|
- {name: regcred, namespace: cert-manager}
|
||||||
|
- {name: regcred, namespace: istio-system}
|
||||||
|
- {name: regcred, namespace: kubernetes-dashboard}
|
||||||
|
|
||||||
# Поднимать стек (docker compose up -d). Требует запущенной службы docker и
|
# Поднимать стек (docker compose up -d). Требует запущенной службы docker и
|
||||||
# docker login в cr.yandex — по умолчанию выключено.
|
# docker login в cr.yandex — по умолчанию выключено.
|
||||||
|
|||||||
@ -144,40 +144,12 @@
|
|||||||
-addext "subjectAltName=DNS:{{ platform_domain }},DNS:{{ admin_domain }},DNS:{{ minio_domain }}"
|
-addext "subjectAltName=DNS:{{ platform_domain }},DNS:{{ admin_domain }},DNS:{{ minio_domain }}"
|
||||||
creates: "{{ cert_dir }}/selfsigned.crt"
|
creates: "{{ cert_dir }}/selfsigned.crt"
|
||||||
|
|
||||||
# --- Логин в приватный реестр образов (json_key) --------------------------
|
# --- Доступ к приватному реестру (docker на хосте + registries.yaml нод) ---
|
||||||
- name: Проверить, выполнен ли вход в реестр
|
# Обязательно ДО подъёма k3s: registries.yaml монтируется в ноды, и k3s читает
|
||||||
ansible.builtin.command: grep -q "{{ registry_host }}" /root/.docker/config.json
|
# его только при старте.
|
||||||
register: registry_login_state
|
- name: Настроить доступ к приватному реестру
|
||||||
changed_when: false
|
ansible.builtin.include_tasks: registry.yml
|
||||||
failed_when: false
|
tags: [login, registry]
|
||||||
tags: [login]
|
|
||||||
|
|
||||||
- name: Скопировать ключ реестра на хост (временно)
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: "{{ registry_key_src }}"
|
|
||||||
dest: /root/.registry-key.json
|
|
||||||
mode: "0600"
|
|
||||||
when: registry_login_state.rc != 0
|
|
||||||
no_log: true
|
|
||||||
tags: [login]
|
|
||||||
|
|
||||||
- name: docker login в приватный реестр
|
|
||||||
ansible.builtin.shell: >-
|
|
||||||
set -o pipefail && cat /root/.registry-key.json
|
|
||||||
| docker login --username {{ registry_username }} --password-stdin {{ registry_host }}
|
|
||||||
args:
|
|
||||||
executable: /bin/bash
|
|
||||||
when: registry_login_state.rc != 0
|
|
||||||
register: registry_login_result
|
|
||||||
changed_when: "'Login Succeeded' in registry_login_result.stdout"
|
|
||||||
no_log: true
|
|
||||||
tags: [login]
|
|
||||||
|
|
||||||
- name: Удалить временный ключ реестра с хоста
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /root/.registry-key.json
|
|
||||||
state: absent
|
|
||||||
tags: [login]
|
|
||||||
|
|
||||||
# --- GitOps-подложка: k3s + gitea + vault + Flux --------------------------
|
# --- GitOps-подложка: k3s + gitea + vault + Flux --------------------------
|
||||||
# Отдельный тег и отдельный флаг: подложка поднимается публичными образами и
|
# Отдельный тег и отдельный флаг: подложка поднимается публичными образами и
|
||||||
|
|||||||
@ -28,6 +28,11 @@
|
|||||||
search_regex: "clusters:"
|
search_regex: "clusters:"
|
||||||
timeout: 60
|
timeout: 60
|
||||||
|
|
||||||
|
# Секреты реестра — до bootstrap: без yc-cr-auth в flux-system source-controller
|
||||||
|
# не сможет скачать ни один OCI-чарт, и вся первая волна инфраструктуры встанет.
|
||||||
|
- name: Создать секреты доступа к реестру в кластере
|
||||||
|
ansible.builtin.include_tasks: registry-secrets.yml
|
||||||
|
|
||||||
- name: Волна 2 — gitea-init, vault(+init) и bootstrap Flux
|
- name: Волна 2 — gitea-init, vault(+init) и bootstrap Flux
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
cmd: "{{ compose_cmd }} up -d {{ aero_platform_services_wave2 | join(' ') }}"
|
cmd: "{{ compose_cmd }} up -d {{ aero_platform_services_wave2 | join(' ') }}"
|
||||||
|
|||||||
41
aero/roles/sarex_stack/tasks/registry-secrets.yml
Normal file
41
aero/roles/sarex_stack/tasks/registry-secrets.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
# Секреты доступа к приватному реестру внутри кластера.
|
||||||
|
# Требуют поднятого k3s — включается из platform.yml после первой волны.
|
||||||
|
#
|
||||||
|
# Манифест собирается из шаблона и ключа сервисного аккаунта, применяется
|
||||||
|
# kubectl'ом и сразу удаляется: в нём секрет в открытом виде.
|
||||||
|
# Ключ уже прочитан в registry_key_content задачей из registry.yml.
|
||||||
|
|
||||||
|
- name: Отрендерить манифест секретов реестра
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: registry-secret.yaml.j2
|
||||||
|
dest: "{{ deploy_dir }}/k3s/registry-secret.yaml"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0600"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# ./k3s смонтирован в k3s-server как /output — отсюда и путь.
|
||||||
|
- name: Применить секреты реестра в кластере
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "{{ compose_cmd.split()[0] }}"
|
||||||
|
- compose
|
||||||
|
- exec
|
||||||
|
- "-T"
|
||||||
|
- k3s-server
|
||||||
|
- kubectl
|
||||||
|
- apply
|
||||||
|
- "-f"
|
||||||
|
- /output/registry-secret.yaml
|
||||||
|
chdir: "{{ deploy_dir }}"
|
||||||
|
register: registry_secret_apply
|
||||||
|
changed_when: >-
|
||||||
|
'created' in registry_secret_apply.stdout or
|
||||||
|
'configured' in registry_secret_apply.stdout
|
||||||
|
|
||||||
|
# Удаляем всегда, в том числе если apply упал: файл содержит ключ.
|
||||||
|
- name: Удалить манифест секретов с хоста
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ deploy_dir }}/k3s/registry-secret.yaml"
|
||||||
|
state: absent
|
||||||
112
aero/roles/sarex_stack/tasks/registry.yml
Normal file
112
aero/roles/sarex_stack/tasks/registry.yml
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
# Доступ к приватному реестру cr.yandex (аутентификация json_key).
|
||||||
|
#
|
||||||
|
# Три независимых потребителя, каждому нужен свой способ:
|
||||||
|
# 1. docker на хосте — образы сервисов compose (backend, frontend, ...)
|
||||||
|
# 2. containerd на нодах — образы подов; /etc/rancher/k3s/registries.yaml
|
||||||
|
# 3. source-controller Flux — OCI-чарты; Secret yc-cr-auth в flux-system
|
||||||
|
#
|
||||||
|
# Ключ читается с control-node и на целевой хост в открытом виде не кладётся
|
||||||
|
# (кроме короткого окна для docker login, см. ниже).
|
||||||
|
|
||||||
|
- name: Проверить наличие ключа реестра на control-node
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ registry_key_src }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
register: registry_key_stat
|
||||||
|
tags: [login, registry]
|
||||||
|
|
||||||
|
- name: Прервать деплой, если ключа нет
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: |
|
||||||
|
Не найден ключ сервисного аккаунта: {{ registry_key_src }}
|
||||||
|
|
||||||
|
Без него не поедет ни один компонент — все чарты и образы лежат
|
||||||
|
в приватном реестре {{ registry_host }}.
|
||||||
|
|
||||||
|
Укажите актуальный путь:
|
||||||
|
uv run poe platform -- -e registry_key_src=/path/to/authorized_key.json
|
||||||
|
when: not registry_key_stat.stat.exists
|
||||||
|
tags: [login, registry]
|
||||||
|
|
||||||
|
- name: Прочитать ключ реестра с control-node
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
registry_key_content: "{{ lookup('file', registry_key_src) }}"
|
||||||
|
no_log: true
|
||||||
|
tags: [login, registry]
|
||||||
|
|
||||||
|
# --- 1. docker на хосте ----------------------------------------------------
|
||||||
|
- name: Проверить, выполнен ли вход в реестр
|
||||||
|
ansible.builtin.command: grep -q "{{ registry_host }}" /root/.docker/config.json
|
||||||
|
register: registry_login_state
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
- name: Скопировать ключ реестра на хост (временно)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ registry_key_content }}"
|
||||||
|
dest: "{{ registry_key_dest }}"
|
||||||
|
mode: "0600"
|
||||||
|
when: registry_login_state.rc != 0
|
||||||
|
no_log: true
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
- name: docker login в приватный реестр
|
||||||
|
ansible.builtin.shell: >-
|
||||||
|
set -o pipefail && cat {{ registry_key_dest | quote }}
|
||||||
|
| docker login --username {{ registry_username }} --password-stdin {{ registry_host }}
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
when: registry_login_state.rc != 0
|
||||||
|
register: registry_login_result
|
||||||
|
changed_when: "'Login Succeeded' in registry_login_result.stdout"
|
||||||
|
no_log: true
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
# helm на хосте может отсутствовать — он нужен только для ручной отладки.
|
||||||
|
# Flux чарты тянет сам, по секрету yc-cr-auth, а не через helm CLI.
|
||||||
|
- name: Проверить наличие helm на хосте
|
||||||
|
ansible.builtin.command: which helm
|
||||||
|
register: registry_helm_present
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
- name: helm registry login (если helm установлен)
|
||||||
|
ansible.builtin.shell: >-
|
||||||
|
set -o pipefail && cat {{ registry_key_dest | quote }}
|
||||||
|
| helm registry login {{ registry_host }} --username {{ registry_username }} --password-stdin
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
when:
|
||||||
|
- registry_helm_present.rc == 0
|
||||||
|
- registry_login_state.rc != 0
|
||||||
|
register: registry_helm_login
|
||||||
|
changed_when: "'Login Succeeded' in registry_helm_login.stdout"
|
||||||
|
no_log: true
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
- name: Удалить временный ключ реестра с хоста
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ registry_key_dest }}"
|
||||||
|
state: absent
|
||||||
|
tags: [login]
|
||||||
|
|
||||||
|
# --- 2. containerd на нодах k3s -------------------------------------------
|
||||||
|
# Монтируется во все ноды (см. docker-compose.yaml). Изменение файла требует
|
||||||
|
# перезапуска нод — k3s читает registries.yaml только на старте.
|
||||||
|
- name: Отрендерить registries.yaml для нод k3s
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: registries.yaml.j2
|
||||||
|
dest: "{{ deploy_dir }}/k3s/registries.yaml"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0600"
|
||||||
|
no_log: true
|
||||||
|
tags: [registry]
|
||||||
|
|
||||||
|
# Секреты доступа в самом кластере создаются отдельно (registry-secrets.yml):
|
||||||
|
# они требуют уже поднятого k3s, поэтому включаются из platform.yml после
|
||||||
|
# первой волны, а не здесь.
|
||||||
21
aero/roles/sarex_stack/templates/registries.yaml.j2
Normal file
21
aero/roles/sarex_stack/templates/registries.yaml.j2
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#jinja2: trim_blocks:True, lstrip_blocks:True
|
||||||
|
# Аутентификация containerd в приватном реестре — на уровне НОДЫ k3s.
|
||||||
|
# Файл монтируется в /etc/rancher/k3s/registries.yaml на каждую ноду.
|
||||||
|
#
|
||||||
|
# Почему так, а не imagePullSecrets/regcred в каждом namespace: контур
|
||||||
|
# однотенантный и реестр всего один, поэтому узловая настройка избавляет от
|
||||||
|
# необходимости заводить секрет в каждом новом namespace. Манифесты из репозитория
|
||||||
|
# при этом продолжают ссылаться на regcred — отсутствующий imagePullSecret
|
||||||
|
# kubelet допускает: он логирует событие и тянет образ кредами ноды.
|
||||||
|
#
|
||||||
|
# ВНИМАНИЕ: файл содержит секрет. Рендерится с mode 0600, в git не попадает.
|
||||||
|
mirrors:
|
||||||
|
"{{ registry_host }}":
|
||||||
|
endpoint:
|
||||||
|
- "https://{{ registry_host }}"
|
||||||
|
|
||||||
|
configs:
|
||||||
|
"{{ registry_host }}":
|
||||||
|
auth:
|
||||||
|
username: "{{ registry_username }}"
|
||||||
|
password: {{ registry_key_content | to_json }}
|
||||||
43
aero/roles/sarex_stack/templates/registry-secret.yaml.j2
Normal file
43
aero/roles/sarex_stack/templates/registry-secret.yaml.j2
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#jinja2: trim_blocks:True, lstrip_blocks:True
|
||||||
|
{#
|
||||||
|
Манифест секретов доступа к приватному реестру, собираемый из ключа
|
||||||
|
сервисного аккаунта (registry_key_src) на control-node.
|
||||||
|
|
||||||
|
Секретов два и они РАЗНОГО назначения:
|
||||||
|
* yc-cr-auth (flux-system) — им source-controller тянет OCI-ЧАРТЫ.
|
||||||
|
Обязателен: без него не поедет ни один HelmRelease.
|
||||||
|
* regcred (namespace потребителя) — imagePullSecrets подов. Продублирован
|
||||||
|
из манифестов репозитория; на уровне ноды образы и так доступны через
|
||||||
|
/etc/rancher/k3s/registries.yaml, но манифесты на него ссылаются.
|
||||||
|
|
||||||
|
Namespace создаётся здесь же: секрет нужен РАНЬШЕ, чем чарт создаст namespace.
|
||||||
|
|
||||||
|
ВНИМАНИЕ: файл содержит секрет в открытом виде. Рендерится с mode 0600
|
||||||
|
во временный каталог и удаляется сразу после kubectl apply.
|
||||||
|
#}
|
||||||
|
{% set docker_config = {
|
||||||
|
"auths": {
|
||||||
|
registry_host: {
|
||||||
|
"username": registry_username,
|
||||||
|
"password": registry_key_content,
|
||||||
|
"auth": (registry_username ~ ":" ~ registry_key_content) | b64encode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
{% for s in registry_secrets %}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ s.namespace }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ s.name }}
|
||||||
|
namespace: {{ s.namespace }}
|
||||||
|
type: kubernetes.io/dockerconfigjson
|
||||||
|
data:
|
||||||
|
.dockerconfigjson: {{ docker_config | to_json | b64encode }}
|
||||||
|
{% endfor %}
|
||||||
6432
clusters/aero/flux-system/gotk-components.yaml
Normal file
6432
clusters/aero/flux-system/gotk-components.yaml
Normal file
File diff suppressed because it is too large
Load Diff
27
clusters/aero/flux-system/gotk-sync.yaml
Normal file
27
clusters/aero/flux-system/gotk-sync.yaml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# This manifest was generated by flux. DO NOT EDIT.
|
||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1
|
||||||
|
kind: GitRepository
|
||||||
|
metadata:
|
||||||
|
name: flux-system
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
interval: 1m0s
|
||||||
|
ref:
|
||||||
|
branch: master
|
||||||
|
secretRef:
|
||||||
|
name: flux-system
|
||||||
|
url: http://gitea.flux-system.svc.cluster.local:3000/infra/iac.git
|
||||||
|
---
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: flux-system
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
interval: 10m0s
|
||||||
|
path: ./clusters/aero
|
||||||
|
prune: true
|
||||||
|
sourceRef:
|
||||||
|
kind: GitRepository
|
||||||
|
name: flux-system
|
||||||
5
clusters/aero/flux-system/kustomization.yaml
Normal file
5
clusters/aero/flux-system/kustomization.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- gotk-components.yaml
|
||||||
|
- gotk-sync.yaml
|
||||||
14
clusters/aero/helm-repositories.yaml
Normal file
14
clusters/aero/helm-repositories.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1
|
||||||
|
kind: HelmRepository
|
||||||
|
metadata:
|
||||||
|
name: yc-oci-charts
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
type: oci
|
||||||
|
interval: 10m0s
|
||||||
|
url: oci://cr.yandex/crp3ccidau046kdj8g9q/charts
|
||||||
|
# Секрет создаёт роль sarex_stack из ключа сервисного аккаунта
|
||||||
|
# (см. aero/roles/sarex_stack/templates/registry-secret.yaml.j2).
|
||||||
|
secretRef:
|
||||||
|
name: yc-cr-auth
|
||||||
@ -14,6 +14,9 @@ x-k3s-worker: &k3s-worker
|
|||||||
environment:
|
environment:
|
||||||
K3S_URL: https://k3s-server:6443
|
K3S_URL: https://k3s-server:6443
|
||||||
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
|
K3S_TOKEN: ${K3S_TOKEN:-supersecrettoken}
|
||||||
|
# ВНИМАНИЕ: volumes здесь не задаём — merge-ключ `<<:` не сливает списки,
|
||||||
|
# и volumes сервиса перекрыл бы якорь целиком. Монтирования, включая
|
||||||
|
# registries.yaml, перечислены в каждом воркере явно.
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /run
|
- /run
|
||||||
- /var/run
|
- /var/run
|
||||||
@ -48,6 +51,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- k3s-server-data:/var/lib/rancher/k3s # etcd/state, образы, манифесты — только named volume
|
- k3s-server-data:/var/lib/rancher/k3s # etcd/state, образы, манифесты — только named volume
|
||||||
- ./k3s:/output:z # отсюда забираем контекст k8s (:z — SELinux label для RedOS)
|
- ./k3s:/output:z # отсюда забираем контекст k8s (:z — SELinux label для RedOS)
|
||||||
|
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z # доступ containerd к cr.yandex
|
||||||
# PVC-данные local-path-provisioner (StorageClass local-path, он же default
|
# PVC-данные local-path-provisioner (StorageClass local-path, он же default
|
||||||
# в k3s). Перекрываем ровно дефолтный путь провижинера, поэтому настраивать
|
# в k3s). Перекрываем ровно дефолтный путь провижинера, поэтому настраивать
|
||||||
# ConfigMap local-path-config не нужно. Bind-mount на хост означает, что
|
# ConfigMap local-path-config не нужно. Bind-mount на хост означает, что
|
||||||
@ -82,6 +86,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- k3s-worker-1-data:/var/lib/rancher/k3s
|
- k3s-worker-1-data:/var/lib/rancher/k3s
|
||||||
- ./k3s-storage/worker-1:/var/lib/rancher/k3s/storage:z
|
- ./k3s-storage/worker-1:/var/lib/rancher/k3s/storage:z
|
||||||
|
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z
|
||||||
|
|
||||||
k3s-worker-2:
|
k3s-worker-2:
|
||||||
<<: *k3s-worker
|
<<: *k3s-worker
|
||||||
@ -90,6 +95,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- k3s-worker-2-data:/var/lib/rancher/k3s
|
- k3s-worker-2-data:/var/lib/rancher/k3s
|
||||||
- ./k3s-storage/worker-2:/var/lib/rancher/k3s/storage:z
|
- ./k3s-storage/worker-2:/var/lib/rancher/k3s/storage:z
|
||||||
|
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z
|
||||||
|
|
||||||
k3s-worker-3:
|
k3s-worker-3:
|
||||||
<<: *k3s-worker
|
<<: *k3s-worker
|
||||||
@ -98,6 +104,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- k3s-worker-3-data:/var/lib/rancher/k3s
|
- k3s-worker-3-data:/var/lib/rancher/k3s
|
||||||
- ./k3s-storage/worker-3:/var/lib/rancher/k3s/storage:z
|
- ./k3s-storage/worker-3:/var/lib/rancher/k3s/storage:z
|
||||||
|
- ./k3s/registries.yaml:/etc/rancher/k3s/registries.yaml:ro,z
|
||||||
|
|
||||||
# Одноразовый провижининг k3s: namespace processing + DNS-мост postgres/minio.
|
# Одноразовый провижининг k3s: namespace processing + DNS-мост postgres/minio.
|
||||||
# Образ k3s содержит kubectl; server/tls перекрываем на k3s-server:6443
|
# Образ k3s содержит kubectl; server/tls перекрываем на k3s-server:6443
|
||||||
|
|||||||
53
infrastructure/cert-manager/aero/clusterissuer-ca.yaml
Normal file
53
infrastructure/cert-manager/aero/clusterissuer-ca.yaml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Внутренний удостоверяющий центр контура aero.
|
||||||
|
#
|
||||||
|
# Зачем отдельный издатель: в репозитории все ClusterIssuer — ACME (Let's Encrypt)
|
||||||
|
# с решателем http01 и ingress class nginx. Контур закрытый, публичного DNS и
|
||||||
|
# входящего HTTP от ACME-сервера нет, поэтому ACME здесь принципиально нерабочий.
|
||||||
|
#
|
||||||
|
# Схема стандартная для внутренней PKI, в три шага:
|
||||||
|
# 1. selfsigned-issuer — самоподписывающий издатель, нужен только чтобы
|
||||||
|
# выпустить корневой сертификат;
|
||||||
|
# 2. aero-ca — сам корневой сертификат (isCA: true). Его приватный
|
||||||
|
# ключ попадает в secret aero-ca-key-pair в namespace cert-manager;
|
||||||
|
# 3. aero-ca-issuer — издатель, который подписывает этим корнем сертификаты
|
||||||
|
# для сервисов кластера (istio-gateway, dashboard и далее).
|
||||||
|
#
|
||||||
|
# Корневой сертификат нужно раздать клиентам (браузеры, curl), иначе они будут
|
||||||
|
# ругаться на недоверенный CA. Выгрузить его можно так:
|
||||||
|
# kubectl -n cert-manager get secret aero-ca-key-pair -o jsonpath='{.data.tls\.crt}' | base64 -d
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: aero-ca
|
||||||
|
# Namespace обязателен и должен совпадать с cert-manager --cluster-resource-namespace
|
||||||
|
# (по умолчанию cert-manager): именно там ClusterIssuer ищет свой секрет.
|
||||||
|
namespace: cert-manager
|
||||||
|
spec:
|
||||||
|
isCA: true
|
||||||
|
commonName: aero-ca
|
||||||
|
secretName: aero-ca-key-pair
|
||||||
|
duration: 87600h # 10 лет — корень контура, ротация вручную
|
||||||
|
renewBefore: 720h # 30 суток
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
size: 256
|
||||||
|
issuerRef:
|
||||||
|
name: selfsigned-issuer
|
||||||
|
kind: ClusterIssuer
|
||||||
|
group: cert-manager.io
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: aero-ca-issuer
|
||||||
|
spec:
|
||||||
|
ca:
|
||||||
|
secretName: aero-ca-key-pair
|
||||||
29
infrastructure/cert-manager/aero/kustomization.yaml
Normal file
29
infrastructure/cert-manager/aero/kustomization.yaml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
# Внутренний CA вместо ACME: контур закрытый, до Let's Encrypt не достучаться.
|
||||||
|
- clusterissuer-ca.yaml
|
||||||
|
|
||||||
|
# ACME-издатели из base выключены удалением, а не форком base: так overlay
|
||||||
|
# остаётся патчем и не расходится с остальными кластерами при обновлении base.
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
kind: ClusterIssuer
|
||||||
|
name: letsencrypt-issuer
|
||||||
|
patch: |
|
||||||
|
$patch: delete
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-issuer
|
||||||
|
- target:
|
||||||
|
kind: ClusterIssuer
|
||||||
|
name: letsencrypt-issuer-istio
|
||||||
|
patch: |
|
||||||
|
$patch: delete
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-issuer-istio
|
||||||
5
infrastructure/dashboard/aero/kustomization.yaml
Normal file
5
infrastructure/dashboard/aero/kustomization.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
5
infrastructure/istio-base/aero/kustomization.yaml
Normal file
5
infrastructure/istio-base/aero/kustomization.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
10
infrastructure/istio-config/aero/kustomization.yaml
Normal file
10
infrastructure/istio-config/aero/kustomization.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
patches:
|
||||||
|
- path: istio-config.yaml
|
||||||
|
target:
|
||||||
|
kind: HelmRelease
|
||||||
|
name: istio-config
|
||||||
5
infrastructure/istio-gateway/aero/kustomization.yaml
Normal file
5
infrastructure/istio-gateway/aero/kustomization.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
5
infrastructure/istio-pilot/aero/kustomization.yaml
Normal file
5
infrastructure/istio-pilot/aero/kustomization.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
Loading…
Reference in New Issue
Block a user