K8S configuration center configMap and Secret

In the production environment, we often encounter the need to modify the configuration file. The traditional modification method will not only affect the normal operation of the service, but also the operation steps are very cumbersome. To solve this problem, the kubernetes project introduced the ConfigMap function from version 1.2 to separate the application configuration information from the application. This method can not only realize the reuse of applications, but also realize more flexible functions through different configurations. When creating a container, users can package the application as a container image and inject configuration through environment variables or external mount files. ConfigMap & & secret is a configuration center for applications in k8s. It effectively solves the problem of application mounting and supports functions such as encryption and hot update. It can be said that it is a very useful function provided by k8s

1, configMap

1.1 configMap

The configuration center of pod is generally used to store configuration files (in plaintext)
For example, MySQL configuration files need to be mounted in Pod, and configMap is generally used

1.2 several ways to create configMap

Format:
kubectl create [storage volume] [storage volume name]

1.2.1 method 1: write specific files into configmap

# The current directory nginx Write yaml to configmap
root@k8s-master ~]# kubectl create configmap test --from-file=./nginx.yaml 
configmap/test created

# Viewing storage volumes
[root@k8s-master ~]# kubectl get configmaps 
NAME               DATA   AGE
test               1      10s

# View the details in the storage volume (you can view the contents specified above)
[root@k8s-master ~]# kubectl describe configmaps test
Name:         test
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.yaml:
----
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web

1.2.2 mode 2: write the directory into the configmap

[root@k8s-master ~]# kubectl create configmap  test1 --from-file=./k8spod/ 
configmap/test1 created

# Viewing test1 storage volumes
[root@k8s-master ~]# kubectl get configmaps 
NAME               DATA   AGE
test1              6      10s

# View the details of the storage volume (you can view the contents of the k8s directory specified above)
[root@k8s-master ~]# kubectl describe configmaps test1

1.2.3 method 3: write the specified content into the configmap

[root@k8s-master ~]# kubectl create configmap test3 --from-literal=MYSQL_ROOT_PASSWORD=123456 --from-literal=MYSQL_DATABASES=wordpress
configmap/test3 created
[root@k8s-master ~]# 
[root@k8s-master ~]# 
[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl describe configmaps test3
Name:         test3
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MYSQL_DATABASES:
----
wordpress
MYSQL_ROOT_PASSWORD:
----
123456
Events:  <none>

1.2.4 mode 4: using configuration list

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: test4
data:
   MYSQL_ROOT_PASSWORD: "123456"
   my.cnf: |         # |It is equivalent to the pipeline when executing the command, and it is equivalent to entering the following contents
     [mysqld]
       basedir=/usr/local/mysql
       datadir=/mysql_data
       port=3306
       socket=/usr/local/mysql/mysql.sock
       character-set-server=utf8.mb4
       log-error=/var/log/mysqld.log
# Application resources
root@k8s-master ~]# kubectl apply -f configmap.yaml 
configmap/test4 created

[root@k8s-master ~]# kubectl get configmaps 
NAME               DATA   AGE
kube-root-ca.crt   1      18d
test               1      15m
test1              6      10m
test3              2      6m46s
test4              2      7s

# View the details in the storage volume (you can view the contents added above)
[root@k8s-master ~]# kubectl describe configmaps test4
Name:         test4
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MYSQL_ROOT_PASSWORD:
----
123456
my.cnf:
----
[mysqld]
  basedir=/usr/local/mysql
  datadir=/mysql_data
  port=3306
  socket=/usr/local/mysql/mysql.sock
  character-set-server=utf8.mb4
  log-error=/var/log/mysqld.log

Events:  <none>

Mounting a storage volume will delete all files in the mounted directory, leaving only the mounted file

