当前位置:网站首页>Yyds dry goods inventory kubernetes management business configuration methods? (08)

Yyds dry goods inventory kubernetes management business configuration methods? (08)

2022-07-05 01:04:00 wzlinux

Learn from the previous chapters , We're right Kubernetes Medium Pod And some business loads . You can use the examples provided in the course , Try to practice in the cluster by yourself .

In use , We often need to be aware of Pod Do some configuration management , For example, how to use parameter configuration files , How to save and transfer sensitive data , wait . Some people might think , Why not put these configurations ( Not limited to parameters 、 The configuration file 、 Key, etc ) Package it into the image ? At first glance to , It seems a little feasible , But that's how it works “ Indifference to ” Too much .

  • Some unchanged configurations can be packaged into the image , What about the variable configuration ?
  • Information leakage , It is easy to cause security risks , Especially some sensitive information , such as password、 Secret key, etc .
  • After each configuration update , All need to be repackaged , Upgrade apps . Too many mirrored versions , It also brings a great burden to image management and image center storage .
  • Customization is too serious , Poor scalability , And it is not easy to reuse .

So a best practice here is to decouple the configuration information from the container image , With “ The same should change ”. stay Kubernetes in , Generally speaking, there are ConfigMap and Secret Two kinds of objects , It can be used for configuration management .

ConfigMap

First of all, let's talk about ConfigMap This object , It is mainly used to save some non sensitive data , Can be used as an environment variable 、 Command line parameters or mount to the storage volume .

#yyds Dry inventory # Kubernetes How to manage business configuration ?(08)_docker

ConfigMap Store information through key value pairs , It's a namespace Level of resources . stay kubectl When using , We can abbreviate it to cm.

Let's take a look at two ConfigMap Of API Definition :

$ cat cm-demo-mix.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-demo-mix #  Object name 
  namespace: demo #  In the namespace 
data: #  This is different from other objects , Other objects here are spec
  #  Each key is mapped to a simple value 
  player_initial_lives: "3" #  Note that the value here is numeric , Must be represented by a string 
  ui_properties_file_name: "user-interface.properties"
  #  You can also save multiple lines of text 
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
$ cat cm-demo-all-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-demo-all-env
  namespace: demo
data:
  SPECIAL_LEVEL: very
  SPECIAL_TYPE: charm

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

so , We go through ConfigMap It can store simple key value pairs , It can also store multiple lines of text .

Now let's create these two ConfigMap:

$ kubectl create -f cm-demo-mix.yaml
configmap/cm-demo-mix created
$ kubectl create -f cm-demo-all-env.yaml
configmap/cm-demo-all-env created

     
  • 1.
  • 2.
  • 3.
  • 4.

establish ConfigMap, You can also pass kubectl create cm be based on   Catalog   file perhaps   Face value To create , Please refer to this for details   Official documents .

Once created , We can view the created objects in the following ways .

$ kubectl get cm -n demo
NAME              DATA   AGE
cm-demo-all-env   2      30s
cm-demo-mix       4      2s
$ kubectl describe cm cm-demo-all-env -n demo
Name:         cm-demo-all-env
Namespace:    demo
Labels:       <none>
Annotations:  <none>

Data
====
SPECIAL_LEVEL:
----
very
SPECIAL_TYPE:
----
charm
Events:  <none>
$ kubectl describe cm cm-demo-mix -n demo
Name:         cm-demo-mix
Namespace:    demo
Labels:       <none>
Annotations:  <none>

Data
====
user-interface.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true

game.properties:
----
enemy.types=aliens,monsters
player.maximum-lives=5

player_initial_lives:
----
3
ui_properties_file_name:
----
user-interface.properties
Events:  <none>

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

Now let's see how to communicate with Pod Use in combination . In use , There are several areas that need special attention :

  • Pod It has to be with ConfigMap In the same namespace below ;
  • Creating Pod Before , Please make sure ConfigMap Already exist , otherwise Pod Error will be reported when creating .
$ cat cm-demo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: cm-demo-pod
  namespace: demo
spec:
  containers:
    - name: demo
      image: busybox:1.28
      command:
        - "bin/sh"
        - "-c"
        - "echo PLAYER_INITIAL_LIVES=$PLAYER_INITIAL_LIVES && sleep 10000"
      env:
        #  Define environment variables 
        - name: PLAYER_INITIAL_LIVES #  Please note here and  ConfigMap  The key names in are different 
          valueFrom:
            configMapKeyRef:
              name: cm-demo-mix         #  This value comes from  ConfigMap
              key: player_initial_lives #  The key that needs to take value 
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: cm-demo-mix
              key: ui_properties_file_name
      envFrom:  #  Can be  configmap  All key value pairs in are injected into the container through environment variables 
        - configMapRef:
            name: cm-demo-all-env
      volumeMounts:
      - name: full-config #  Here is the following definition  volume  name 
        mountPath: "/config" #  The target path of the mount 
        readOnly: true
      - name: part-config
        mountPath: /etc/game/
        readOnly: true
  volumes: #  You can go to  Pod  Level setting volume , Then mount it to  Pod  Inside the container 
    - name: full-config #  This is a  volume  Name 
      configMap:
        name: cm-demo-mix #  Provide what you want to mount  ConfigMap  Name 
    - name: part-config
      configMap:
        name: cm-demo-mix
        items: #  We can also mount only part of the configuration 
        - key: game.properties
          path: properties

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

