9

For now, I deploy my application pods using static files and one of them is app-secrets.yaml with all secrets to deploy an application

---
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  root: xxxxxx
  user1: xxxxxx
  user2: xxxxxx

but this is not neither secure nor convenient (if I need another app instance, I have to create another file with human-generated password).

I'm looking to generate random passwords at application creation but I don't know if it's possible. I've already looked to the topic secret and especially secretGenerator but this is not directly what I want as I understand it, because it does not create a random string but a random secret name like secret/app-secrets-ssdsdfmfh4k but I have to provide still the passwords.

Baptiste Mille-Mathias
  • 2,144
  • 4
  • 31
  • 37

5 Answers5

5

You may want to use kubernetes-secret-generator. I've tested it and it's doing exactly what you need.

To accomplish it you have to have helm in your cluster and follow these instructions:

Clone repository

$ git clone https://github.com/mittwald/kubernetes-secret-generator

Create helm deployment

$ helm upgrade --install secret-generator ./deploy/chart

Now you to use it, you just have to

Add annotation secret-generator.v1.mittwald.de/autogenerate to any Kubernetes secret object .The value of the annotation can be a field name (or comma separated list of field names) within the secret; the SecretGeneratorController will pick up this annotation and add a field [or fields] (password in the example below) to the secret with a randomly generated string value. From here.

$ kubectl apply -f mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  annotations:
    secret-generator.v1.mittwald.de/autogenerate: password
data:
  username: UGxlYXNlQWNjZXB0Cg==

After applying this secret you can take a look at it to check if the passward was generated as expected:

$ kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
  password: dnVKTDBJZ0tFS1BacmtTMnBuc3d2YWs2YlZsZ0xPTUFKdStDa3dwUQ==
  username: UGxlYXNlQWNjZXB0Cg==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"username":"UGxlYXNlQWNjZXB0Cg=="},"kind":"Secret","metadata":{"annotations":{"secret-generator.v1.mittwald.de/autogenerate":"password"},"name":"mysecret","namespace":"default"}}
    secret-generator.v1.mittwald.de/autogenerate: password
    secret-generator.v1.mittwald.de/autogenerate-generated-at: 2020-01-09 14:29:44.397648062
      +0000 UTC m=+664.011602557
    secret-generator.v1.mittwald.de/secure: "yes"
  creationTimestamp: "2020-01-09T14:29:44Z"
  name: mysecret
  namespace: default
  resourceVersion: "297425"
  selfLink: /api/v1/namespaces/default/secrets/mysecret
  uid: 7ae42d71-32ec-11ea-92b3-42010a800009
type: Opaque

As we can see, the password was generated.

ant31
  • 4,471
  • 4
  • 15
  • 20
Mark Watney
  • 5,268
  • 2
  • 11
  • 33
  • 2
    exactly what I was looking for, unfortunate that k8s does not provide that by default and that this project uses helm for deployment. – Baptiste Mille-Mathias Jan 14 '20 at 09:31
  • 1
    Passwords are not encrypted ! they are only encoded. Everyone can read the password you posted. I want to make sure there is no misconception about base64 encoding vs encryption, as it could give a false sense of security. The secret you posted contains: username: PleaseAccept password: vuJL0IgKEKPZrkS2pnswvak6bVlgLOMAJu+CkwpQ – ant31 Mar 24 '23 at 09:25
3

You can do this too:

$ head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8 ; echo '' | base64 | kubectl create secret generic mysecret --from-literal=password=-

The inconvenient is that you need to change secret name every time you run the command, but looks like you already have a mechanism to generate random secret names.

Note: change the number in head -c 8 to control the length of the string.

suren
  • 7,817
  • 1
  • 30
  • 51
  • 1
    The example above doesn't work, so I give the working one: `head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8 | xargs -I {} kubectl create secret generic mysecret --from-literal=password={}` – red Jul 05 '21 at 16:21
  • @red First of all, I just tried with k8s 1.20, and it DID work. and you should expect some posts to get outdated after a year and half. – suren Jul 07 '21 at 08:15
2

To piggy back @suren's answer this is how it should be done today

If you want to dry run,

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8 | kubectl create secret generic xxx --dry-run=client --from-file=password=/dev/stdin -o json

To create the secret and decode,

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8 | kubectl create secret generic xxx --from-file=password=/dev/stdin

kubectl get secret xxx -o jsonpath='{.data.password}' | base64 -d
nixgadget
  • 6,983
  • 16
  • 70
  • 103
2

That's how we do it my team:

{{ randAlphaNum 30 | b64enc | quote }}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
1

Kubernetes natively does not have this functionality.

If you want to perform this yourself manually check out this question

If you want to automate this manual task then you can use this custom controller to perform this.

Add the annotation secret-generator.v1.mittwald.de/autogenerate to any Kubernetes secret object. The value of the annotation can be a field name (or comma separated list of field names) within the secret; the SecretGeneratorController will pick up this annotation and add a field [or fields] (password in the example below) to the secret with a randomly generated string value

Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107