#Inventory storage volume resources
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          volumeMounts:
            - mountPath: /opt/    # Directory to mount to container
              name: mysqlcnf           # What is specified is the name of the storage volume (that is, the name of volumes)
      volumes:           # Defined storage volumes
        - name: mysqlcnf    # Defines the name of volumes
          configMap:     # Storage volume type
            name: test4   # The name of the created configmap and the name of the file inside the container (the same as the configmap storage volume name defined outside last time to achieve the effect of mounting)
            items:
              - key: my.cnf      # File name or variable name in configmap
                path: my.cnf     # In this case, the relative path to / conf in the container means the relative path to mount to / F
# Application resources
[root@k8s-master ~]# kubectl apply -f deployment-configmap.yaml 
deployment.apps/mysql created

# View the running status of pod
[root@k8s-master ~]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
mysql-54ff6465fb-wc9b9   1/1     Running   0          4s
[root@k8s-master ~]# 

# Verification: mounting a storage volume will delete all files in the mounted directory
[root@k8s-master ~]# kubectl exec -it mysql-54ff6465fb-wc9b9 -- bash
root@mysql-54ff6465fb-wc9b9:/# cd /opt/
root@mysql-54ff6465fb-wc9b9:/opt# ls
my.cnf
root@mysql-54ff6465fb-wc9b9:/opt# cat my.cnf 
[mysqld]
  basedir=/usr/local/mysql
  datadir=/mysql_data
  port=3306
  socket=/usr/local/mysql/mysql.sock
  character-set-server=utf8.mb4
  log-error=/var/log/mysqld.log

Verification: support hot update (can be said to be real-time update)

# Modify the contents of the mounted volume file
[root@k8s-master ~]## kubectl edit configmaps test04
[mysqld]
  basedir=/usr/local/mysql
  datadir=/mysql_data
  port=3306
  socket=/usr/local/mysql/mysql.sock
  character-set-server=utf8
  log-error=/var/log/mysqld.log
  
  server-id=12345   # Add this line

# Go inside the container (check the my.cnf file, you can see the increase of the file content, and you can verify the hot update)
[root@master-lm1 k8s]# kubectl exec -it mysql-79696f8d5c-xfrph -- bash
root@mysql-79696f8d5c-xfrph:/# cat /opt/my.cnf
[mysqld]
  basedir=/usr/local/mysql
  datadir=/mysql_data
  port=3306
  socket=/usr/local/mysql/mysql.sock
  character-set-server=utf8
  log-error=/var/log/mysqld.log
  server-id=12345

Another way of using configmap (specifying environment variables) is to load password variables directly from configmap

#Inventory storage volume resources
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          envFrom:                 # How to specify environment variables     
            - configMapRef:         # Define an item in the configMap as an internal environment variable
                name: test4        # Name of configMap
                optional: true        # Specifies whether a configMap must be defined
          volumeMounts:
            - mountPath: /opt/    # Directory to mount to container
              name: mysqlconf           # What is specified is the name of the storage volume (that is, the name of volumes)
      volumes:           # Defined storage volumes
        - name: mysqlconf    # Defines the name of volumes
          configMap:     # Storage volume type
            name: test4   # The name of the created configmap and the name of the file inside the container (the same as the configmap storage volume name defined outside last time to achieve the effect of mounting)
            items:
              - key: my.cnf      # File name or variable name in configmap
                path: my.cnf     # The relative path to mount configMap to the container (the so-called relative path refers to the relative path to specify the directory to mount the container, which means / opt / my. CNF in this case)
                
 #Application resources
[root@k8s-master ~]## kubectl apply -f configmap-deployment.yaml 

#View pod information
[root@k8s-master ~]## kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
discuz-cd966b5bc-zvcmc   1/1     Running   0          3h31m
mysql-5db8cd8bc5-w54nf   1/1     Running   0          11s

#Enter the inside of pod container
[root@k8s-master ~]## kubectl exec -it mysql-5db8cd8bc5-w54nf -- bash

# View environment variables
root@mysql-5db8cd8bc5-w54nf:/# printenv
MYSQL_ROOT_PASSWORD=123456

Once subPath is used, the file will not be overwritten, but the hot update function of configMap will be lost

