Liunx-Configmap and Secret of k8s

Secret and ConfigMap

In the daily stand-alone or even cluster state, we need to configure an application and only need to modify its configuration file.
There are usually the following methods in traditional practice:

  • When starting the container, pass parameters through commands;
  • Write the defined configuration file through the mirror file;
  • Pass configuration data through environment variables;
  • Mount the Docker volume to transfer configuration files;

In the Kubernetes system, there are also such components, which are special storage volume types. It does not provide pod storage space, but provides a way for administrators or users to inject configuration information from outside the cluster to applications inside the Pod. The two special types of storage volumes are: configMap and secret

  • Secret: Used to pass sensitive information to the Pod, such as passwords, private keys, certificate files, etc. If these information is easily leaked if defined in the container, the Secret resource allows users to store this information in the emergency crowd, and then mount it through the Pod. Realize the effect of decoupling sensitive data and system;
  • ConfigMap: It is mainly used to inject non-sensitive data into the Pod. When using it, the user stores the data directly in the ConfigMap object, and then the Pod uses the ConfigMap volume for reference to realize the centralized definition and management of the container's configuration file;

1. Secret

The way the Secret object stores data is to store the data in a key-value way, and the way to call Secret in the Pod resource is to access the data through environment variables or storage volumes, which solves the configuration problem of sensitive data such as passwords, tokens, and keys. There is no need to expose these sensitive data to the mirror or Pod Spec. In addition, the data storage and printing format of the Secret object is a Base64-encoded string. Therefore, when creating the Secret object, the user also needs to provide data in this type of encoding format. When accessed in the container by means of environment variables or storage volumes, it will be automatically decoded into a plaintext format. It should be noted that if it is on the Master node, the Secret object is stored in etcd in a non-encrypted format, so the management and permissions of etcd need to be strictly controlled.

There are 4 types of Secret:

  • Service Account: Used to access the Kubernetes API, automatically created by Kubernetes, and automatically mounted to the Pod's /run/secrets/kubernetes.io/serviceaccount directory;
  • Opaque: Secret in base64 encoding format, used to store passwords, keys, information, certificates, etc. The type identifier is generic;
  • kubernetes.io/dockerconfigjson: used to store the authentication information of the private docker registry, the type identification is docker-registry;
  • kubernetes.io/tls: used to store certificates and private key files for SSL communication mode, the imperative creation type identification is tls;

1.1 How to create Secret:

1.1.1 --from-literal

View help

[root@master ~]# kubectl  create  secret  -h
Create a secret using specified subcommand.

Available Commands:
  docker-registry 创建一个给 Docker registry 使用的 secret
  generic         从本地 file, directory 或者 literal value 创建一个 secret
  tls             创建一个 TLS secret

