Secret overview
When studying in the previous article ConfigMap
, we said that ConfigMap
this resource object is Kubernetes
a very important object. Generally, ConfigMap
it is used to store some non-secure configuration information. If it involves some security-related data, it ConfigMap
is very inappropriate to use it. Because ConfigMap
it is called storage, we said that we need to use another resource object at this time: Secret
, Secret
which is used to store sensitive information, such as passwords, OAuth tokens and ssh keys, etc., and put these information in the middle Secret
than in It is safer and more flexible Pod
in the definition or docker
image.
Secret
There are three types:
- Opaque: Secret in base64 encoding format, used to store passwords, keys, etc.; but the data can also be decoded by base64 –decode to get the original data, all encryption is very weak.
- kubernetes.io/dockerconfigjson: Used to store authentication information for private docker registries.
- kubernetes.io/service-account-token: Used for
serviceaccount
reference, when serviceaccout is created, Kubernetes will create the corresponding secret by default. If the Pod uses serviceaccount, the corresponding secret will be automatically mounted in the Pod directory/run/secrets/kubernetes.io/serviceaccount
.
Opaque Secret
The data of Opaque type is a map type, and the value is required to be base64
encoded. For example, let’s create a Secret object whose username is admin and password is admin321. First, we encode the username and password in base64.
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "admin321" | base64
YWRtaW4zMjE=
Then we can use the encoded data above to write a YAML
file: (secret-demo.yaml)
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: YWRtaW4zMjE=
Then we can use the same kubectl
command to create:
$ kubectl create -f secret-demo.yaml
secret "mysecret" created
Use get secret
the command to view:
$ kubectl get secret
NAME TYPE DATA AGE
default-token-n9w2d kubernetes.io/service-account-token 3 33d
mysecret Opaque 2 40s
Among them
default-token-cty7pdefault-token-n9w2d
is the secret created by default when creating a cluster, which is referenced by serviceacount/default.
Use describe
the command to view details:
$ kubectl describe secret mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 8 bytes
username: 5 bytes
We can see that the information describe
viewed by the command Data
is not directly displayed. If we want to see Data
the detailed information inside, we can also output it into YAML
a file for viewing:
$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
password: YWRtaW4zMjE=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: 2018-06-19T15:27:06Z
name: mysecret
namespace: default
resourceVersion: "3694084"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: 39c139f5-73d5-11e8-a101-525400db4df7
type: Opaque
After creating Secret
an object, there are two ways to use it:
- in the form of environment variables
- Mount as Volume
environment variable
First, let's test the way of environment variables. Similarly, let's use a simple busybox
mirror to test: (secret1-pod.yaml)
apiVersion: v1
kind: Pod
metadata:
name: secret1-pod
spec:
containers:
- name: secret1
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
The keywords defined in the above environment variables are similar to secretKeyRef
those in our last lesson . One is obtained from the object, and the other is obtained from the object. Create the above :configMapKeyRef
Secret
ConfigMap
Pod
$ kubectl create -f secret1-pod.yaml
pod "secret1-pod" created
Then we view Pod
the log output:
$ kubectl logs secret1-pod
...
USERNAME=admin
PASSWORD=admin321
...
You can see that there are two environment variables, USERNAME and PASSWORD, outputted.
Volume mount
Similarly, we use one Pod
to verify Volume
the mount and create a Pod
file: (secret2-pod.yaml)
apiVersion: v1
kind: Pod
metadata:
name: secret2-pod
spec:
containers:
- name: secret2
image: busybox
command: ["/bin/sh", "-c", "ls /etc/secrets"]
volumeMounts:
- name: secrets
mountPath: /etc/secrets
volumes:
- name: secrets
secret:
secretName: mysecret
create Pod
:
$ kubectl create -f secret-pod2.yaml
pod "secret2-pod" created
Then we look at the output log:
$ kubectl logs secret2-pod
password
username
You can see secret
that the two keys are mounted into two corresponding files. Of course, if you want to mount to a specified file, can you also use the method of the previous lesson: secretName
add items
the specified key and path below, you can refer to the ConfigMap
method in the previous lesson to test it.
kubernetes.io/dockerconfigjson
In addition to the above Opaque
types, we can also create user docker registry
authentication Secret
, kubectl create
just use the command to create it directly, as follows:
$ kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistry" created
Then view Secret
the list:
$ kubectl get secret
NAME TYPE DATA AGE
default-token-n9w2d kubernetes.io/service-account-token 3 33d
myregistry kubernetes.io/dockerconfigjson 1 15s
mysecret Opaque 2 34m
Pay attention to whether the above TYPE
types myregistry
are corresponding kubernetes.io/dockerconfigjson
, and you can also use describe
the command to view detailed information:
$ kubectl describe secret myregistry
Name: myregistry
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 152 bytes
In the same way, you can see that Data
the area is not directly displayed. If you want to view it, you can use it -o yaml
to output and display it:
$ kubectl get secret myregistry -o yaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0=
kind: Secret
metadata:
creationTimestamp: 2018-06-19T16:01:05Z
name: myregistry
namespace: default
resourceVersion: "3696966"
selfLink: /api/v1/namespaces/default/secrets/myregistry
uid: f91db707-73d9-11e8-a101-525400db4df7
type: kubernetes.io/dockerconfigjson
data.dockerconfigjson
You can decode the data above and below base64
to see what the data inside is like?
$ echo eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= | base64 -d
{
"auths":{
"DOCKER_SERVER":{
"username":"DOCKER_USER","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRVI6RE9DS0VSX1BBU1NXT1JE"}}}
If we need to pull docker
the image in the private warehouse, we need to use myregistry
the above Secret
:
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: foo
image: 192.168.1.100:5000/test:v1
imagePullSecrets:
- name: myregistrykey
We need to pull the mirror of the private warehouse 192.168.1.100:5000/test:v1
, we need to create a private warehouse as above Secret
, and then Pod
specify it in the YAML file imagePullSecrets
, we will explain in detail in the course of private warehouse construction later.
kubernetes.io/service-account-token
Another Secret
type is kubernetes.io/service-account-token
, for being serviceaccount
referenced. When serviceaccout is created, Kubernetes will create the corresponding secret by default. If the Pod uses serviceaccount, the corresponding secret will be automatically mounted in the Pod /run/secrets/kubernetes.io/serviceaccount
directory.
Here we use a nginx
mirror image to verify it. Think about it, why not use busybox
a mirror image to verify it? Of course, it is also possible, but we can’t command
verify it in it, because the token Pod
will be mounted after it is running. If command
you check it directly in the command, there must be no token file.
$ kubectl run secret-pod3 --image nginx:1.7.9
deployment.apps "secret-pod3" created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
...
secret-pod3-78c8c76db8-7zmqm 1/1 Running 0 13s
...
$ kubectl exec secret-pod3-78c8c76db8-7zmqm ls /run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token
$ kubectl exec secret-pod3-78c8c76db8-7zmqm cat /run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbjl3MmQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjMzY2FkOWQxLTU5MmYtMTFlOC1hMTAxLTUyNTQwMGRiNGRmNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.0FpzPD8WO_fwnMjwpGIOphdVu4K9wUINwpXpBOJAQ-Tawd0RTbAUHcgYy3sEHSk9uvgnl1FJRQpbQN3yVR_DWSIlAtbmd4dIPxK4O7ZVdd4UnmC467cNXEBqL1sDWLfS5f03d7D1dw1ljFJ_pJw2P65Fjd13reKJvvTQnpu5U0SDcfxj675-Z3z-iOO3XSalZmkFIw2MfYMzf_WpxW0yMFCVkUZ8tBSTegA9-NJZededceA_VCOdKcUjDPrDo-CNti3wZqax5WPw95Ou8RJDMAIS5EcVym7M2_zjGiqHEL3VTvcwXbdFKxsNX-1VW6nr_KKuMGKOyx-5vgxebl71QQ
Secret vs. ConfigMap
Finally, let's compare the similarities Secret
and ConfigMap
differences with these two resource objects:
Same point:
- The form of key/value
- belong to a specific namespace
- can be exported to environment variables
- Can be mounted in the form of directory/file
- The configuration information mounted through the volume can be hot updated
difference:
- Secret can be associated with ServerAccount
- Secret can store the authentication information of docker register, which is used in the parameter of ImagePullSecret to pull the image of the private warehouse
- Secret supports Base64 encryption
- Secret is divided into three types: kubernetes.io/service-account-token, kubernetes.io/dockerconfigjson, and Opaque, while Configmap does not distinguish between types