k8s之configmap与secret

k8s之configmap与secret

容器化应用配置方式

​ configMap,secret是k8s上2种特殊的存储卷,功能:被pod挂载,为pod提供非敏感和敏感的配置信息或文件;

​ 针对容器化容器,其配置方式通常有以下5种方式:

  1. 命令行传参:启动容器时,docker run image-name [command...] [args..]
  2. 环境变量传参:启动容器时,docker run xx -e var1=v1 -e var2=v2 ...
  3. 配置文件打入镜像:不像命令行和环境变量传参,直接传递较为简单的kv类型的配置信息,可以传递整个文件
  4. 借助普通存储卷挂在节点上预先放置的配置文件:可传递整个文件,但考虑到pod的动态性,需要集群中每个节点都放置一份配置文件显然不够灵活
  5. k8s的特殊卷:configmap和secret:借助这2种存储卷,可以将配置文件,证书,密钥等敏感信息都创建为标准k8s资源,从而在pod中引用,以存储卷方式引用,或envFrom字段以环境变量方式引入

命令行参数配置应用

docker:entrypoint和cmd

​ 制作docker镜像时,entrypoint分别代表,启动为容器时要运行的程序和其参数;

k8s:command和args

​ 定义pod中containers字段时,其中command和args分别代表,传递给容器的,要其运行的程序和其参数;可覆盖镜像中写好的程序和程序参数

覆盖关系图示:

  • pod中的command和args都定义时,分别覆盖镜像中的entrypoint和cmd
  • pod中只定义了commnd时,覆盖镜像中的entrypoint和cmd,只运行定义的command
  • pod中只定义了args时,将覆盖镜像中的cmd参数,args作为entrypoint的参数
  • pod中的command和args都未定义时,采用镜像中默认的entrypoint和cmd

image-20201119154855731

示例

pod中定义了command和args

apiVersion: v1
kind: Pod
metadata:
 name: pod1
spec:
 containers:
 - name: b1
   image: busybox
   command: 
   - httpd
   args: 
   - -f

httpd -f 覆盖了busybox镜像中定义的/bin/sh -c 

[root@client pod]# kubectl exec pod1 -c b1 -i -t -- /bin/sh -il
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 httpd -f
   35 root      0:00 /bin/sh -il
   39 root      0:00 ps -ef

pod中定义了args

apiVersion: v1
kind: Pod
metadata:
 name: pod1
spec:
 containers:
 - name: b1
   image: busybox
   args: 
   - httpd
   - -f

传递的args,作为busybox镜像的entrypoint程序的参数 /bin/sh -c httpd -f
相当于在shell窗口,执行了httpd -f命令,效果和上面的pod相当

[root@client pod]# kubectl exec pod2 -i -t -- /bin/sh -il
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 httpd -f
    5 root      0:00 /bin/sh -il
    9 root      0:00 ps -ef

环境变量配置应用

​ 定义pod中容器时,可以通过env字段,向其中传递环境变量,环境变量可以被直接引用,也可以通过entrypoint脚本,将其传递到应用的配置文件中,尤其适合云原生应用在容器中执行;

语法:

[root@client pod]# kubectl explain pods.spec.containers.env.
KIND:     Pod
VERSION:  v1

   name	<string> -required-
     Name of the environment variable. Must be a C_IDENTIFIER.

   value	<string>
     Variable references $(VAR_NAME) are expanded using the previous defined
     environment variables in the container and any service environment
     variables. If a variable cannot be resolved, the reference in the input
     string will be unchanged. The $(VAR_NAME) syntax can be escaped with a
     double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
     regardless of whether the variable exists or not. Defaults to "".

   valueFrom	<Object>
     Source for the environment variable's value. Cannot be used if value is not
     empty.

env的值,是对象,列表;
变量名,必选
value valuefrom,二选一
value 直接给定变量值,
valuefrom是选择从别处引如变量,共四类:configmap,secret,或pod的属性信息,或资源配额的上限和下限,见下方
---
[root@client pod]# kubectl explain pods.spec.containers.env.valueFrom.