Usage:
  kubectl create secret [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

PS: A -from-literal statement can only save one piece of information

[root@master ~]# kubectl  create  secret  generic  mysecret1 --from-literal=username=root --from-literal=password=123.com
secret/mysecret1 created

View Secrets resource object

[root@master ~]# kubectl  get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-bql2v   kubernetes.io/service-account-token   3      8d
mysecret1             Opaque                                2      112s

check the detail information

[root@master ~]# kubectl  describe  secrets  mysecret1 
Name:         mysecret1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  7 bytes
username:  4 bytes

PS: When viewing the detailed information, when you see the corresponding key value, you can't see the detailed values ​​value, because this data is encrypted when the resource is created

1.1.2 --from-file

PS: The method of -from-file is that each file content corresponds to an information entry.

[root@master ~]# echo root > username
[root@master ~]# echo 123.com > password
[root@master ~]# kubectl  create  secret generic  mysecret2 --from-file=username  --from-file=password 
secret/mysecret2 created
[root@master ~]# kubectl  get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-bql2v   kubernetes.io/service-account-token   3      8d
mysecret1             Opaque                                2      10m
mysecret2             Opaque                                2      4s

1.1.3 --from-env-file

PS: Each line of Key=Value in the file env.txt corresponds to an information item. That is, each line in the file can only record one piece of data

[root@master ~]# vim env.txt
username=root
password=123.com
[root@master ~]# kubectl  create  secret  generic  myseret3 --from-env-file=env.txt 
secret/myseret3 created
[root@master ~]# kubectl get secrets  | grep myseret3
NAME                  TYPE                                  DATA   AGE
myseret3              Opaque                                2      22s

1.1.4 Create by yaml list

Encrypt data in advance

[root@master ~]# echo root | base64
cm9vdAo=
[root@master ~]# echo  123.com | base64
MTIzLmNvbQo=

yaml list

[root@master ~]# vim secret.yaml 
kind: Secret
apiVersion: v1
metadata: 
  name: mysecret4
data:
  username: cm9vdAo=
  password: MTIzLmNvbQo=
[root@master ~]# kubectl  apply  -f  secret.yaml 
secret/mysecret4 created
[root@master ~]# kubectl get secrets  | grep mysecret4
NAME                  TYPE                                  DATA   AGE
mysecret4             Opaque                                2      17s

decoding

PS: Before saving the data, the saved data is encrypted, but the base64 method is not absolutely safe. For example, the garbled string obtained by the base64 method above can be decoded with -decode

[root@master ~]# echo  -n cm9vdAo= | base64 --decode 
root
[root@master ~]# echo  -n MTIzLmNvbQo= | base64 --decode 
123.com

1.2 Use of Secret resources

PS: Pod can use Secret through Volume or environment variables

1.2.1 Volume

yaml list

[root@master ~]# vim volume.yaml

kind: Pod
apiVersion: v1
metadata:
  name: pod
spec:
  volumes:
  - name: test-volume
    secret:
      secretName: mysecret1 
  containers:
  - name: pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 30000
    volumeMounts:
    - name: test-volume
      mountPath:  "/etc/volume" 
      readOnly: true
  
[root@master ~]# kubectl  apply  -f  volume.yaml 
pod/pod created

PS: Use the secret resource in the way of volume mounting, it will change with the change of the secret resource object data. Therefore, when mounting with volume, in order to ensure the security of secret resources, the mount is read-only (readOnly).

Check if there is corresponding data in the pod

[root@master ~]# kubectl  get pod
NAME   READY   STATUS    RESTARTS   AGE
pod    1/1     Running   0          61s
[root@master ~]# kubectl  exec  pod cat /etc/volume/username
root 
[root@master ~]# kubectl  exec  pod cat /etc/volume/password
123.com

You can also define your own data path

[root@master ~]# kubectl  delete  -f volume.yaml 
pod "pod" deleted
[root@master ~]# vim volume.yaml 
......
spec:
  volumes:
  - name: test-volume
    secret:
      secretName: mysecret1 
      items:
      - key:  username
        path: mygroup/my-username
      - key:  password
        path: mygroup/my-password
......
[root@master ~]# kubectl  apply  -f  volume.yaml 
pod/pod created

[root@master ~]# kubectl  exec  -it pod  sh
/ # cd /etc/volume/
/etc/volume # ls
mygroup
/etc/volume # ls mygroup/
my-password  my-username

或者
[root@master ~]#  kubectl  exec  pod cat /etc/volume/mygroup/my-username
root
[root@master ~]#  kubectl  exec  pod cat /etc/volume/mygroup/my-password
123.com

1.2.2 Environment variables

PS: Copy the above file and change the name to bianliang

[root@master ~]# kubectl  delete  -f  volume.yaml 
pod "pod" deleted
[root@master ~]# mv volume.yaml  bianliang.yaml
[root@master ~]# vim bianliang.yaml 

kind: Pod
apiVersion: v1
metadata:
  name: pod
spec:
  containers:
  - name: pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 30000
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key:  username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key:  password
            
[root@master ~]# kubectl  apply  -f  bianliang.yaml 
pod/pod created

View data

[root@master ~]# kubectl  get pod
NAME   READY   STATUS    RESTARTS   AGE
pod    1/1     Running   0          50s
[root@master ~]# kubectl  exec  -it pod  sh
/ # echo $SECRET_USERNAME
root
/ # echo $SECRET_PASSWORD
123.com

Export the resources created with the command line as a yaml list.

[root@master ~]# kubectl  get  secrets 
NAME                  TYPE                                  DATA   AGE
default-token-bql2v   kubernetes.io/service-account-token   3      8d
mysecret1             Opaque                                2      50m
mysecret2             Opaque                                2      40m
mysecret4             Opaque                                2      33m
myseret3              Opaque                                2      39m

[root@master ~]# kubectl  get secrets mysecret2  -o yaml >> mysecret2.yaml
[root@master ~]# cat mysecret2.yaml 
apiVersion: v1
data:
  password: MTIzLmNvbQo=
  username: cm9vdAo=
kind: Secret
metadata:
  creationTimestamp: "2020-11-15T06:56:01Z"
  name: mysecret2
  namespace: default
  resourceVersion: "8821"
  selfLink: /api/v1/namespaces/default/secrets/mysecret2
  uid: 3d7db9bb-5fdc-40db-8cf4-f59624f9ec42
type: Opaque

to sum up:

  • In the process of creating resources, you can directly use commands to create, or you can use yaml files. Although the creation of yaml files is relatively troublesome, it will do the basic state when we create the corresponding resources. One save.

  • The secret resource can also be correctly referenced by using environment variables, but it is not the same as the Volume method, and the reference data will not be dynamically updated. But volume supports dynamic data updates.

二、ConfigMap

  • The configmap is to decouple the configuration file from the mirror and make the mirror portable and reproducible. Many applications read configuration information from configuration files, command line parameters, or environment variables. This configuration information needs to be decoupled from the docker image. You can't redo an image every time you modify a configuration, right? The ConfigMap API provides us with a mechanism to inject configuration information into the container. ConfigMap can be used to save a single attribute, or it can be used to save the entire configuration file or a JSON binary large object.
  • The ConfigMap API resource is used to store key-value pair configuration data. This data can be used in pods or used to store configuration data for system components like controllers. Although ConfigMap is similar to Secrets, ConfigMap handles strings that do not contain sensitive information more conveniently. Note: ConfigMaps are not a substitute for property configuration files. ConfigMaps is just a reference for multiple properties files. It can be understood as the /etc directory in the Linux system, a directory dedicated to storing configuration files. Here is an example, using ConfigMap configuration to create Kuberntes Volumes, each data item in the ConfigMap will become a new file

2.1 The way to create ConfigMap:

2.1.1 --from-literal

[root@master ~]# kubectl  create configmap mycondifmap1 --from-literal=user1=admin --from-literal=user2=root
configmap/mycondifmap1 created
[root@master ~]# kubectl  describe configmaps  mycondifmap1 
Name:         mycondifmap1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
user2:
----
root
user1:
----
admin
Events:  <none>

2.1.2 --from-file

[root@master ~]# echo admin > user1
[root@master ~]# echo root > user2
[root@master ~]# kubectl  create  configmap  myconfigmap2 --from-file=user1 --from-file=user2
configmap/myconfigmap2 created
[root@master ~]# kubectl  describe  configmaps  myconfigmap2 
Name:         myconfigmap2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
user2:
----
root

user1:
----
admin

Events:  <none>

2.1.3 --from-env-file

[root@master ~]# cat user.txt 
user1=admin
user2=root
[root@master ~]# kubectl  create  configmap  myconfigmap3 --from-env-file=user.txt 
configmap/myconfigmap3 created
[root@master ~]# kubectl  describe configmaps myconfigmap3 
Name:         myconfigmap3
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
user2:
----
root
user1:
----
admin
Events:  <none>

2.1.4 Create by yaml list

[root@master ~]# vim configmap.yaml

kind: ConfigMap
apiVersion: v1
metadata:
  name: myconfigmap4
data:
  user1:  admin
  user2:  root
[root@master ~]# kubectl  apply  -f  configmap.yaml 
configmap/myconfigmap4 created
[root@master ~]# kubectl  describe  configmaps  myconfigmap4

Name:         myconfigmap4
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {
    
    "apiVersion":"v1","data":{
    
    "user1":"admin","user2":"root"},"kind":"ConfigMap","metadata":{
    
    "annotations":{
    
    },"name":"myconfigmap4","namespac...

Data
====
user1:
----
admin
user2:
----
root
Events:  <none>

2.2 Use of ConfigMap resources

2.1.1 Volume

[root@master ~]# vim volume.yaml 
 
kind: Pod
apiVersion: v1
metadata:
  name: pod
spec:
  volumes:
  - name: test-volume
    configMap:
      name: mycondifmap1
  containers:
  - name: pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 30000
    volumeMounts:
    - name: test-volume
      mountPath:  "/tmp/volume"
      readOnly: true

[root@master ~]# kubectl  apply  -f  volume.yaml 
pod/pod created

View data

pod    1/1     Running   0          37s
[root@master ~]# kubectl  exec  pod  cat /tmp/volume/user1
admin
[root@master ~]# kubectl  exec  pod  cat /tmp/volume/user2
root

If you change the value of user1 corresponding to myconfigmap1, you will see that the corresponding value in the Pod will also be dynamically updated

[root@master ~]# kubectl  edit  configmaps mycondifmap1 
......
apiVersion: v1
data:
  user1: test
......
configmap/mycondifmap1 edited

[root@master ~]# kubectl  exec  pod  cat /tmp/volume/user1
test

2.2.2 Environment variables

[root@master ~]# vim configmap-bianliang.yaml

kind: Pod
apiVersion: v1
metadata:
  name: pod
spec:
  containers:
  - name: pod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 30000
    env:
      - name: USER_1
        valueFrom:
          configMapKeyRef:
            name: mycondifmap1
            key:  user1
      - name: USER_2
        valueFrom:
          configMapKeyRef:
            name: mycondifmap1
            key:  user2
            
[root@master ~]# kubectl  apply  -f  configmap-bianliang.yaml 
pod/pod created

View the corresponding data

[root@master ~]# kubectl  get pod
NAME   READY   STATUS    RESTARTS   AGE
pod    1/1     Running   0          9m6s
[root@master ~]# kubectl  exec  -it pod sh
/ # echo $USER_1
test
/ # echo $USER_2
root

Change the data source to see if the data will change

[root@master ~]# kubectl  edit  configmaps mycondifmap1 
......
apiVersion: v1
data:
  user1: admin
......
configmap/mycondifmap1 edited

[root@master ~]# kubectl  exec  -it pod sh
/ # echo $USER_1
test
/ # echo $USER_1
test
/ # 
/ # echo $USER_1
test
/ # echo $USER_2
root

to sum up:

After the ConfigMap is created by volume, it supports dynamic update, while the ConfigMap created by variables does not support dynamic update.

Guess you like

Origin blog.csdn.net/weixin_45191791/article/details/109956724