diff --git a/kubernetes/apps/security/kustomization.yaml b/kubernetes/apps/security/kustomization.yaml new file mode 100644 index 0000000..0942720 --- /dev/null +++ b/kubernetes/apps/security/kustomization.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: security + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./vault/ks.yaml diff --git a/kubernetes/apps/security/namespace.yaml b/kubernetes/apps/security/namespace.yaml new file mode 100644 index 0000000..1d48e62 --- /dev/null +++ b/kubernetes/apps/security/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: security + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/security/vault/app/gitrepository.yaml b/kubernetes/apps/security/vault/app/gitrepository.yaml new file mode 100644 index 0000000..a787cdb --- /dev/null +++ b/kubernetes/apps/security/vault/app/gitrepository.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: vault-helm +spec: + interval: 12h + # Чарт берём прямо из git, а не из https://helm.releases.hashicorp.com: + # этот Helm-репозиторий отдаётся через CloudFront, который блокирует + # российские адреса (403 Forbidden), и HelmRelease не может получить index.yaml. + url: https://github.com/hashicorp/vault-helm + ref: + # hashicorp/vault-helm: Chart.yaml version 0.34.1 (appVersion Vault 2.0.4), + # чарт лежит в корне репозитория. + tag: v0.34.1 diff --git a/kubernetes/apps/security/vault/app/helmrelease.yaml b/kubernetes/apps/security/vault/app/helmrelease.yaml new file mode 100644 index 0000000..a70dbb9 --- /dev/null +++ b/kubernetes/apps/security/vault/app/helmrelease.yaml @@ -0,0 +1,70 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: vault +spec: + interval: 1h + chart: + spec: + chart: . + version: 0.34.1 + sourceRef: + kind: GitRepository + name: vault-helm + install: + crds: CreateReplace + upgrade: + crds: CreateReplace + cleanupOnFail: true + remediation: + retries: 3 + # Упавший первый релиз без этой настройки залипает: Flux пытается + # откатиться, предыдущей ревизии нет и HelmRelease навсегда остаётся False. + strategy: uninstall + values: + global: + enabled: true + tlsDisable: true + # authDelegator включает auth-метод kubernetes (service account -> токен Vault): + # через него External Secrets Operator будет читать секреты без хранения + # пароля/токена Vault в sops. + authDelegator: + enabled: true + # Агент-инжектор не используем — секреты раздаёт ESO. + injector: + enabled: false + csi: + enabled: false + server: + # Один под и один PVC на ZFS-зеркале (rpool через StorageClass + # proxmox-local-zfs) с интегрированным raft-хранилищем — single-node Vault. + standalone: + enabled: true + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + } + + storage "raft" { + path = "/vault/data" + } + + service_registration "kubernetes" {} + dataStorage: + enabled: true + size: 5Gi + storageClass: proxmox-local-zfs + accessMode: ReadWriteOnce + service: + enabled: true + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + memory: 1Gi diff --git a/kubernetes/apps/security/vault/app/httproute.yaml b/kubernetes/apps/security/vault/app/httproute.yaml new file mode 100644 index 0000000..8d25274 --- /dev/null +++ b/kubernetes/apps/security/vault/app/httproute.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: vault +spec: + parentRefs: + - name: envoy-internal + namespace: network + # https-листенер шлюза принимает маршруты из любых namespace, а http — только + # из network, поэтому цепляемся именно к https. + sectionName: https + hostnames: + - "vault.${SECRET_DOMAIN}" + rules: + - backendRefs: + - name: vault + port: 8200 diff --git a/kubernetes/apps/security/vault/app/kustomization.yaml b/kubernetes/apps/security/vault/app/kustomization.yaml new file mode 100644 index 0000000..c95c4c2 --- /dev/null +++ b/kubernetes/apps/security/vault/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./gitrepository.yaml + - ./helmrelease.yaml + - ./httproute.yaml diff --git a/kubernetes/apps/security/vault/ks.yaml b/kubernetes/apps/security/vault/ks.yaml new file mode 100644 index 0000000..c7bb6b0 --- /dev/null +++ b/kubernetes/apps/security/vault/ks.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: vault +spec: + interval: 1h + path: ./kubernetes/apps/security/vault/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: security + # wait выключен сознательно: PVC у Vault создаётся дефолтным StorageClass'ом из + # proxmox-csi, а готовность пода Vault наступает только после ручного + # `vault operator init` + unseal (readinessProbe `vault status` возвращает exit 2, + # пока хранилище запечатано). С wait: true Kustomization висела бы красной всё + # это время, хотя чарт установлен корректно. + wait: false