In the example above , It almost covers ConfigMap Several usage scenarios of :

  • Command line arguments ;
  • environment variable , You can inject only some variables , It can also be fully injected ;
  • Mount the file , It can be a single file , It can also be all key value pairs , Use each key value as the file name .

So let's create :

$ kubectl create -f cm-demo-pod.yaml
pod/cm-demo-pod created

     
  • 1.
  • 2.

Once created , We exec Look into the container :

$ kubectl exec -it cm-demo-pod -n demo sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
UI_PROPERTIES_FILE_NAME=user-interface.properties
HOSTNAME=cm-demo-pod
SHLVL=1
HOME=/root
SPECIAL_LEVEL=very
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
PLAYER_INITIAL_LIVES=3
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
SPECIAL_TYPE=charm
/ # ls /config/
game.properties            ui_properties_file_name
player_initial_lives       user-interface.properties
/ # ls -alh /config/
total 12
drwxrwxrwx    3 root     root        4.0K Aug 27 09:54 .
drwxr-xr-x    1 root     root        4.0K Aug 27 09:54 ..
drwxr-xr-x    2 root     root        4.0K Aug 27 09:54 ..2020_08_27_09_54_31.007551221
lrwxrwxrwx    1 root     root          31 Aug 27 09:54 ..data -> ..2020_08_27_09_54_31.007551221
lrwxrwxrwx    1 root     root          22 Aug 27 09:54 game.properties -> ..data/game.properties
lrwxrwxrwx    1 root     root          27 Aug 27 09:54 player_initial_lives -> ..data/player_initial_lives
lrwxrwxrwx    1 root     root          30 Aug 27 09:54 ui_properties_file_name -> ..data/ui_properties_file_name
lrwxrwxrwx    1 root     root          32 Aug 27 09:54 user-interface.properties -> ..data/user-interface.properties
/ # cat /config/game.properties
enemy.types=aliens,monsters
player.maximum-lives=5
/ # cat /etc/game/properties
enemy.types=aliens,monsters
player.maximum-lives=5

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.

You can see , Environment variables have been injected correctly , The corresponding files and directories are also mounted .
on top ls -alh /config/ after , We see that there are soft links in the mounted files , All point to ..data A file in a directory . The benefits of doing this , yes kubelet It will regularly check the attached ConfigMap Is it the latest , If it's updated , Is to create a new folder to store the latest content , And synchronously modify ..data Soft link to .

Generally, we only save some non sensitive data to ConfigMap in , Sensitive data should be saved to Secret It's in .

Secret

We can use Secret To save some sensitive data information , Like passwords 、 secret key 、token etc. . In use , Follow ConfigMap The usage is basically the same , Can be used as environment variables or file mount .

Kubernetes It also has some built-in Secret, It is mainly used to save access APIServer Of service account token, Let's talk about it later in the permissions section , Let's skip .

besides , It can also be used to save the identity information of the private image center , such kubelet You can pull the image .

notes : If you're using Docker, You can also run on the target machine in advance docker login yourprivateregistry.com To save your valid login information .Docker Generally, the key of the private warehouse will be saved in $HOME/.docker/config.json In file , Distribute the file to all nodes .

Let's see how to pass kubectl To create secret, From the command line help You can see kubectl Be able to create many types of Secret.

$ kubectl create secret  -h
 Create a secret using specified subcommand.
Available Commands:
   docker-registry Create a secret for use with a Docker registry
   generic         Create a secret from a local file, directory or literal value
   tls             Create a TLS secret
Usage:
   kubectl create secret [flags] [options]
Use "kubectl --help" for more information about a given command.
 Use "kubectl options" for a list of global command-line options (applies to all commands).

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

Let's create a Secret To save the identity information of accessing the private container warehouse :

$ kubectl create secret -n demo docker-registry regcred \
   --docker-server=yourprivateregistry.com \
   --docker-username=allen \
   --docker-password=mypassw0rd \
   --docker-email=[email protected]
 secret/regcred created
 $ kubectl get secret -n demo regcred
 NAME      TYPE                             DATA   AGE
 regcred   kubernetes.io/dockerconfigjson   1      28s

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Here we can see , created Secret The type is kubernetes.io/dockerconfigjson

$ kubectl describe secret -n demo regcred
Name:         regcred
Namespace:    demo
Labels:       <none>
Annotations:  <none>
Type:  kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson:  144 bytes

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