FIELDS:
   configMapKeyRef	<Object>
     Selects a key of a ConfigMap.

   fieldRef	<Object>
     Selects a field of the pod: supports metadata.name, metadata.namespace,
     metadata.labels, metadata.annotations, spec.nodeName,
     spec.serviceAccountName, status.hostIP, status.podIP.

   resourceFieldRef	<Object>
     Selects a resource of the container: only resources limits and requests
     (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
     requests.memory and requests.ephemeral-storage) are currently supported.

   secretKeyRef	<Object>
     Selects a key of a secret in the pod's namespace

1、定义pod文件

​ 采用直接给定变量值,和引用元数据信息变量2种方式;

[root@client pod]# cat pod-env.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: pod-env
spec:
 containers:
 - name: busybox
   image: busybox
   command: 
   - httpd
   args:
   - -f
   env:
   - name: k1
     value: v1
   - name: node_name
     valueFrom:
      fieldRef:
       fieldPath: spec.nodeName
   - name: node_ip
     valueFrom:
      fieldRef:
       fieldPath: status.hostIP
   - name: node_ns
     valueFrom:
      fieldRef:
       fieldPath: metadata.namespace

2、打印pod中容器中的环境变量

[root@client pod]# kubectl exec pod-env printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=pod-env
k1=v1
node_name=node2
node_ip=192.168.80.107
node_ns=default
...

3、环境变量传参的缺陷:

​ 是在运行为pod后,根据yaml中定义,将环境变量注入到容器中,即,容器运行中,环境变量无法动态修改;但configmap可以;

configmap配置应用

configmap优势

​ 对于微服务化的分布式应用,大量的应用模块需要频繁的配置,传统的配置文件方式不适用,配置和应用代码耦合度高,改配置有时会修改代码,例如;多套环境下,就需要修改代码引用不同的配置文件,

​ configmap和secret解耦了配置和应用代码,允许在多套环境中,定义同名的configmap资源,但其内部内容不同,从而pod应用中利用configmap名称调用的configmap,无需做任何修改;

​ configmap对象,把配置数据,以键值对方式存储其中,pod或其他k8s组件,可以以环境变量、存储卷挂载,2种方式引用;

configmap创建

语法:

kubectl create confimap CONFIG_NAME DADA_SOURCE

data_source是指将要存储到configmap中的数据源,存储形式为键值对,类型有:1、命令行给定kv对,2、指定包含数据的文件,3、指定包含数据文件的目录

[root@client ~]# kubectl create configmap -h
Create a configmap based on a file, directory, or specified literal value. 

A single configmap may package one or more key/value pairs. 

When creating a configmap based on a file, the key will default to the basename of the file, and the value will default
to the file content.  If the basename is an invalid key, you may specify an alternate key. 

When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be
packaged into the configmap.  Any directory entries except regular files are ignored (e.g. subdirectories, symlinks,
devices, pipes, etc).

Aliases:
configmap, cm
...

基于命令创建

命令行方式,适合量比较少的kv数据

  # Create a new configmap named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

1,创建

1
2
3
[root@client ~]# kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
configmap/my-config created

2,查看

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@client ~]# kubectl get cm
NAME        DATA   AGE
my-config   2      6s
[root@client ~]# kubectl get cm -o yaml
apiVersion: v1
items:
- apiVersion: v1
  data:
    key1: config1
    key2: config2
  kind: ConfigMap
  metadata:
    creationTimestamp: 2020-11-20T02:31:04Z
    name: my-config
    namespace: default
    resourceVersion: "428496"
    selfLink: /api/v1/namespaces/default/configmaps/my-config
    uid: 6fea902e-2ad8-11eb-8f71-000c292d5d7c
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

基于文件创建

基于文件创建的方式,configmap中的key默认为文件路径的basename,也可以手动指定其他的值做key,其值就是整个文件的内容,使用于整个配置文件,如nginx.conf

eg:

  # Create a new configmap named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar

1、创建

[root@client ~]# kubectl create configmap cm1 --from-file=/etc/fstab 
configmap/cm1 created

2、查看

 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