#Inventory storage volume resources
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          envFrom:                 # How to specify environment variables     
            - configMapRef:         # Define an item in the configMap as an internal environment variable
                name: test4        # Name of configMap
                optional: true        # Specifies whether a configMap must be defined
          volumeMounts:
            - mountPath: /etc/mysql/conf.d/my.cnf    # The directory attached to the container, and the absolute path of the normal file (must be the absolute path of the file)
              name: mysqlconf           # What is specified is the name of the storage volume (that is, the name of volumes)
              subPath: my.cnf   # Specifies the relative path inside the container
      volumes:           # Defined storage volumes
        - name: mysqlconf     # Defines the name of volumes
          configMap:     # Storage volume type
            name: test4   # The name of the created configmap and the name of the file inside the container (the same as the configmap storage volume name defined outside last time to achieve the effect of mounting)
            items:
              - key: my.cnf      # File name or variable name in configmap
                path: my.cnf    
                
                
# Application resources
[root@k8s-master ~]# # kubectl apply -f configmap-deployment.yaml 
deployment.apps/mysql created

#View pod operation details
[root@k8s-master ~]# # kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
mysql-58d4bf5d86-klgrr   1/1     Running   0          10s


# Enter the inside of the pod container
[root@k8s-master ~]# # kubectl exec -it mysql-58d4bf5d86-klgrr  -- bash

# Check that the file is not overwritten (verification completed)
root@mysql-58d4bf5d86-klgrr:/#  ls /etc/mysql/conf.d
docker.cnf  my.cnf  mysql.cnf  mysqldump.cnf

2, Secret

In kubernetes, there is also an object very similar to configmap, called secret object, which is mainly used to store sensitive information, such as password, key, certificate and so on.
It is also called encrypted configuration center. All configuration files in Secret use base64 encrypted content
Secret encrypts the database password. From the outside, it is encrypted. From the inside of the container, it is decrypted (limited security, relatively safe)

