177

I inherited a Kubernetes/Docker setup, and I accidentally crashed the pod by changing something relating to the DB password.

I am trying to troubleshoot this.

I don't have much Kubernetes or Docker experience, so I'm still learning how to do things.

The value is contained inside the db-user-pass credential I believe, which is an Opaque type secret.

I'm describing it:

kubectl describe secrets/db-user-pass
Name:         db-user-pass
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  16 bytes
username:  13 bytes

but I have no clue how to get any data from this secret. The example on the Kubernetes site seems to assume I'll have a base64 encoded string, but I can't even seem to get that. How do I get the value for this?

Steven Matthews
  • 9,705
  • 45
  • 126
  • 232
  • 14
    Try `kubectl get secret db-user-pass -o yaml`, which will dump it out in YAML form and usually includes the encoded secret values. – David Maze Jul 05 '19 at 21:03
  • 1
    Perfect! Thank you. If you want to write this as an answer I'll accept it. – Steven Matthews Jul 05 '19 at 21:03
  • 49
    `kubectl get secret db-user-pass -o json | jq '.data | map_values(@base64d)'`. This givest the nicest results but needs the [jq](https://stedolan.github.io/jq/) dependency. – marcelosalloum Oct 28 '20 at 14:43
  • for dots in json see this: https://github.com/kubernetes/kubernetes/issues/23386 – Tilo Aug 25 '21 at 18:29
  • kubectl get secrets --namespace=jhalokia my-jalokia-credentials -ojsonpath='{.data.password}' | base64 -d – Sanjeev Nov 21 '22 at 16:26

19 Answers19

217

You can use kubectl get secrets/db-user-pass -o yaml or -o json where you'll see the base64-encoded username and password. You can then copy the value and decode it with something like echo <ENCODED_VALUE> | base64 -D (Mac OS X).

A more compact one-liner for this:

kubectl get secrets/db-user-pass --template={{.data.password}} | base64 -D

and likewise for the username:

kubectl get secrets/db-user-pass --template={{.data.username}} | base64 -D

Note: on GNU/Linux, the base64 flag is -d, not -D.

Amit Kumar Gupta
  • 17,184
  • 7
  • 46
  • 64
  • 29
    according to base64 on centos7 the command is `base64 -d` not -D – TheSteve0 Mar 12 '20 at 19:29
  • 4
    -D is not available for ubuntu 18 as well – cafebabe1991 Jul 28 '20 at 05:28
  • 8
    This answer was posted by someone on a mac OS. `-d` is the appropriate argument for decode in linux. – Derek Lemon Sep 16 '20 at 23:02
  • 15
    This template doesn't work when a key inside a secret contains a dot (e.g. `credentials.json`). The working variant is: `kubectl get secrets/secret-name --template="{{index .data \"credentials.json\" | base64decode}}"`. Also note the usage of Go's `base64decode` instead of OS's `base64` to make it work under any OS. – Ruslan Stelmachenko Dec 05 '20 at 05:36
  • There is no point making this work on any OS, as docker only really works in Linux. I've updated the answer to work with bash and made a note about OS/X and zsh. – Software Engineer May 04 '21 at 15:33
115

I would suggest using this handy command. It utilizes a power of go-templates. It iterates over all values, decodes them, and prints them along with the key. It also handles not set values.

kubectl get secret name-of-secret -o go-template='
{{range $k,$v := .data}}{{printf "%s: " $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{"\n"}}{{end}}'

## In your case it would output
# password: decoded_password
# username: decoded_username

If you don't like go-templates you can use different output formats e.g. yaml or json, but that will output secrets encoded by base64.

blacktide
  • 10,654
  • 8
  • 33
  • 53
Břetislav Hájek
  • 3,056
  • 2
  • 15
  • 17
  • 10
    This is the most robust answer. – Pawel Furmaniak Jan 11 '20 at 12:29
  • 1
    Has anyone figured out the syntax to get this to work in PowerShell? If I put the template in a file, and use `--go-template-file` it works. But `--go-template` behaves differently (gives various errors about unexpected this or that). Even with properly escaping the string (which, frankly, is painful). – BrettJ Apr 19 '20 at 16:34
  • 1
    Use: `kubectl get secret name-of-secret -o go-template='{{range $k,$v := .data}}{{printf \"%s: \" $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{\"\n\"}}{{end}}'` Note the escaped double quotes. – Rashack Jan 14 '21 at 13:40
  • @BrettJ I recommend to use at least Powershell 7.3, since the [quoting issue](https://github.com/PowerShell/PowerShell/issues/1995) was [fixed](https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.3#psnativecommandargumentpassing) there. I was able to just use the command in the answer as it is. – Mariusz Pawelski Aug 23 '23 at 09:38
101

If you have jq (json query) this works:

kubectl get secret db-user-pass -o json | jq '.data | map_values(@base64d)'

NOTE:

  • db-user-pass is the name of the k8s secret
  • .data is the variable within that contains the secret value
slm
  • 15,396
  • 12
  • 109
  • 124
Charles Thayer
  • 1,678
  • 1
  • 13
  • 17
22

This should work on all platforms, with kubectl 1.11+

kubectl get secrets/db-user-pass --template='{{.data.password | base64decode}}'

If there is a "-" in the password, the following will work

kubectl get secrets/db-user-pass --template='{{ index .data "sql-password" | base64decode}}'

And if you want to get all keys, values

kubectl get secrets/db-user-pass --template='{{ range $key, $value := .data }}{{ printf "%s: %s\n" $key ($value | base64decode) }}{{ end }}'
Maoz Zadok
  • 4,871
  • 3
  • 33
  • 43
  • and if there is a dash "-" in the password key the first example will not work, it will return an error: error parsing template {{ .data.sql-password |base64decode }}, template: output:1: bad character U+002D '-' , you can do the following `kubectl get secrets/db-user-pass --template='{{ index .data "sql-password" | base64decode}}'` – Maoz Zadok Apr 14 '22 at 06:40
  • 1
    Pity that https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/#decoding-secret has not been updated with this more portable idiom. BTW you can include `{{"\n"}}` at the end to get a trailing newline, nicer for interactive use. – Jesse Glick Feb 03 '23 at 18:12
  • @JesseGlick thank you for clearing this point, I'll add it to the answer – Maoz Zadok Feb 04 '23 at 06:06
15

If your secret keys contain dash (-) or dot (.):

kubectl get secret db-user-pass -o=go-template='{{index .data "password"}}' | base64 -d
cakraww
  • 2,493
  • 28
  • 30
  • 1
    As our `argocd-cluster` secret has a dot with `admin.password` inside it's `data`, this approach using a `go-template` was the only solution that worked for us. Here's our command: `kubectl -n argocd get secret argocd-cluster -o=go-template='{{index .data "admin.password"}}' | base64 -d; echo`. – jonashackt Feb 22 '22 at 10:19
14

This jsonpath variation works for me on OSX.

kubectl get secrets/db-user-pass -o jsonpath="{.data.username}" | base64 -d

To get secret with dot in the name.

kubectl get secrets/tls -o jsonpath="{.data['tls\.crt']}" | base64 -d
Tor
  • 141
  • 1
  • 6
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 22 '21 at 08:40
12

This is the link you might be looking for.

Kubernetes secrets need the secrets to be given in base64 encoded format, which can be created using base64 binary in case of linux distributions.

Example:

echo "hello" | base64
aGVsbG8K

Kubernetes decodes the base64 encoding when we pass the secret key as environment variable or mounted as volume.

Community
  • 1
  • 1
Malathi
  • 2,119
  • 15
  • 40
10

First, get the secret from the etcd by querying the api server using kubectl.

kubectl get secret db-user-pass -o yaml 

This will give you the base64 encoded secret in yaml format.

Once you have the yaml file decode them using

"base64 --decode"

Final command will look like this: Don't forget the -n flag in echo command

echo -n "jdddjdkkdkdmdl" | base64 --decode

shashank tyagi
  • 484
  • 3
  • 7
Vaibhav Jain
  • 2,155
  • 5
  • 27
  • 41
3

For easier decoding you can use a tool like ksd that will do the base64 decoding for you

kubectl get secrets/db-user-pass -o yaml | ksd

or using https://github.com/elsesiy/kubectl-view-secret

kubectl view-secret secrets/db-user-pass
csanchez
  • 1,623
  • 11
  • 20
2

on ubuntu 18+

kubectl get secrets/db-user-pass --template={{.data.password}} | base64 -d
Gajendra D Ambi
  • 3,832
  • 26
  • 30
  • Does not work for me. In version 1.18.5 I get "" when using `--template={{.data.password}}` as a parameter. – Dave May 06 '21 at 20:54
  • I use the same everyday, I have different clusters of version 1,17, 1.18,1.19 and 1.20 and it is still working for me. – Gajendra D Ambi May 07 '21 at 21:10
2

Yet another approach. This one involves a kubectl plugin, kubectl-view-secret, the good part is it doesn't print all the secrets only the selected ones, which might be beneficial from time to time.

This is how it works.

Setup

#suppose you have krew installed
❯ kubectl krew install view-secret 

Working Example

❯ kubectl get secrets 
NAME                        TYPE                             DATA   AGE
cert-manager-webhook-ca     Opaque                           3      30d
harbor-global-docker-pull   kubernetes.io/dockerconfigjson   1      30d

❯ kubectl view-secret cert-manager-webhook-ca
Multiple sub keys found. Specify another argument, one of:
-> ca.crt
-> tls.crt
-> tls.key

❯ kubectl view-secret cert-manager-webhook-ca ca.crt
-----BEGIN CERTIFICATE-----
MIIBwj.......

Vad1mo
  • 5,156
  • 6
  • 36
  • 65
2
$kubectl get secret grafana -n monitoring -o jsonpath='{.data}'

The output is the encoded string

Use the String in the echo command below

$echo "string" | base64 --decode
Andromeda
  • 1,205
  • 1
  • 14
  • 21
Chandra Y
  • 21
  • 2
1

Kubernetes 1.11+

kubectl get secrets/db-user-pass --template='{{.data.password | base64decode }}'
User1
  • 39,458
  • 69
  • 187
  • 265
1

This one liner is used to get an encoded kubeconfig file from a secret, and generate a file from it to be used dynamically on a ci job for example:

kubectl get secret YOUR_SECRET -o json | grep -oP '(?<=\"YOUR_SECRET_KEY\": \")[^\"]*' | base64 --decode > ./YOUR_KUBECONFIG_FILE_NAME
Lucas
  • 9,871
  • 5
  • 42
  • 52
0

Extending @Břetislav Hájek solution (thank you very much for that). If you need to get it by a label, then you'll need to add an extra range command to iterate over the returned items.

$ LABEL_FILTER="app.kubernetes.io/name=mysql-chart"

$ kubectl get secret  -l "$LABEL_FILTER"  -o go-template='
{{range $i := .items}}{{range $k,$v := $i.data}}{{printf "%s: " $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{"\n"}}{{end}}{{end}}'

mysql_password: ...
mysql_root_password: ...
mysql_user: ...
Meir Gabay
  • 2,870
  • 1
  • 24
  • 34
0

With bash. This is running ubuntu 18.04, and Kubernetes 1.18.5

kubectl -n metallb-system get secrets memberlist -o json | grep secretkey | grep -v f:s | awk -F '"' '{print$4}' |base64 --decode; echo
Dave
  • 727
  • 1
  • 9
  • 20
0

Minimal nodejs CLI tool (github)

npm i -g kusd
kubectl get secret your-secret -o yaml | kusd
0

This would help if you have yaml file for k8s secrets. You can use this intellij plugin to decode all base64 encoded values in a yaml file. https://plugins.jetbrains.com/plugin/19099-yaml-base64-decoder

0

For anyone who has the secret only offline (for whatever reasons) you can also use yq and jus decode the values back and forth here is an alias snippet:

elif [[ ($1 == "secret") && ($2 == "decode") ]]; then
  yq -i '.data[] |= @base64d' $3
elif [[ ($1 == "secret") && ($2 == "encode") ]]; then
  yq -i '.data[] |= @base64' $3

$3 is the path to the secret in question.

rufreakde
  • 542
  • 4
  • 17