[root@client ~]# kubectl get cm
NAME        DATA   AGE
cm1         1      8s
my-config   2      15m
[root@client ~]# kubectl get cm cm1 -o yaml
apiVersion: v1
data:
  fstab: |2

    #
    # /etc/fstab
    # Created by anaconda on Sat Aug  8 11:58:02 2020
    #
    # Accessible filesystems, by reference, are maintained under '/dev/disk'
    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
    #
    UUID=046ebf1d-861c-42bb-a48f-9641dfc9afec /                       xfs     defaults        0 0
    UUID=686c38ff-6d1b-40cd-9baa-9860097e81ec /boot                   xfs     defaults        0 0
kind: ConfigMap
metadata:
  creationTimestamp: 2020-11-20T02:46:50Z
  name: cm1
  namespace: default
  resourceVersion: "429926"
  selfLink: /api/v1/namespaces/default/configmaps/cm1
  uid: a4091ae0-2ada-11eb-8f71-000c292d5d7c

基于目录创建

​ 将所有配置文件放在一个目录,configmap还可以通过--from-file=/path/to/dir来指定一整个目录,一下子为其下包含所有文件,都创建为一个键值对;

​ 实际中,方便一次用一个configmap包含一批配置文件

eg:

 # Create a new configmap named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar

1、创建

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[root@client ~]# mkdir /cmdir/
[root@client ~]# echo 1.txt >> /cmdir/1.txt
[root@client ~]# echo 3.txt >> /cmdir/3.txt
[root@client ~]# echo 2.txt >> /cmdir/2.txt
[root@client ~]# ll /cmdir/
total 12
-rw-r--r-- 1 root root 6 Nov 20 10:54 1.txt
-rw-r--r-- 1 root root 6 Nov 20 10:55 2.txt
-rw-r--r-- 1 root root 6 Nov 20 10:55 3.txt


[root@client ~]#   kubectl create configmap cm2 --from-file=/cmdir/
configmap/cm2 created

2、查看

 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


[root@client ~]# kubectl get cm
NAME        DATA   AGE
cm1         1      9m39s
cm2         3      2s
my-config   2      25m

[root@client ~]# kubectl get cm cm2 -o yaml
apiVersion: v1
data:
  1.txt: |
        1.txt
  2.txt: |
        2.txt
  3.txt: |
        3.txt
kind: ConfigMap
metadata:
  creationTimestamp: 2020-11-20T02:56:27Z
  name: cm2
  namespace: default
  resourceVersion: "430797"
  selfLink: /api/v1/namespaces/default/configmaps/cm2
  uid: fb9a18b2-2adb-11eb-8f71-000c292d5d7c

使用清单创建

​ 使用清单创建,使用简单的kv类型数据,若数据源来自文件,或目录,倒不如命令行来的直接,为方便保存,可用命令行创建后,用get cmName -o yaml 输出为yaml文件,保存待用

[root@client cm]# kubectl get cm cm1 -o yaml > cm1.yaml

[root@client cm]# cat cm3.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: cm3
data:
 k3: v3
 k4: v4


[root@client cm]# kubectl get cm
NAME        DATA   AGE
cm1         1      30m
cm2         3      21m
cm3         2      3s
my-config   2      46m
[root@client cm]# kubectl get cm cm3 -o yaml
apiVersion: v1
data:
  k3: v3
  k4: v4
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"k3":"v3","k4":"v4"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"cm3","namespace":"default"}}
  creationTimestamp: 2020-11-20T03:17:33Z
  name: cm3
  namespace: default
  resourceVersion: "432712"
  selfLink: /api/v1/namespaces/default/configmaps/cm3
  uid: ee714da9-2ade-11eb-8f71-000c292d5d7c

configmap使用

​ configMpa在pod中使用方式:

There are four different ways that you can use a ConfigMap to configure a container inside a Pod:

Inside a container command and args
Environment variables for a container
Add a file in read-only volume, for the application to read
Write code to run inside the Pod that uses the Kubernetes API to read a ConfigMap
	第4种方式,支持动态更新configmap和跨ns引用configmap

​ configMap配置好后,被pod引用方式:1、通过环境变量pods.spec.containers.env.valueFrom.configMapKeyRef引用;2、通过卷挂载的方式引用;

向pod环境变量传递configmap键值对

