Secret and configMap for k8s data persistence

Preface

In K8s, there are two resource objects, Secret and configMap. This is also a way to realize data persistence, which is slightly different from the way of PV or mount directory written before.

Secret resource object: it can store light sensitive information, such as database user name and password or authentication secret key. Its data is stored in secret

configMap resource object: like Secret, configMap has most of the same features, but the difference is that configMap stores some less important information, and the data it saves is stored in clear text.

When we create these two resource objects, we write the information stored by these two resource objects to the etcd data center in the k8s cluster.

I. similarities and differences between secret and configMap

Same point:

They are used to store lightweight information and can be used for mounting other resource objects (Deployment, RC, RS, and POd).

The creation methods (4 kinds) and reference methods (2 kinds) of these two resource objects are the same, and they are stored in the way of key value pairs.

Difference:

Secret is used to save sensitive information, and configMap is used to save some unimportant data. Specifically, when we execute the command "kubectl describe...", the resource object of secret type cannot see its specific information, while configMap can see its saved specific content.

2. Four ways to create Secret resource objects

Create method 1 (via -- from literal)

Suppose the data to be stored is:
name: zhangsan
tel:15888888888

[root@master ~]# kubectl create secret generic secret
1 --from-literal=name=zhangsan --from-literal=tel=1588888888
[root@master ~]# kubectl get secrets secret1  #View the created secret 1
NAME      TYPE     DATA   AGE
secret1   Opaque   2      89s
[root@master ~]# kubectl describe secrets secret1 
Name:         secret1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
name:  8 bytes       #You can see that you can only view the content of the key, but not the value corresponding to the key
tel:   10 bytes

Create method 2 (via -- from file)

This method is more troublesome than method 1 and is not recommended.

#The key value pairs to be stored need to be written to the file first, and only one value can be written to each file
[root@master ~]# echo zhangsan > name
[root@master ~]# echo 15888888888 > tel
[root@master ~]# cat name tel
zhangsan
15888888888
[root@master ~]# kubectl create secret generic secret2 --from-file=name --from-file=tel 
#Execute the above command to create, and then use the command of method 1 to view by yourself

Create method 3 (via -- from env file)

This method can write multiple key value pairs in the same file, which is recommended.

[root@master ~]# cat > env.txt <<EOF  #Write the key value pair to be stored to the file
> name=zhangsan
> tel=15888888888
> EOF
[root@master ~]# kubectl create secret generic secert3 --from-env-file=env.txt 
#The key value pairs in env.txt can be stored in k8s data center by executing the above command
#Check whether it is created or not

Create method 4 (via yaml profile)

#The value to be stored can be encrypted
[root@master ~]# echo zhangsan | base64
emhhbmdzYW4K
[root@master ~]# echo 1588888888 | base64
MTU4ODg4ODg4OAo=
[root@master ~]# vim secret.yaml     #Write yaml file
apiVersion: v1
kind: Secret
metadata:
  name: secret4
data:                           #The following values are encrypted at the command line
  name: emhhbmdzYW4K
  tel: MTU4ODg4ODg4OAo=
[root@master ~]# kubectl apply -f secret.yaml     #Execute yaml file
#You can use the following command to decrypt encrypted characters
[root@master ~]# echo -n MTU4ODg4ODg4OAo= | base64 --decode 
1588888888

3. Two ways to use Secret

Since secret can't be viewed from the command line, what's the meaning of secret? Through the following usage, you should be able to understand its usage scenarios.

Use method 1 (use secret as volume mount)

[root@master ~]# vim secret-pod.yaml  #Write yaml file and run a pod

apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
  - name: secret-pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy; sleep 30000  #The above fields are independent of using secret
    volumeMounts:
    - name: test
      mountPath: /etc/test        #Specify the directory to mount to the container
      readOnly: true     #It's decided here that it's mounted read-only
  volumes:
  - name: test
    secret:
      secretName: secret4         #Here we specify the name of secret, which is the secret we created with the fourth method

[root@master ~]# kubectl apply -f secret-pod.yaml     #Execute yaml file
[root@master ~]# kubectl exec -it secret-pod /bin/sh   #Enter the created container
/ # cat /etc/test/name /etc/test/tel     #View the mounted directory
zhangsan
1588888888
#You can find that it's automatically decrypted for us

Now, we can verify that if the contents of secret 4 are changed at this time, does the contents of the corresponding mount directory in the container change?

[root@master ~]# echo lisi | base64
bGlzaQo=
[root@master ~]# echo 1599999999 | base64
MTU5OTk5OTk5OQo=
[root@master ~]# vim secret.yaml      #Modify its contents
apiVersion: v1
kind: Secret
metadata:
  name: secret4
data:
  name: bGlzaQo=
  tel: MTU5OTk5OTk5OQo=
[root@master ~]# kubectl apply -f secret.yaml     #Re execute yaml file
[root@master ~]# kubectl exec -it secret-pod /bin/sh   #Enter the container again
/ # cat /etc/test/name /etc/test/tel     #You can see that the data in the container has changed
lisi
1599999999

Use method 2 (secret as an environment variable)

