Установка ExternalSecret Operator + LockBox
ExternalSecret позволяет использовать внешнюю, по отношению к кластеру Kubernetes, секретницу. В YC этой секретницей является Lockbox.
Предполагаю, что SA есть и IAM ключ для него уже сгенерирован. Если нет, то можно воспользоваться инструкцией: https://teletype.in/@cameda/w93lPMPQWS4
На всякий случай. Генерацию IAM ключа для SA можно выполнить так:
yc iam key create --service-account-id $SA --output key.json
Создаётся файл key.json, который можно использовать в дальнейшем.
KMS ключ сгенерировал здесь: https://teletype.in/@cameda/vBIMDOZi7vV
Lockbox был создан по этому мануалу: https://teletype.in/@cameda/M1Rm88sCB7t
Установим ExternalSecret Operator с помощью Helm.
export HELM_EXPERIMENTAL_OCI=1 && \ helm pull oci://cr.yandex/yc-marketplace/yandex-cloud/external-secrets/chart/external-secrets \ --version 0.5.5 \ --untar && \ helm install \ --namespace external-secret \ --create-namespace \ --set-file auth.json=key.json \ external-secrets ./external-secrets/
helm list -n external-secret NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION external-secrets external-secret 1 2023-08-15 14:04:37.243386 +0300 MSK deployed external-secrets-0.5.5 v0.5.5
Создаём секрет на основе файла key.json.
kubectl create secret generic yc-auth --from-file=authorized-key=key.json
# Проверяем, что содержимое соответствует файлу. kubectl get secret yc-auth --output=json | jq --raw-output ".data[]" | base64 -d
Создаём SecretStore на основе секрета.
kubectl apply -f - <<< ' apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: secret-store spec: provider: yandexlockbox: auth: authorizedKeySecretRef: name: yc-auth key: authorized-key'
kubectl get ss NAME AGE STATUS secret-store 4s Valid
SecretStore в статусе Valid. Значит создалось нормально.
kubectl apply -f - <<< ' apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: external-secret spec: refreshInterval: 1h secretStoreRef: name: secret-store kind: SecretStore target: name: k8s-secret data: - secretKey: ssh remoteRef: key: e6qad2p5dog8d6e07mol property: ssh'
где secret-store - имя созданного SecretStore для обеспечения доступа к Lockbox,
k8s-secret - имя создаваемого секрета,
e6qa5j84t1gaq1fc1lgr - идентификатор секрета в Lockbox,
ssh - ключ секрета.
kubectl get es NAME STORE REFRESH INTERVAL STATUS external-secret secret-store 1h SecretSynced
# Проверяем, что содержимое ключа отдаётся верно. kubectl get secret k8s-secret --output=json | jq --raw-output ".data.ssh" | base64 -d
ExternalSecret Operator создаёт несколько сущностей.
kubectl api-resources clusterexternalsecrets ces external-secrets.io/v1beta1 false ClusterExternalSecret clustersecretstores css external-secrets.io/v1beta1 false ClusterSecretStore externalsecrets es external-secrets.io/v1beta1 true ExternalSecret secretstores ss external-secrets.io/v1beta1 true SecretStore
kubectl get po -n external-secret NAME READY STATUS RESTARTS AGE external-secrets-5b6fbc88f9-286m6 1/1 Running 0 13m external-secrets-cert-controller-7b7d4c9bcd-7gnq4 1/1 Running 0 13m external-secrets-webhook-7446c9896-br9ql 1/1 Running 0 13m
kubectl get deploy -n external-secret NAME READY UP-TO-DATE AVAILABLE AGE external-secrets 1/1 1 1 31m external-secrets-cert-controller 1/1 1 1 31m external-secrets-webhook 1/1 1 1 31m
kubectl get svc -n external-secret NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-secrets-webhook ClusterIP 10.75.239.144 <none> 443/TCP 17m
kubectl get crd NAME CREATED AT clusterexternalsecrets.external-secrets.io 2023-08-16T09:50:37Z clustersecretstores.external-secrets.io 2023-08-16T09:50:37Z externalsecrets.external-secrets.io 2023-08-16T09:50:37Z secretstores.external-secrets.io 2023-08-16T09:50:37Z
kubectl get validatingwebhookconfigurations NAME WEBHOOKS AGE externalsecret-validate 1 19m secretstore-validate 2 19m
kubectl get secret -n external-secret NAME TYPE DATA AGE external-secrets-webhook Opaque 4 22m sa-creds Opaque 1 22m sh.helm.release.v1.external-secrets.v1 helm.sh/release.v1 1 22m
kubectl get cm -n external-secret NAME DATA AGE kube-root-ca.crt 1 22m
kubectl get sa -n external-secret NAME SECRETS AGE default 0 23m external-secrets 0 23m external-secrets-cert-controller 0 23m external-secrets-webhook 0 23m
kubectl get role -n external-secret NAME CREATED AT external-secrets-leaderelection 2023-08-16T09:50:37Z kubectl describe role external-secrets-leaderelection -n external-secret Name: external-secrets-leaderelection Labels: app.kubernetes.io/instance=external-secrets app.kubernetes.io/managed-by=Helm app.kubernetes.io/name=external-secrets app.kubernetes.io/version=v0.5.5 helm.sh/chart=external-secrets-0.5.5 Annotations: meta.helm.sh/release-name: external-secrets meta.helm.sh/release-namespace: external-secret PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- configmaps [] [] [create] leases.coordination.k8s.io [] [] [get create update patch] configmaps [] [external-secrets-controller] [get update patch]
Установка из родного репозитория.
helm repo add external-secrets https://charts.external-secrets.io helm install external-secrets \ external-secrets/external-secrets \ -n external-secrets \ --create-namespace
После этого создаём SecretStore и ExternalSecret.
Они успешно создаются.
kubectl get ss NAME AGE STATUS CAPABILITIES READY secret-store 22s Valid ReadOnly True kubectl get es NAME STORE REFRESH INTERVAL STATUS READY external-secret secret-store 1h SecretSynced True
Полезные ссылки.
https://external-secrets.io/latest/provider/yandex-lockbox/
Установка из стандартного helm:
https://external-secrets.io/latest/introduction/getting-started/
Использование совместно с LockBox:
https://external-secrets.io/latest/provider/yandex-lockbox/
Использование совместно с Certificate Manager:
https://external-secrets.io/latest/provider/yandex-certificate-manager/
Пример использования совместно с FluxCD:
https://external-secrets.io/latest/examples/gitops-using-fluxcd/