定义cm,和pod

 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
[root@client cm]# cat pod-with-cm.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: cm-busybox
data:
 httpd_port: "8080"
 httpd_log_level: "-vv"
---
apiVersion: v1
kind: Pod
metadata:
 name: pod-with-cm
spec:
 containers:
 - name: b1
   image: busybox
   command: 
   - /bin/httpd
   args:
   - -f
   - -p
   - $(port)
   - $(log_level)
   env:
   - name: port
     valueFrom:
      configMapKeyRef:
       name: cm-busybox
       key: httpd_port
   - name: log_level
     valueFrom:
      configMapKeyRef:
       name: cm-busybox
       key: httpd_log_level
容器启动参数引用了环境变量;
pod中定义的环境变量,引用了cm-busybox这个cm中的key
cm-busybox中需事先定义好对应的key

查看,可以看到,变量已经被正常传递给pod的容器中进程

[root@client cm]# kubectl exec pod-with-cm -- ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -p 8080 -vv
    5 root      0:00 ps -ef

envfrom批量导入configmap中所有键

​ 采用configMapKeyRef一个个引用confimap中定义的键,针对大量键存在时,效率底下,因此可以用envFrom字段,在其中引用configmMapRef,一次导入configmap中所有的key,且可以导入多个configmap一次性,语法如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[root@client cm]# kubectl explain pods.spec.containers.envFrom.configMapRef
KIND:     Pod
VERSION:  v1

RESOURCE: configMapRef <Object>

DESCRIPTION:
     The ConfigMap to select from

     ConfigMapEnvSource selects a ConfigMap to populate the environment
     variables with. The contents of the target ConfigMap's Data field will
     represent the key-value pairs as environment variables.


1、编写yaml

root@client cm]# cat pod-with-cm.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: cm-busybox
data:
 httpd_port: "8080"
 httpd_log_level: "-vv"
---
apiVersion: v1
kind: Pod
metadata:
 name: pod-with-cm
spec:
 containers:
 - name: b1
   image: busybox
   command: 
   - /bin/httpd
   args:
   - -f
   - -p
   - $(httpd_port)
   - $(httpd_log_level)
   envFrom:
   - configMapRef:
      name: cm-busybox

2、查看容器中环境变量

^C[root@client cm]# kubectl exec pod-with-cm -- printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=pod-with-cm
httpd_log_level=-vv
httpd_port=8080

configmap以挂载卷使用

​ cm中不仅可以存储一般的kv类型的值,也可以存储整个文件的内容,适用于为pod中容器提供配置文件;其存储方式也是键值,键是文件名,值是整个文件内容;

使用步骤:

  1. 定义configmap,其中引用一个或多个配置文件,kubectl explain cm.data
  2. volumes字段引用上步定义好的cm名称, kubectl explain pods.spec.volumes
  3. 容器中引用上步定义好的volumes名称,kubectl explain pods.spec.containers.volumeMounts

1、挂载cm中所有文件

​ 创建3个文件,模拟3个nginx的虚拟主机的配置文件,默认情况下,引用的confimap中所有的文件都会被挂载到mountPath目录下;

[root@client cm]# mkdir /tmp/nginx_conf_dir/

[root@client cm]# echo host1.conf > /tmp/nginx_conf_dir/host1.conf
[root@client cm]# echo host2.conf > /tmp/nginx_conf_dir/host2.conf
[root@client cm]# echo host3.conf > /tmp/nginx_conf_dir/host3.conf

[root@client cm]# ll /tmp/nginx_conf_dir/
total 12
-rw-r--r-- 1 root root 11 Nov 22 12:09 host1.conf
-rw-r--r-- 1 root root 11 Nov 22 12:09 host2.conf
-rw-r--r-- 1 root root 11 Nov 22 12:09 host3.conf

示例yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@client cm]# cat ngx1.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: ngx1
spec:
 containers:
 - name: ngx1
   image: nginx:alpine
   volumeMounts:
   - name: nginx
     mountPath: /usr/share/nginx/html
 volumes:
 - name: nginx
   configMap:
    name: cm-nginx