① Service Account: it is used to access Kubbernetes, which is automatically created by Kubernetes and automatically mounted to / run / secrets / Kubernetes.com of pod IO / serviceaccount directory. It is mainly used to store certificates and tokens (for example, ~ /. ssh/id_rsa file)
② Opaque: Secret in base64 encoding format. It is mainly used to store user name, password and other data with high security
③ kubernetes.io/dockerconfigjson/ DockerLogin: mainly used to store the login information of docker warehouse
④ TLS: mainly used to store certificates (Nginx's certificate ` ` c)

[root@k8s-master ~]# echo -n "123456" | base64
MTIzNDU2
#Prepare resource allocation list
[root@k8s-master ~]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: test
data:
  MYSQL_ROOT_PASSWORD: MTIzNDU2 # Encrypted password

# Application resources
[root@k8s-master ~]# kubectl apply -f secret.yaml 
secret/test created

[root@k8s-master ~]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-czh6g   kubernetes.io/service-account-token   3      18d
test                  Opaque                                1      11s

# View storage volume details (password in byte format)
[root@k8s-master ~]# kubectl describe secrets test
Name:         test
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
MYSQL_ROOT_PASSWORD:  6 bytes

Use of secret
The first usage type (Opaque type) (how environment variables are defined)

# Prepare resource allocation list
[root@k8s-master ~]# vim secret-deployment.yaml

kind: Secret
apiVersion: v1
metadata:
  name: test
data:
  MYSQL_ROOT_PASSWORD: MTIzNDU2   # The encrypted password is specified here
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: secret
spec:
  selector:
    matchLabels:
      app: secret
  template:
    metadata:
      labels:
        app: secret
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          envFrom:                  # Specify environment variables
            - secretRef:           # Define an item in secret as an internal environment variable
                name: test          # Name of secret
                optional: true      # Specifies whether it must be defined
                
# Application resources
[root@k8s-master ~]#  kubectl apply -f secret-deployment.yaml 
secret/test unchanged

# View pod operation details
[root@k8s-master ~]#  kubectl get pods
secret-54c5965b4d-r827x   1/1     Running   0          9s

# Enter the inside of pod container
[root@k8s-master ~]#  kubectl exec -it secret-54c5965b4d-r827x -- bash

# View the environment variable (which contains the password of the database)
root@secret-54c5965b4d-r827x:/# printenv
MYSQL_ROOT_PASSWORD=123456

The second method: (the password can be used as a storage volume to mount files)

# Prepare resource allocation list
[root@master-lm1 k8s]# vim secret-deployment.yaml 
kind: Secret
apiVersion: v1
metadata:
  name: test
data:
  MYSQL_ROOT_PASSWORD: MTIzNDU2   # The encrypted password is specified here
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: secret
spec:
  selector:
    matchLabels:
      app: secret
  template:
    metadata:
      labels:
        app: secret
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          envFrom:
            - secretRef:
                name: test
                optional: true
          volumeMounts:           # Mount information is defined below
            - mountPath: /opt/     # The directory that needs to be mounted to the container
              name: test     # This name is the name of the following storage volume, not the name of secretName
      volumes:               # Defined storage volumes
        - name: test         # Defines the name of the storage volume
          secret:              # Specify secret storage volume
            secretName: test  # Define the name of secret
            optional: true    # Specifies whether it must be defined
      
      
 # Application resources
[root@k8s-master ~]#  kubectl apply -f secret-deployment.yaml 
secret/test created

# View pod operation details
[root@k8s-master ~]#  kubectl get pods
secret-8cb97c4fb-x555q   1/1     Running   0          13s

# Inside pods container
[root@k8s-master ~]#  kubectl exec -it secret-8cb97c4fb-x555q -- bash

# You can also view the password of the database
root@secret-8cb97c4fb-x555q:/# cd /opt
root@secret-8cb97c4fb-x555q:/opt# ls
MYSQL_ROOT_PASSWORD
root@secret-8cb97c4fb-x555q:/opt# cat MYSQL_ROOT_PASSWORD 
123456

Pull the image from the private harbor warehouse

1. From the docker login on the host master to the private warehouse, enter the user name and password, and / root /. Will be generated on the current node docker/config. JSON file

2. Create a secret

kubectl create secret docker-registry harbor  \
--namespace=default \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--docker-server=harbor.bertwu.online \
--docker-username=admin \
--docker-password=Harbor12345 

Where harbor is the created secrets name, which can be modified
– name space specifies the project namespace
– from file specifies the config. Of the host JSON path
– docker server fill in the warehouse address specified in step 1
– docker username specifies the user name
– docker password specifies the password
– docker email optional

3. Create a resource list

root@k8s-master ~]# cat tomcat.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
spec:
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      imagePullSecrets:
        - name: harbor # Specify a self created secret
      containers:
        - name: tomcat
          image: harbor.bertwu.online/beijing/tomcat:latest
          imagePullPolicy: IfNotPresent

4. Application resources

[root@k8s-master ~]# kubectl apply -f tomcat.yaml 
deployment.apps/tomcat created

#View resources
[root@k8s-master ~]# kubectl get pods
NAME                      READY   STATUS              RESTARTS   AGE
tomcat-799bd68685-ncbf5   0/1     ContainerCreating   0          5s
[root@k8s-master ~]# kubectl get pods
NAME                      READY   STATUS              RESTARTS   AGE
tomcat-799bd68685-ncbf5   0/1     ContainerCreating   0          15s
[root@k8s-master ~]# kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
tomcat-799bd68685-ncbf5   1/1     Running   0          88s

Service Account type

Service Account Used to access Kubernetes API,from Kubernetes Automatically created and automatically mounted to Pod of/run/secrets/kubernetes.io/serviceaccount In the directory.

# The directory where the certificate is stored in the container
/run/secrets/kubernetes.io/serviceaccount

# View help information for the secret storage volume
[root@master-lm1 k8s]# kubectl create secret -h

Keywords: Operation & Maintenance Docker Kubernetes

Added by terandle on Mon, 03 Jan 2022 01:34:47 +0200