[root@master ~]# vim secret-pod.yaml      #Write yaml file
apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
  - name: secret-pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy; sleep 30000
    env:          #Set the environment variable, where the value stored in secert3 is called
      - name: SECRET_NAME   #Variable name in container
        valueFrom:
          secretKeyRef:
            name: secert3         #Specifies that secert3 is called
            key: name                   #The value corresponding to the name of secert3 is called
      - name: SECRET_TEL          #This is the same as the above
        valueFrom:
          secretKeyRef:
            name: secert3
            key: tel
[root@master ~]# kubectl delete -f secret-pod.yaml  #Delete previous pod
[root@master ~]# kubectl apply -f secret-pod.yaml     #Regenerate pod
#Enter the container and output the corresponding variables
[root@master ~]# kubectl exec -it secret-pod /bin/sh
/ # echo $SECRET_NAME
zhangsan
/ # echo $SECRET_TEL
15888888888

At this point, the key value pair stored in secert is called in the form of variable. You can also test and modify the value stored in secert to see if the variable in the pod container will change with it. The answer is No. if the value stored in secert is called in the way of variable, the value of the variable in the container will not change with the value stored in secert unless the pod is regenerated.

Four ways to create configMap resource objects

In fact, configMap and secert resource objects are created in exactly the same way. Here, write down the three creation methods of "- from literal", "from env file" and "yaml file". For the creation method of "- from file", refer to the creation method of secert.

Create method 1 (via -- from literal)

[root@master ~]# kubectl create configmap config1 --from-literal=name=lisi --from-literal=age=18
#Store the key value pair with the name config1
[root@master ~]# kubectl describe configmaps config1   #View the config1 created
Name:         config1
Namespace:    default
Labels:       <none>
Annotations:  <none>
#You can clearly see the data stored in it, so it is used to store some less important data
Data
====
age:
----
18
name:
----
lisi
Events:  <none>

Create method 2 (via -- from env file)

[root@master ~]# cat > config.txt <<EOF   #Write key value pair to file
> name=lisi
> age=18
> EOF
[root@master ~]# kubectl create configmap configmap2 --from-env-file=config.txt 
#Executive order

Create method 3 (via yaml profile)

[root@master ~]# vim configmap3.yaml #Write yaml file
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap3
data:
  name: lisi
  age: '18'       #If the value is a number, it must be enclosed in single quotes
[root@master ~]# kubectl apply -f configmap3.yaml     #Execute yaml file

V. two ways to reference configMap data

The application mode is similar to that of the secert resource object. It is either volume mount or variable reference, but some keywords in some yaml files are different.

Reference method 1 (mount via volume)

[root@master ~]# kubectl delete -f secret-pod.yaml    #Delete the previously created pod
[root@master ~]# vim secret-pod.yaml     #Modify yaml file

apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
  - name: secret-pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy; sleep 30000   #There's no change in that
    volumeMounts:
    - name: test
      mountPath: /mnt    #Mount to container's mnt directory
      readOnly: true
  volumes:
  - name: test
    configMap:             #The keywords here are different
      name: configmap3         #configmap3 is mounted
[root@master ~]# kubectl apply -f secret-pod.yaml      #Execute yaml file
[root@master ~]# kubectl exec -it secret-pod /bin/sh  #Container entry
/ # cat /mnt/name /mnt/age    #View attached content
lisi18/ # 
(Because of the special container used, the output format is not intuitive, but the data is correct.)

Similarly, in this way of volume mounting, the data in the pod container will change with the data in configmap3, and they share the same file.

Reference method 2 (by configuring env environment variables)

[root@master ~]# kubectl delete -f secret-pod.yaml    #Delete the previously created pod
[root@master ~]# vim secret-pod.yaml         #Modify yaml file
apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
  - name: secret-pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy; sleep 30000
    env:           #Define the environment variables, and use the configmap created here
        2 Key value pair content of
      - name: USER_NAME
        valueFrom:
          configMapKeyRef:
            name: configmap2
            key: name      #Call the value of name in configmap2
      - name: USER_AGE
        valueFrom:
          configMapKeyRef:
            name: configmap2
            key: age      #Call the value of age in configmap2
[root@master ~]# kubectl apply -f secret-pod.yaml 
[root@master ~]# kubectl exec -it secret-pod /bin/sh    #Enter container output environment variable
/ # echo $USER_NAME
lisi
/ # echo $USER_AGE
18

Here is a test. If you change the key value pair of configmap2, will the environment variables in the container change?

[root@master ~]# vim config.txt    #Modify the value of configmap2
name=wangwu
age=28
[root@master ~]# kubectl delete configmaps     #Need to delete first
[root@master ~]# kubectl create configmap configmap2 --from-env-file=config.txt       #Re create
[root@master ~]# kubectl exec -it secret-pod /bin/sh #Enter the container output variable, and you can see that the variable has not changed
/ # echo $USER_AGE
18
/ # echo $USER_NAME
lisi

Now, regenerate the pod to see if its environment variables will change?

[root@master ~]# kubectl delete -f secret-pod.yaml   #Delete pod
[root@master ~]# kubectl apply -f secret-pod.yaml      #Regenerate pod
[root@master ~]# kubectl exec -it secret-pod /bin/sh   #Enter the container to view the environment variables and find that they have changed
/ # echo $USER_NAME
wangwu
/ # echo $USER_AGE
28

At this point, the validation is complete.

————————Thank you for reading————————

Keywords: vim less Database

Added by Jaguar83 on Wed, 20 Nov 2019 15:13:44 +0200