查看容器中挂载的路径;
[root@client cm]# kubectl exec ngx1 -- ls /usr/share/nginx/html
host1.conf
host2.conf
host3.conf

2、指定挂载cm中部分文件

​ 可以利用pods.spec.volumes.configMap.item字段,只挂载cm中部分的文件到mountPath指定的路径下;

示例yaml:

 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
[root@client cm]# cat ngx1.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: ngx1
spec:
 containers:
 - name: ngx1
   image: nginx:alpine
   volumeMounts:
   - name: nginx
     mountPath: /usr/share/nginx/html
 volumes:
 - name: nginx
   configMap:
    name: cm-nginx
    items:
    - key: host1.conf
      mode: 0644
      path: host1.conf
    - key: host2.conf
      path: newhost2.conf
key指定引用cm中哪个键,即文件名
mode设置了文件权限,可选字段
path设置了挂载到容器中后,文件名叫什么,可与cm中原文件名保持一致,也可不一致


查看容器中挂载的路径;
[root@client cm]# kubectl exec ngx1 -- ls /usr/share/nginx/html
host1.conf
newhost2.conf

3、挂载cm文件时,不覆盖原镜像的文件路径下存在的文件

​ 有时需求会是,挂载cm中文件中时,不覆盖mountPath路径下原有文件,而是添加的方式

示例yaml:

 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
[root@client cm]# cat ngx1.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: ngx1
spec:
 containers:
 - name: ngx1
   image: nginx:alpine
   volumeMounts:
   - name: nginx
     mountPath: /usr/share/nginx/html/newhost1.conf
     subPath: host1.conf
   - name: nginx
     mountPath: /usr/share/nginx/html/newhost2.conf
     subPath: host2.conf
 volumes:
 - name: nginx
   configMap:
    name: cm-nginx
mountPath指定,cm中的文件,挂载到容器中后的文件名,要唯一
subPath指明cm中要挂载的key,即文件名,就不会默认覆盖原有文件

查看容器中挂载的路径;原有首页文件,和错误页面都还存在
[root@client cm]# kubectl exec ngx1 -- ls  /usr/share/nginx/html
50x.html
index.html
newhost1.conf
newhost2.conf

configmap的动态更新

步骤:

  1. 更新cm中数据
  2. 容器中进程,重载配置文件

更新cm:

[root@client cm]# kubectl edit cm cm-nginx
configmap/cm-nginx edited

更新了cm之后,还需要容器中进程,重装配置文件才可,如nginx需要nginx -s reload ,容器中若是不支持热重载配置文件的进程仍需要重新启动pod才可更新cm中数据;

采用subPath挂载的cm中文件不更新动态更新

​ 也非2级软链接方式

[root@client cm]# kubectl exec ngx1 -- ls -lA  /usr/share/nginx/html/
total 16
-rw-r--r--    1 root     root           494 Oct 27 15:48 50x.html
-rw-r--r--    0 root     root            20 Nov 22 05:40 host1.conf
-rw-r--r--    0 root     root            11 Nov 22 05:40 host2.conf
-rw-r--r--    1 root     root           612 Oct 27 15:48 index.html

默认挂载方式为2级链接方式,支持动态更新

​ 更新cm时,由..data指向一个新的时间点目录即实现了cm的更新,也即容器内文件更新;

[root@client cm]# kubectl exec ngx1 -- ls -lA  /usr/share/nginx/html/
total 0
drwxr-xr-x    2 root     root            60 Nov 22 05:51 ..2020_11_22_05_51_33.789268335
lrwxrwxrwx    1 root     root            31 Nov 22 05:51 ..data -> ..2020_11_22_05_51_33.789268335
lrwxrwxrwx    1 root     root            17 Nov 22 05:51 host1.conf -> ..data/host1.conf
lrwxrwxrwx    1 root     root            17 Nov 22 05:51 host2.conf -> ..data/host2.conf
lrwxrwxrwx    1 root     root            17 Nov 22 05:51 host3.conf -> ..data/host3.conf

configmap注意事项

  • cofigmap是名称空间级别资源,需要同一个ns内部的pod才可引用;

  • 以存储卷方式被引用的configmap需要先于pod被创建,同样被引用到的key都要事先创建;否则pod无法正常启动;

  • 以环境变量方式被引用的configmap无需先于pod被创建,pod仍可正常启动;

