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.