Kubernetes Secrets Operator on Thalassa Cloud Kubernetes
Kubernetes Secrets Operator is a Kubernetes operator developed by ContainerInfra, designed to assist in generating secrets for Kubernetes environments, particularly those driven by GitOps methodologies. By deploying Kubernetes Secrets Operator in your Thalassa Cloud Kubernetes cluster, you can automatically generate and manage secrets without manual intervention, making it ideal for GitOps workflows with tools like FluxCD.
This guide walks you through deploying Kubernetes Secrets Operator using FluxCD, configuring it to generate secrets automatically, and using it in your GitOps workflows.
About the Kubernetes Secrets Operator
Kubernetes Secrets Operator provides a middle ground for teams that consider a full Key Management System (KMS) and Secret Management setup to be overly complicated or expensive. It acts as a solution between SealedSecrets (which requires manual work) and cloud-based KMS services (which add process overhead), such as Vault.
The operator works by watching for GeneratedSecret custom resources in your cluster. When you create a GeneratedSecret resource, the operator automatically generates the specified secrets and creates Kubernetes Secret resources based on your configuration. This makes it well-suited for testing purposes, CI/CD operations, and temporary setups.
The operator supports several secret generation methods:
- Generated values: Automatically generate passwords, tokens, or other random values with configurable requirements
- Static values: Use predefined values for secrets
- Templated values: Create secrets that reference other secrets using templates
For GitOps workflows, you can commit GeneratedSecret resources to your Git repository, and the operator will automatically create the corresponding Kubernetes Secrets when the resources are applied to your cluster.
Prerequisites
Before deploying Kubernetes Secrets Operator, ensure you have a few things in place.
First, you need a running Kubernetes cluster in Thalassa Cloud. If you’re new to Thalassa Cloud Kubernetes, see the Getting Started guide for cluster creation and basic setup.
You’ll also need cluster access configured using
kubectl. Usetcloud kubernetes connectto configure access, or set up kubeconfig manually. You’ll need cluster administrator permissions to install the operator and create custom resources.FluxCD must be installed in your cluster. If you haven’t installed it yet, follow the Installing FluxCD guide to set it up. This guide assumes you have FluxCD installed and configured with access to a Git repository where you’ll store your configuration.
Finally, ensure your cluster has sufficient resources. The operator is lightweight, but it needs CPU and memory to run. Most clusters have adequate resources, but verify your nodes have capacity for additional workloads.
Installing Kubernetes Secrets Operator
The recommended way to install Kubernetes Secrets Operator is using FluxCD with Helm charts. The operator consists of two components: CRDs (Custom Resource Definitions) and the operator itself.
Step 1: Install CRDs
First, create an OCIRepository resource for the CRDs:
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: kube-secrets-operator-crds
namespace: kube-system
spec:
interval: 160m
url: oci://ghcr.io/containerinfra/charts/kube-secrets-operator-crds
ref:
semver: ">= 0.0.0"Apply the OCIRepository:
kubectl apply -f oci-repository-crds.yamlOr commit it to your Git repository if you’re using FluxCD with Git.
Create a HelmRelease for the CRDs:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kube-secrets-operator-crds
namespace: kube-system
spec:
chartRef:
kind: OCIRepository
name: kube-secrets-operator-crds
namespace: kube-system
interval: 1h
values: {}Apply the HelmRelease:
kubectl apply -f helm-release-crds.yamlWait for the CRDs to be installed:
kubectl get crd | grep generatedsecretYou should see the generatedsecrets.apps.k8s.containerinfra.com CRD.
Step 2: Install the Operator
Create an OCIRepository resource for the operator:
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"Apply the OCIRepository:
kubectl apply -f oci-repository-operator.yamlCreate a HelmRelease for the operator:
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:
enableServiceMonitor: false
replicaCount: 1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
nodeSelector:
kubernetes.io/os: linux
tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoScheduleThe install.crds: Skip setting tells Helm to skip installing CRDs since we installed them separately in Step 1.
Apply the HelmRelease:
kubectl apply -f helm-release-operator.yamlStep 3: Verify Installation
Verify that the operator is running:
kubectl get pods -n kube-system | grep kube-secrets-operatorYou should see the operator pod running. Check the logs if needed:
kubectl logs -n kube-system -l app.kubernetes.io/name=kube-secrets-operatorVerify that the CRD is available:
kubectl get crd generatedsecrets.apps.k8s.containerinfra.comGenerating Secrets
Once the operator is installed, you can create GeneratedSecret resources to automatically generate Kubernetes Secrets. The operator supports several types of secret generation.
Example 1: Simple Generated Password
Create a GeneratedSecret that automatically generates a 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: adminThis example creates a secret named basic-app-secret in the default namespace with:
- A generated password (16 characters, with up to 4 digits and 2 symbols)
- A static username value of “admin”
Apply the resource:
kubectl apply -f basic-password.yamlThe operator will automatically create the Kubernetes Secret. Verify it was created:
kubectl get secret basic-app-secret -n defaultView the secret (the password will be base64 encoded):
kubectl get secret basic-app-secret -n default -o yamlPassword Generation Options
The generated section supports various options:
length: Total length of the generated passwordmaxDigits: Maximum number of digitsmaxSymbols: Maximum number of symbolsnoUpperCaseValues: Set totrueto exclude uppercase lettersnoRepeatedValues: Set totrueto prevent repeated characters
Example 2: Static Values Only
Create a GeneratedSecret with only static values:
apiVersion: apps.k8s.containerinfra.com/v1
kind: GeneratedSecret
metadata:
name: static-config
namespace: default
spec:
secretType: Opaque
metadata:
name: app-config
namespaces:
- default
template:
data:
api_endpoint:
value: https://api.example.com
api_version:
value: v1
environment:
value: productionThis creates a secret with static configuration values. While you could create this secret manually, using GeneratedSecret allows you to manage it declaratively in GitOps workflows.
Apply the resource:
kubectl apply -f static-config.yamlVerify the secret was created:
kubectl get secret app-config -n defaultExample 3: Templated Secrets
Create a GeneratedSecret that uses templates to reference other secrets:
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: defaultThis example creates a secret that references values from the app-config secret created in Example 2. The template uses Go template syntax to construct a connection string from the referenced secret values.
Template Syntax
Templates use Go template syntax. Use {{.Ref.key_name}} to reference values from the input secret. The referenced secret must exist before the templated secret can be created.
Apply the resource:
kubectl apply -f generated-config.yamlVerify the secret was created:
kubectl get secret generated-config -n defaultUsing Secrets in Applications
Once secrets are generated, you can use them in your applications just like any other Kubernetes Secret. Reference them in your Deployments, StatefulSets, or other resources:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
env:
- name: PASSWORD
valueFrom:
secretKeyRef:
name: basic-app-secret
key: password
- name: USERNAME
valueFrom:
secretKeyRef:
name: basic-app-secret
key: usernameOr mount them as volumes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
volumes:
- name: config
secret:
secretName: app-configManaging Secrets in GitOps
For GitOps workflows, commit your GeneratedSecret resources to your Git repository. FluxCD will automatically apply them to your cluster, and the operator will generate the corresponding secrets. This provides several benefits: all secret configurations are version-controlled in Git, changes are auditable through Git history, secrets are automatically generated when resources are applied, and you maintain consistent secret configurations across environments.
Secret Values in Git
The GeneratedSecret resources contain secret generation instructions, not the actual secret values. The generated secret values are stored only in Kubernetes Secrets, not in Git. This makes it safe to commit GeneratedSecret resources to Git.
Best Practices
Following best practices helps you use Kubernetes Secrets Operator effectively and maintain secure secret management.
- Use namespaces to organize secrets and control access.
- Add labels under
metadata.labelsto help identify and manage secrets. - Use templated secrets to combine or reference multiple secret values.
- Keep GeneratedSecret resources in Git for tracking changes, but never commit the actual secret values.
Summary
Kubernetes Secrets Operator lets you easily generate and manage secrets in Kubernetes without manual steps. Just deploy the operator and create GeneratedSecret resources to have your secrets created automatically. You can use it to generate passwords, set fixed values, or combine values from other secrets with templating, making it useful for both simple and advanced needs.
For more information about Kubernetes Secrets Operator features and advanced configurations, see the official repository.