As we know Secrets are used to store sensitive data like password, keys, certificates and token In Secrets these values are encoded by base64. But the actual problem is these encoded values can be easily decoded, which means if hacker or normal guy get access to your Secrets then can easily get access to your sensitive data like passwords, token, etc. To know more
Concept of private-public
keys. The Secret(or any data) will be encrypted
using Public keys and those encrypted values can only be decrypted using
private key only. So, neither hacker(or normal guy) is having those prvate keys.
Therefore, it can't be decoded. So, it is safely secured.
Sealed Secrets is a solution to encrypt your Kubernetes Secret into a SealedSecret,
which is safe to store – even to a public repository.
The SealedSecret can be decrypted only by the controller running in
the target cluster and nobody else.
Sealed secrets are build on the top of kubernetes secrets where the
data is encrypted using the cluster controllers public key
, so it can
only be read by the controller. Because the target cluster controller
keeps the private key
with itself. So no one else other than target
cluster controller could have access to Secrets sesitive data.
To know more, refer
You can turn any kubernetes secret into a sealed secret, so it doesnt matter how the normal secret was created, but here are some examples of how to create a secret.
note: use of --dry-run
- this is just a local file!
# create a generic secret foo=bar by using the STDIN
echo -n bar | kubectl create secret generic mysecret -n target-namespace-in-k8s --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json
# create a generic secret username=mydevuser passed as the literal value
kubectl create secret generic mysecret -n target-namespace-in-k8s --dry-run=client --from-literal=username=mydevuser -o json >mysecret.json
# create a tls secret with specified tls.key and tls.crt files
kubectl create secret tls mysecret -n target-namespace-in-k8s --dry-run=client --key="tls.key" --cert="tls.crt" -o json >mysecret.json
# create a generic secret from a files contents (gets encoded as base64 and can be made available as file inside pod).
kubectl create secret generic alertmanagerconfig -n target-namespace --from-file=./alertmanager.yml --dry-run=client -o json >mysecret.json
# Create a dockerlogin secret which can be used f.ex. as image pullsecret
kubectl create secret --namespace system --dry-run=client docker-registry myDockerSecret --docker-server=<registry-url> --docker-username=xxx --docker-password=xxx -o json > mysecret.json
Using kubeseal, the secret can then be converted to a sealed secret.
# for using local public cert
kubeseal --cert secret-certificate.pem <mysecret.json >mysealedsecret.json
#for pulling public cert from service in cluster
kubeseal --controller-namespace system --controller-name sealed-secrets < mysecret.json > mysealedsecret.json
mysecret.json is your target secret file, which will generated to sealedsecret one (can be yaml format too)
sealedsecret.json is a new generated sealedsecret file (name can be changed also)
This can then be imported manually using kubectl apply for confirming.
You can use this f.ex to create sealed secrets for adding repos to ArgoCD.
(If you are using a token, the scope has to include full repo privilges, and the UN can be any non-empty string):
kubectl create secret generic sample-git --namespace argocd --dry-run=client --from-literal=type='git' --from-literal=name='sample-git' --from-literal=url=https://gitlab.com/Obmondo/myreponame.git --from-literal=username='gitlab+deploy-token-20' --from-literal=password='lolpassword' --output yaml | yq eval '.metadata.labels.["argocd.argoproj.io/secret-type"]="repository"' - | yq eval '.metadata.annotations.["sealedsecrets.bitnami.com/managed"]="true"' - | yq eval '.metadata.annotations.["managed-by"]="argocd.argoproj.io"' - | kubeseal --controller-namespace system --controller-name sealed-secrets --format yaml - > argocdrepo-myreponame.yaml
Look in argocd -> applications -> secrets
and verify it shows your unsealed secret as well as the sealed one.. if the
unsealed one is not showing it is most likely because secret already exists in an unmanaged version, in which case you
must add an annotation to the existing secret:
sealedsecrets.bitnami.com/managed: "true"
and then restart sealed-secrets pod in kube-system to make it do its job (it has already given up at this point).
Sealed secrets have an interesting feature which can use config files where only a part of the file needs to be encrypted. To use templates in sealed secrets, create a sealed secret yaml using the examples provided above, with palceholder values for data to be sealed, and add the template part as given in the example below:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: example
spec:
encryptedData:
password: AgC2==
access-token: AgDE==
template:
data:
kubeaid-pushupdate.yaml: |
repo-url: https://gitlab.com/example/repo.git
username: smart_user
password: "{{ index . "password" }}"
repo-token: "{{ index . "access-token" }}"
metadata:
creationTimestamp: null
namespace: test
The encryptedData
field can store some random data for the start. All the referenced
fields in the data
section, need to be present in the encryptedData
before you attempt to seal the secret.
Then seal and merge the secret using the below command:
kubectl create secret generic example\
--dry-run=client \
--namespace test \
--from-literal=password="super_secret_pass" \
--from-literal=access-token="0123abcDEF" -o yaml | \
kubeseal \
--controller-namespace system \
--controller-name sealed-secrets \
--namespace test -o yaml \
--merge-into sealedSecret.yaml
The --merge-into
option only changes the encrypted data without changing the whole SealedSecret.
Original Example
We are basically backing up all the tls.crt & tls.key files of the cluster locally, so we can restore them later.
# This would get all the tls secrets in the cluster from all the name spaces.
kubectl get secrets -n system -l sealedsecrets.bitnami.com/sealed-secrets-key=active -o yaml > backup_key.yml
This would backup the tls.crt
& tls.key
in a yaml file locally.
For restoring the secrets, in a cluster use .
# This would restore the tls secrets in the cluster from the backup file.
kubectl apply -f backup_key.yml
Run the commands from the velero pod in the cluster .
We are backing up the system namespace which contains the sealed secrets if there is no shedule backup already present. If there is sheduled backup already present skip this command.
# This would create backup of the sealesecret pod in system namespace.
velero backup create <backup-name> --include-namespaces system --include-resources pods --selector sealedsecrets.bitnami.com/sealed-secrets-key=active
Assuming we already have scheduled backup . Check the backup status using the following command.
velero get backups
Restore the backup with the name that is created/exists.
velero restore create <restore-name> --include-namespaces system --include-resources pods --selector sealedsecrets.bitnami.com/sealed-secrets-key=active --from-backup <backup-name>
Create the s3 bucket
aws s3api create-bucket --bucket kbm-sealed-secrets-backups --region eu-west-1 --endpoint-url=https://s3.obmondo.com