
Werken met secrets in Kubernetes is altijd een uitdaging, maar in GitOps workflows wordt dit nog complexer. GitOps methodologieën zoals FluxCD vereisen dat alles version-controlled is en declaratief gedefinieerd wordt - maar hoe beheer je dan secrets zonder ze in plain text in Git te committen?
Over het algemeen heb je een paar opties:
kubeseal. Niet ideaal voor dynamische of gegenereerde secrets. Elke wijziging betekent handmatige re-encryptie.De meeste van deze alternatieven vereisen significant handmatig werk: per-secret encryptie, key management setup, of complexe configuratie. Voor dynamische secrets die regelmatig gegenereerd moeten worden, wordt dit snel onpraktisch.
Voor veel teams is er behoefte aan iets daartussenin: een oplossing die GitOps-friendly is, automatisch secrets kan genereren, en niet de volledige complexiteit van een enterprise secret management systeem vereist.
De Kube Secrets Operator is een Kubernetes operator die we ontwikkeld hebben om precies dit probleem op te lossen. Het is ontworpen voor GitOps workflows zoals FluxCD en biedt een manier om secrets te genereren en beheren via Kubernetes custom resources.
De operator zit precies in het sweet spot tussen handmatige encryptie en enterprise secret management:
Dit maakt het uitstekend geschikt voor testing omgevingen, CI/CD pipelines en tijdelijke setups waar je niet meteen een volledig KMS systeem wilt opzetten.
Het meest simpele use case: een secret met een automatisch gegenereerd password.
apiVersion: apps.k8s.containerinfra.com/v1
kind: GeneratedSecret
metadata:
name: basic-password
namespace: default
spec:
secretType: Opaque
deletionPolicy: Delete
metadata:
name: basic-app-secret
namespaces:
- default
labels:
app: my-app
template:
data:
password:
generated:
length: 16
maxDigits: 4
maxSymbols: 2
noUpperCaseValues: false
noRepeatedValues: true
username:
value: admin
De operator genereert automatisch een secure password en combineert dit met statische values zoals de username. Perfect voor applicaties waar je een database connection nodig hebt maar niet handmatig passwords wilt beheren.
Je kan het gegenereerde secret dan gebruiken bij initial boot van de database, waarbij de user & password gezet worden, en vervolgens door de applicatie om hier mee te verbinden.
Het meest interessante voorbeeld: secrets die referenties maken naar andere secrets via templates.
apiVersion: apps.k8s.containerinfra.com/v1
kind: GeneratedSecret
metadata:
name: generated-config
namespace: default
spec:
secretType: Opaque
metadata:
name: generated-config
namespaces:
- default
template:
data:
connection_string:
templated:
template: |
test: {{.Ref.api_endpoint}}/{{.Ref.api_version}}/{{.Ref.environment}}
inputSecretRef:
name: app-config
namespace: default
Dit laat zien hoe de operator complexere use cases kan oplossen: je kunt secrets genereren die dynamisch refereren naar andere secrets. Handig voor connection strings, URLs of andere samengestelde configuraties.
Veel 3rd party applicaties hebben config files nodig waarin één of meerdere secrets staan. Denk aan object storage access keys/secrets, database passwords, API keys, etc. Dit is een perfecte use case voor de operator omdat je een config file kunt genereren die meerdere secrets combineert.
apiVersion: apps.k8s.containerinfra.com/v1
kind: GeneratedSecret
metadata:
name: application-config
namespace: default
spec:
secretType: Opaque
metadata:
name: app-config-file
namespaces:
- default
template:
data:
config.yaml:
templated:
template: |
storage:
endpoint: https://storage.example.com
access_key: {{.Ref.storage_access_key}}
secret_key: {{.Ref.storage_secret_key}}
database:
host: {{.Ref.db_host}}
port: {{.Ref.db_port}}
username: {{.Ref.db_username}}
password: {{.Ref.db_password}}
api:
key: {{.Ref.api_key}}
inputSecretRef:
name: app-secrets
namespace: default
In dit voorbeeld wordt een config.yaml file gegenereerd die meerdere secrets combineert: object storage credentials, database connection details en een API key. De 3rd party applicatie kan deze config file als volume mount gebruiken, zonder dat je handmatig config files hoeft te genereren of te encrypten.
Dit is vooral waardevol omdat:
Zonder de operator zou je dit handmatig moeten doen: secrets encrypten met SealedSecrets of SOPS, en dan config files genereren die de secrets bevatten - wat snel onpraktisch wordt bij regelmatige wijzigingen.
De operator is volledig GitOps-native en deploy je via FluxCD met HelmReleases:
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: kube-secrets-operator
namespace: kube-system
spec:
interval: 160m
url: oci://ghcr.io/containerinfra/charts/kube-secrets-operator
ref:
semver: ">= 0.0.0"
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kube-secrets-operator
namespace: kube-system
spec:
chartRef:
kind: OCIRepository
name: kube-secrets-operator
namespace: kube-system
interval: 1h
install:
crds: Skip
values:
replicaCount: 1
De operator is niet bedoeld als vervanging voor enterprise secret management in productie omgevingen waar je zeer hoge security eisen hebt. In plaats daarvan is het ideaal voor:
De Kube Secrets Operator is volledig open source en beschikbaar op GitHub. We moedigen feedback en contributions aan van de community.