secret配置应用

secret概述

​ secret和configmap等同,只是secret是用来存储敏感数据,如密码,密钥,证书,令牌等;

​ secret也是以键值形式,存储数据,且仅仅分发到调用了secret资源的pod所在的节点的内存中,以base64编码,

用途:

  • 提供kubelet用于拉取私有仓库时的认证信息
  • pod中容器使用的私密信息存储
  • tls的证书和key

secret类型:

常用的3种:

[root@client cm]# 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
  保存tls证书和key的

完整类型:https://kubernetes.io/docs/concepts/configuration/secret/

Builtin Type Usage
Opaque arbitrary user-defined data
kubernetes.io/service-account-token service account token
kubernetes.io/dockercfg serialized ~/.dockercfg file
kubernetes.io/dockerconfigjson serialized ~/.docker/config.json file
kubernetes.io/basic-auth credentials for basic authentication
kubernetes.io/ssh-auth credentials for SSH authentication
kubernetes.io/tls data for a TLS client or server
bootstrap.kubernetes.io/token bootstrap token data

创建secret

命令式创建

1、命令行方式创建mysql用户密码

[root@client cm]# kubectl create secret generic auth-mysql --from-literal=user=root --from-literal=password=mysql
secret/auth-mysql created

[root@client cm]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
auth-mysql            Opaque                                2      23s
类型为generic/Opaque,编码为base64,

[root@client cm]# kubectl get secrets auth-mysql -o yaml
apiVersion: v1
data:
  password: bXlzcWw=
  user: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: 2020-11-22T06:14:52Z
  name: auth-mysql
  namespace: default
  resourceVersion: "477205"
  selfLink: /api/v1/namespaces/default/secrets/auth-mysql
  uid: 0851f310-2c8a-11eb-9e9a-000c292d5d7c
type: Opaque

[root@client cm]# echo bX1zcWw= | base64 -d
m}sql[root@client cm]# 
其中base64编码不能起到加密效果;

2、命令行方式从文件导入数据

[root@client cm]# kubectl create secret generic fil1 --from-file=s1=/etc/hosts
secret/fil1 created
[root@client cm]# kubectl get secret fil1 -o yaml
apiVersion: v1
data:
  s1: MTI3LjAuMC4xICAgbG9jYWxob3N0IGxvY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYWxkb21haW40Cjo6MSAgICAgICAgIGxvY2FsaG9zdCBsb2NhbGhvc3QubG9jYWxkb21haW4gbG9jYWxob3N0NiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNgoxOTIuMTY4LjgwLjEwMSBtYXN0ZXIKMTkyLjE2OC44MC4xMDYgbm9kZTEKMTkyLjE2OC44MC4xMDcgbm9kZTIKMTkyLjE2OC44MC4xMDggbm9kZTMKMTkyLjE2OC44MC4xMDIgY2xpZW50Cg==
kind: Secret
metadata:
  creationTimestamp: 2020-11-22T06:19:43Z
  name: fil1
  namespace: default
  resourceVersion: "477647"
  selfLink: /api/v1/namespaces/default/secrets/fil1
  uid: b5f59d68-2c8a-11eb-9e9a-000c292d5d7c
type: Opaqu

3、命令行方式,创建tls类型的secrets,存储key和证书

​ 生成证书,私钥

[root@client cm]# (umask 077;openssl genrsa -out nginx.key 2048)
Generating RSA private key, 2048 bit long modulus
.........................................................................................+++
............................+++
e is 65537 (0x10001)

[root@client cm]# openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=www.ilinux.io

​ 创建为tls类型的secrets

Usage:
  kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file
[--dry-run] [options]

Use "kubectl options" for a list of global command-line options (applies to all
commands).

[root@client cm]# kubectl create secret tls nginx-cert --cert=./nginx.crt --key=./nginx.key secret/nginx-cert created
[root@client cm]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
auth-mysql            Opaque                                2      12m
default-token-q6vpk   kubernetes.io/service-account-token   3      11d
fil1                  Opaque                                1      7m18s
nginx-cert            kubernetes.io/tls                     2      6s

