Skip to content

Commit aa40dc7

Browse files
authored
Merge pull request #41936 from shannonxtreme/secret-use-cases
Improve and clean up use cases for Secrets
2 parents 02f34df + a9db787 commit aa40dc7

File tree

2 files changed

+200
-281
lines changed

2 files changed

+200
-281
lines changed

content/en/docs/concepts/configuration/secret.md

Lines changed: 75 additions & 281 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,75 @@ See [Information security for Secrets](#information-security-for-secrets) for mo
5555

5656
## Uses for Secrets
5757

58-
There are three main ways for a Pod to use a Secret:
58+
You can use Secrets for purposes such as the following:
5959

60-
- As [files](#using-secrets-as-files-from-a-pod) in a
61-
{{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of
62-
its containers.
63-
- As [container environment variable](#using-secrets-as-environment-variables).
64-
- By the [kubelet when pulling images](#using-imagepullsecrets) for the Pod.
60+
- [Set environment variables for a container](/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data).
61+
- [Provide credentials such as SSH keys or passwords to Pods](/docs/tasks/inject-data-application/distribute-credentials-secure/#provide-prod-test-creds).
62+
- [Allow the kubelet to pull container images from private registries](/docs/tasks/configure-pod-container/pull-image-private-registry/).
6563

6664
The Kubernetes control plane also uses Secrets; for example,
6765
[bootstrap token Secrets](#bootstrap-token-secrets) are a mechanism to
6866
help automate node registration.
6967

68+
### Use case: dotfiles in a secret volume
69+
70+
You can make your data "hidden" by defining a key that begins with a dot.
71+
This key represents a dotfile or "hidden" file. For example, when the following secret
72+
is mounted into a volume, `secret-volume`, the volume will contain a single file,
73+
called `.secret-file`, and the `dotfile-test-container` will have this file
74+
present at the path `/etc/secret-volume/.secret-file`.
75+
76+
{{< note >}}
77+
Files beginning with dot characters are hidden from the output of `ls -l`;
78+
you must use `ls -la` to see them when listing directory contents.
79+
{{< /note >}}
80+
81+
```yaml
82+
apiVersion: v1
83+
kind: Secret
84+
metadata:
85+
name: dotfile-secret
86+
data:
87+
.secret-file: dmFsdWUtMg0KDQo=
88+
---
89+
apiVersion: v1
90+
kind: Pod
91+
metadata:
92+
name: secret-dotfiles-pod
93+
spec:
94+
volumes:
95+
- name: secret-volume
96+
secret:
97+
secretName: dotfile-secret
98+
containers:
99+
- name: dotfile-test-container
100+
image: registry.k8s.io/busybox
101+
command:
102+
- ls
103+
- "-l"
104+
- "/etc/secret-volume"
105+
volumeMounts:
106+
- name: secret-volume
107+
readOnly: true
108+
mountPath: "/etc/secret-volume"
109+
```
110+
111+
### Use case: Secret visible to one container in a Pod
112+
113+
Consider a program that needs to handle HTTP requests, do some complex business
114+
logic, and then sign some messages with an HMAC. Because it has complex
115+
application logic, there might be an unnoticed remote file reading exploit in
116+
the server, which could expose the private key to an attacker.
117+
118+
This could be divided into two processes in two containers: a frontend container
119+
which handles user interaction and business logic, but which cannot see the
120+
private key; and a signer container that can see the private key, and responds
121+
to simple signing requests from the frontend (for example, over localhost networking).
122+
123+
With this partitioned approach, an attacker now has to trick the application
124+
server into doing something rather arbitrary, which may be harder than getting
125+
it to read a file.
126+
70127
### Alternatives to Secrets
71128
72129
Rather than using a Secret to protect confidential data, you can pick from alternatives.
@@ -108,8 +165,8 @@ These types vary in terms of the validations performed and the constraints
108165
Kubernetes imposes on them.
109166

110167
| Built-in Type | Usage |
111-
| ------------------------------------- | --------------------------------------- |
112-
| `Opaque` | arbitrary user-defined data |
168+
| ------------------------------------- |---------------------------------------- |
169+
| `Opaque` | arbitrary user-defined data |
113170
| `kubernetes.io/service-account-token` | ServiceAccount token |
114171
| `kubernetes.io/dockercfg` | serialized `~/.dockercfg` file |
115172
| `kubernetes.io/dockerconfigjson` | serialized `~/.docker/config.json` file |
@@ -576,17 +633,17 @@ metadata:
576633
name: mypod
577634
spec:
578635
containers:
579-
- name: mypod
580-
image: redis
581-
volumeMounts:
582-
- name: foo
583-
mountPath: "/etc/foo"
584-
readOnly: true
585-
volumes:
636+
- name: mypod
637+
image: redis
638+
volumeMounts:
586639
- name: foo
587-
secret:
588-
secretName: mysecret
589-
optional: true
640+
mountPath: "/etc/foo"
641+
readOnly: true
642+
volumes:
643+
- name: foo
644+
secret:
645+
secretName: mysecret
646+
optional: true
590647
```
591648

592649
By default, Secrets are required. None of a Pod's containers will start until
@@ -697,269 +754,6 @@ for a detailed explanation of that process.
697754

698755
You cannot use ConfigMaps or Secrets with {{< glossary_tooltip text="static Pods" term_id="static-pod" >}}.
699756

700-
## Use cases
701-
702-
### Use case: As container environment variables {#use-case-as-container-environment-variables}
703-
704-
You can create a Secret and use it to
705-
[set environment variables for a container](/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data).
706-
707-
### Use case: Pod with SSH keys
708-
709-
Create a Secret containing some SSH keys:
710-
711-
```shell
712-
kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
713-
```
714-
715-
The output is similar to:
716-
717-
```
718-
secret "ssh-key-secret" created
719-
```
720-
721-
You can also create a `kustomization.yaml` with a `secretGenerator` field containing ssh keys.
722-
723-
{{< caution >}}
724-
Think carefully before sending your own SSH keys: other users of the cluster may have access
725-
to the Secret.
726-
727-
You could instead create an SSH private key representing a service identity that you want to be
728-
accessible to all the users with whom you share the Kubernetes cluster, and that you can revoke
729-
if the credentials are compromised.
730-
{{< /caution >}}
731-
732-
Now you can create a Pod which references the secret with the SSH key and
733-
consumes it in a volume:
734-
735-
```yaml
736-
apiVersion: v1
737-
kind: Pod
738-
metadata:
739-
name: secret-test-pod
740-
labels:
741-
name: secret-test
742-
spec:
743-
volumes:
744-
- name: secret-volume
745-
secret:
746-
secretName: ssh-key-secret
747-
containers:
748-
- name: ssh-test-container
749-
image: mySshImage
750-
volumeMounts:
751-
- name: secret-volume
752-
readOnly: true
753-
mountPath: "/etc/secret-volume"
754-
```
755-
756-
When the container's command runs, the pieces of the key will be available in:
757-
758-
```
759-
/etc/secret-volume/ssh-publickey
760-
/etc/secret-volume/ssh-privatekey
761-
```
762-
763-
The container is then free to use the secret data to establish an SSH connection.
764-
765-
### Use case: Pods with prod / test credentials
766-
767-
This example illustrates a Pod which consumes a secret containing production credentials and
768-
another Pod which consumes a secret with test environment credentials.
769-
770-
You can create a `kustomization.yaml` with a `secretGenerator` field or run
771-
`kubectl create secret`.
772-
773-
```shell
774-
kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
775-
```
776-
777-
The output is similar to:
778-
779-
```
780-
secret "prod-db-secret" created
781-
```
782-
783-
You can also create a secret for test environment credentials.
784-
785-
```shell
786-
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
787-
```
788-
789-
The output is similar to:
790-
791-
```
792-
secret "test-db-secret" created
793-
```
794-
795-
{{< note >}}
796-
Special characters such as `$`, `\`, `*`, `=`, and `!` will be interpreted by your
797-
[shell](https://en.wikipedia.org/wiki/Shell_(computing)) and require escaping.
798-
799-
In most shells, the easiest way to escape the password is to surround it with single quotes (`'`).
800-
For example, if your actual password is `S!B\*d$zDsb=`, you should execute the command this way:
801-
802-
```shell
803-
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
804-
```
805-
806-
You do not need to escape special characters in passwords from files (`--from-file`).
807-
{{< /note >}}
808-
809-
Now make the Pods:
810-
811-
```shell
812-
cat <<EOF > pod.yaml
813-
apiVersion: v1
814-
kind: List
815-
items:
816-
- kind: Pod
817-
apiVersion: v1
818-
metadata:
819-
name: prod-db-client-pod
820-
labels:
821-
name: prod-db-client
822-
spec:
823-
volumes:
824-
- name: secret-volume
825-
secret:
826-
secretName: prod-db-secret
827-
containers:
828-
- name: db-client-container
829-
image: myClientImage
830-
volumeMounts:
831-
- name: secret-volume
832-
readOnly: true
833-
mountPath: "/etc/secret-volume"
834-
- kind: Pod
835-
apiVersion: v1
836-
metadata:
837-
name: test-db-client-pod
838-
labels:
839-
name: test-db-client
840-
spec:
841-
volumes:
842-
- name: secret-volume
843-
secret:
844-
secretName: test-db-secret
845-
containers:
846-
- name: db-client-container
847-
image: myClientImage
848-
volumeMounts:
849-
- name: secret-volume
850-
readOnly: true
851-
mountPath: "/etc/secret-volume"
852-
EOF
853-
```
854-
855-
Add the pods to the same `kustomization.yaml`:
856-
857-
```shell
858-
cat <<EOF >> kustomization.yaml
859-
resources:
860-
- pod.yaml
861-
EOF
862-
```
863-
864-
Apply all those objects on the API server by running:
865-
866-
```shell
867-
kubectl apply -k .
868-
```
869-
870-
Both containers will have the following files present on their filesystems with the values
871-
for each container's environment:
872-
873-
```
874-
/etc/secret-volume/username
875-
/etc/secret-volume/password
876-
```
877-
878-
Note how the specs for the two Pods differ only in one field; this facilitates
879-
creating Pods with different capabilities from a common Pod template.
880-
881-
You could further simplify the base Pod specification by using two service accounts:
882-
883-
1. `prod-user` with the `prod-db-secret`
884-
1. `test-user` with the `test-db-secret`
885-
886-
The Pod specification is shortened to:
887-
888-
```yaml
889-
apiVersion: v1
890-
kind: Pod
891-
metadata:
892-
name: prod-db-client-pod
893-
labels:
894-
name: prod-db-client
895-
spec:
896-
serviceAccount: prod-db-client
897-
containers:
898-
- name: db-client-container
899-
image: myClientImage
900-
```
901-
902-
### Use case: dotfiles in a secret volume
903-
904-
You can make your data "hidden" by defining a key that begins with a dot.
905-
This key represents a dotfile or "hidden" file. For example, when the following secret
906-
is mounted into a volume, `secret-volume`:
907-
908-
```yaml
909-
apiVersion: v1
910-
kind: Secret
911-
metadata:
912-
name: dotfile-secret
913-
data:
914-
.secret-file: dmFsdWUtMg0KDQo=
915-
---
916-
apiVersion: v1
917-
kind: Pod
918-
metadata:
919-
name: secret-dotfiles-pod
920-
spec:
921-
volumes:
922-
- name: secret-volume
923-
secret:
924-
secretName: dotfile-secret
925-
containers:
926-
- name: dotfile-test-container
927-
image: registry.k8s.io/busybox
928-
command:
929-
- ls
930-
- "-l"
931-
- "/etc/secret-volume"
932-
volumeMounts:
933-
- name: secret-volume
934-
readOnly: true
935-
mountPath: "/etc/secret-volume"
936-
```
937-
938-
The volume will contain a single file, called `.secret-file`, and
939-
the `dotfile-test-container` will have this file present at the path
940-
`/etc/secret-volume/.secret-file`.
941-
942-
{{< note >}}
943-
Files beginning with dot characters are hidden from the output of `ls -l`;
944-
you must use `ls -la` to see them when listing directory contents.
945-
{{< /note >}}
946-
947-
### Use case: Secret visible to one container in a Pod
948-
949-
Consider a program that needs to handle HTTP requests, do some complex business
950-
logic, and then sign some messages with an HMAC. Because it has complex
951-
application logic, there might be an unnoticed remote file reading exploit in
952-
the server, which could expose the private key to an attacker.
953-
954-
This could be divided into two processes in two containers: a frontend container
955-
which handles user interaction and business logic, but which cannot see the
956-
private key; and a signer container that can see the private key, and responds
957-
to simple signing requests from the frontend (for example, over localhost networking).
958-
959-
With this partitioned approach, an attacker now has to trick the application
960-
server into doing something rather arbitrary, which may be harder than getting
961-
it to read a file.
962-
963757
## Immutable Secrets {#secret-immutable}
964758

965759
{{< feature-state for_k8s_version="v1.21" state="stable" >}}

0 commit comments

Comments
 (0)