feat(security): External Secrets Operator + ClusterSecretStore на Vault #8
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
metadata:
|
||||||
|
name: vault
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
vault:
|
||||||
|
# Внутрикластерный адрес, а не https://vault.<домен>: Vault слушает без TLS
|
||||||
|
# (tls_disable), а поход через шлюз потребовал бы ещё и доверия к internal-ca
|
||||||
|
# внутри ESO. Снаружи UI остаётся на https через envoy.
|
||||||
|
server: http://vault.security.svc:8200
|
||||||
|
path: kv
|
||||||
|
version: v2
|
||||||
|
auth:
|
||||||
|
kubernetes:
|
||||||
|
mountPath: kubernetes
|
||||||
|
role: eso
|
||||||
|
# Service account оператора: имя и namespace должны совпадать с
|
||||||
|
# bound_service_account_names/namespaces роли eso в Vault.
|
||||||
|
serviceAccountRef:
|
||||||
|
name: external-secrets
|
||||||
|
namespace: security
|
||||||
|
# Vault 1.21+ требует audience в роли, ESO по умолчанию просит "vault".
|
||||||
|
audiences:
|
||||||
|
- vault
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
# Проверочный ExternalSecret: доказывает всю цепочку ESO -> kubernetes-auth ->
|
||||||
|
# Vault -> Secret в кластере. Значение кладётся в Vault командой
|
||||||
|
# vault kv put kv/demo username=demo password=s3cr3t
|
||||||
|
# (key в ExternalSecret указывается без префикса path: demo -> kv/data/demo).
|
||||||
|
# Когда появятся настоящие потребители (токен вебхука Flux и приложения),
|
||||||
|
# этот объект можно удалить.
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: vault-smoke
|
||||||
|
namespace: security
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: vault
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: vault-smoke
|
||||||
|
creationPolicy: Owner
|
||||||
|
deletionPolicy: Retain
|
||||||
|
data:
|
||||||
|
- secretKey: username
|
||||||
|
remoteRef:
|
||||||
|
key: demo
|
||||||
|
property: username
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: demo
|
||||||
|
property: password
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||||
|
kind: HelmRelease
|
||||||
|
metadata:
|
||||||
|
name: external-secrets
|
||||||
|
spec:
|
||||||
|
interval: 1h
|
||||||
|
chartRef:
|
||||||
|
kind: OCIRepository
|
||||||
|
name: external-secrets
|
||||||
|
install:
|
||||||
|
crds: CreateReplace
|
||||||
|
upgrade:
|
||||||
|
crds: CreateReplace
|
||||||
|
cleanupOnFail: true
|
||||||
|
remediation:
|
||||||
|
retries: 3
|
||||||
|
# Оператор без состояния: переустановка с нуля безопасна, поэтому при
|
||||||
|
# падении апгрейда релиз снимается и ставится заново, а не залипает.
|
||||||
|
strategy: uninstall
|
||||||
|
values:
|
||||||
|
replicaCount: 1
|
||||||
|
# CRD ставит и обновляет сам чарт.
|
||||||
|
installCRDs: true
|
||||||
|
# Валидирующий вебхук и его certController включены: сертификаты чарт
|
||||||
|
# выпускает и продлевает сам, cert-manager для этого не нужен.
|
||||||
|
webhook:
|
||||||
|
create: true
|
||||||
|
certController:
|
||||||
|
create: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ./ocirepository.yaml
|
||||||
|
- ./helmrelease.yaml
|
||||||
|
- ./clustersecretstore.yaml
|
||||||
|
- ./externalsecret.yaml
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
apiVersion: source.toolkit.fluxcd.io/v1
|
||||||
|
kind: OCIRepository
|
||||||
|
metadata:
|
||||||
|
name: external-secrets
|
||||||
|
spec:
|
||||||
|
interval: 15m
|
||||||
|
layerSelector:
|
||||||
|
mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip
|
||||||
|
operation: copy
|
||||||
|
ref:
|
||||||
|
# Версия чарта external-secrets (равна appVersion). Релизы чарта тегируются
|
||||||
|
# как helm-chart-<version>, в ghcr публикуется тег без префикса.
|
||||||
|
tag: 2.10.0
|
||||||
|
url: oci://ghcr.io/external-secrets/charts/external-secrets
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: external-secrets
|
||||||
|
spec:
|
||||||
|
interval: 1h
|
||||||
|
path: ./kubernetes/apps/security/external-secrets/app
|
||||||
|
prune: true
|
||||||
|
sourceRef:
|
||||||
|
kind: GitRepository
|
||||||
|
name: flux-system
|
||||||
|
namespace: flux-system
|
||||||
|
targetNamespace: security
|
||||||
|
wait: true
|
||||||
|
healthChecks:
|
||||||
|
- apiVersion: helm.toolkit.fluxcd.io/v2
|
||||||
|
kind: HelmRelease
|
||||||
|
name: external-secrets
|
||||||
|
namespace: security
|
||||||
|
# Оператор ходит в Vault через kubernetes-auth, поэтому ждём готовности Vault.
|
||||||
|
# Обе Kustomization живут в ns security — dependsOn работает только внутри
|
||||||
|
# своего namespace, и здесь это выполняется.
|
||||||
|
dependsOn:
|
||||||
|
- name: vault
|
||||||
@@ -8,4 +8,5 @@ components:
|
|||||||
|
|
||||||
resources:
|
resources:
|
||||||
- ./namespace.yaml
|
- ./namespace.yaml
|
||||||
|
- ./external-secrets/ks.yaml
|
||||||
- ./vault/ks.yaml
|
- ./vault/ks.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user