注意:key会统计转为tls.key 和 tls.cert

清单式创建

​ 同样secret的清单式创建反到不如命令行来的简便,可以用命令创建后再输出为yaml文件,用于留档使用;

[root@client secret]# vim s1.yaml
[root@client secret]# cat s1.yaml 
apiVersion: v1
kind: Secret
metadata:
 name: s1
stringData:
 user: wang
 pass: linux
type: Opaque

stringdata和data不同的是,后者只能接收base64编码后的键值数据,用户还需手动编码一下;

[root@client secret]# kubectl apply -f s1.yaml 
secret/s1 created
[root@client secret]# kubectl get secret s1
NAME   TYPE     DATA   AGE
s1     Opaque   2      8s
[root@client secret]# kubectl get secret s1 -o yaml
apiVersion: v1
data:
  pass: bGludXg=
  user: d2FuZw==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"s1","namespace":"default"},"stringData":{"pass":"linux","user":"wang"},"type":"Opaque"}

secret以存储卷使用

​ secret可以以环境变量和存储卷方式注入到pod中,但环境变量方式存在安全隐患,如环境变量可能会打印到日志中,被子进程继承,因此推荐采用存储卷方式:

1、定义pod

[root@client secret]# vim nginx-with-ssl.yaml
[root@client secret]# kubectl apply -f nginx-with-ssl.yaml 
pod/nginx-with-ssl created

[root@client secret]# cat nginx-with-ssl.yaml 
apiVersion: v1
kind: Pod
metadata: 
 name: nginx-with-ssl
spec:
 containers:
 - name: n1
   image: nginx:alpine
   volumeMounts:
   - name: cert
     mountPath: /etc/nginx/conf.d/ssl/
 volumes:
 - name: cert
   secret:
    secretName: nginx-cert

2、查看

[root@client secret]# kubectl exec nginx-with-ssl -- ls /etc/nginx/conf.d/ssl
tls.crt
tls.key

3、之后,在configmap中引用该处的证书和私钥,即可完成nginx的https配置

imagePullSecret

提供私有仓库的认证信息方式:

  • 创建docker-registry类型的secret,在pod中引用;
  • 创建docker-registry类型的secret,然后在service-account引用,此后,所有以该service-account运行的pod都可通过私有仓库认证;

​ imagePullsecret字段引用了docker-registry类型的secret,用于拉取私有镜像仓库的镜像时提供的认证信息;

1、创建docker-registry类型的secret

[root@client secret]# kubectl create secret docker-registry reg1 --docker-username=wang --docker-password=linux --docker-email=wang@gmail.com
secret/reg1 created
[root@client secret]# kubectl get secret reg1 -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJ3YW5nIiwicGFzc3dvcmQiOiJsaW51eCIsImVtYWlsIjoid2FuZ0BnbWFpbC5jb20iLCJhdXRoIjoiZDJGdVp6cHNhVzUxZUE9PSJ9fX0=
kind: Secret
metadata:
  creationTimestamp: 2020-11-22T07:29:36Z
  name: reg1
  namespace: default
  resourceVersion: "483608"
  selfLink: /api/v1/namespaces/default/secrets/reg1
  uid: 78f26a73-2c94-11eb-9e9a-000c292d5d7c
type: kubernetes.io/dockerconfigjson
[root@client secret]# kubectl get secret reg1
NAME   TYPE                             DATA   AGE
reg1   kubernetes.io/dockerconfigjson   1      21s

2、在pod时引用即可

[root@client secret]# cat nginx-with-ssl.yaml 
apiVersion: v1
kind: Pod
metadata: 
 name: nginx-with-ssl
spec:
 imagePullSecrets:
 - name: reg1

小结:

  • 总结了配置容器应用的方式:
    • 定义pod时,定义启动为容器时命令行传参,command和args字段
    • 定义pod时,定义env环境变量字段,可有entrypoint脚本注入到配置文件中
    • 配置文件打入镜像
    • 将节点预先放置的配置文件以普通存储卷挂载给pod
    • configmap和secret
updatedupdated2020-12-012020-12-01
加载评论