In order to prevent Secret The content in is leaked ,kubectl get and kubectl describe It will avoid directly displaying the content of the password . But we can get the complete Secret Object to further view its data :

$ kubectl get secret -n demo regcred -o yaml
apiVersion: v1
data: #  Follow  configmap  equally , This is used to save data information 
  .dockerconfigjson: eyJhdXRocyI6eyJ5b3VycHJpdmF0ZXJlZ2lzdHJ5LmNvbSI6eyJ1c2VybmFtZSI6ImFsbGVuIiwicGFzc3dvcmQiOiJteXBhc3N3MHJkIiwiZW1haWwiOiJhbGxlbkBleGFtcGxlLmNvbSIsImF1dGgiOiJZV3hzWlc0NmJYbHdZWE56ZHpCeVpBPT0ifX19
kind: Secret
metadata:
.........
  name: regcred
  namespace: demo
  resourceVersion: "1419452"
  selfLink: /api/v1/namespaces/demo/secrets/regcred
  uid: 6d34123e-4d79-406b-9556-409cfb4db2e7
type: kubernetes.io/dockerconfigjson

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Here we find .dockerconfigjson It's a piece of garbled code , We use it base64 Try decompression :

$ kubectl get secret regcred -n demo --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
{"auths":{"yourprivateregistry.com":{"username":"allen","password":"mypassw0rd","email":"[email protected]","auth":"YWxsZW46bXlwYXNzdzByZA=="}}}

     
  • 1.
  • 2.

This actually passed with us docker login After ~/.docker/config.json It's the same in .
thus , We found that Secret and ConfigMap The biggest difference in data storage .Secret The saved data is through base64 Encrypted data .

We usually use another kind more widely Opaque Type of Secret:

$ cat secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
  name: dev-db-secret
  namespace: demo
type: Opaque
data: #  The values here are all  base64  Encrypted 
  password: UyFCXCpkJHpEc2I9
  username: ZGV2dXNlcg==

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

Or we can use the following equivalent kubectl Command to create :

$ kubectl create secret generic dev-db-secret -n demo \
  --from-literal=username=devuser \
  --from-literal=password='S!B\*d$zDsb='

     
  • 1.
  • 2.
  • 3.

Or create objects through files , such as :

$ echo -n 'username=devuser' > ./db_secret.txt
$ echo -n 'password=S!B\*d$zDsb=' >> ./db_secret.txt
$ kubectl create secret generic dev-db-secret -n demo \
  --from-file=./db_secret.txt

     
  • 1.
  • 2.
  • 3.
  • 4.

Sometimes for convenience , You can also use stringData, In this way, you can avoid using it manually in advance base64 To encrypt .

$ cat secret-demo-stringdata.yaml
apiVersion: v1
kind: Secret
metadata:
  name: dev-db-secret
  namespace: demo
type: Opaque
stringData:
  password: devuser
  username: S!B\*d$zDsb=

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

And now we have Pod Use in Secret:

$ cat pod-secret.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
  namespace: demo
spec:
  containers:
    - name: demo-container
      image: busybox:1.28
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - secretRef:
          name: dev-db-secret
  restartPolicy: Never
$ kubectl create -f pod-secret.yaml
pod/secret-test-pod created

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

Once created , Let's take a look at :

$ kubectl get pod -n demo secret-test-pod
NAME              READY   STATUS      RESTARTS   AGE
secret-test-pod   0/1     Completed   0          14s
$ kubectl logs -f -n demo secret-test-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=secret-test-pod
SHLVL=1
username=devuser
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
password=S!B\*d$zDsb=
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/

     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

We can see the command in the log env Output , See environment variables username and password Has been injected correctly . Similarly , We can also put Secret As Volume Mount to Pod Inside .

Last

ConfigMap and Secret yes Kubernetes Common objects for saving configuration data , You can choose the right object to store data according to your needs . adopt Volume How to mount to Pod Internal ,kubelet Will be updated regularly . But inject into the container through environment variables , So you can't feel ConfigMap or Secret Content update for .

How to make Pod The business inside is aware of ConfigMap or Secret The change of , It is still a problem to be solved . But we still have some Workaround Of .

  • If the business supports reload Configuration , such as nginx -s reload, Can pass inotify Aware of file updates , Or directly and regularly reload( We can cooperate here readinessProbe Use it together ).
  • If our business does not have this ability , Considering the idea of immutable infrastructure , Can we use rolling upgrade ? you 're right , This is a very good way . There is currently an open source tool  Reloader, It is in this way , adopt watch ConfigMap and Secret, Once the object is found to be updated , It will automatically trigger right Deployment or StatefulSet Wait for workload objects to roll up . Specific usage , Refer to the documentation of the project .

For this question , In fact, the community has been discussing better solutions , We'll see .

Welcome to scan the code to pay attention to , For more information

#yyds Dry inventory # Kubernetes How to manage business configuration ?(08)_json_02

原网站

版权声明
本文为[wzlinux]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202141055326025.html