抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Kubernetes 配置存储

image-20220525094307190

概述

K8s提供了多种外部数据注入容器的方式,今天我们主要学习环境变量、ConfigMap以及Secret的使用和配置

配置环境变量

我们可以通过配置清单中的 envenvFrom(来自外部配置) 字段来设置环境变量。

​ 对一个容器添加环境变量可以在容器创建时通过-e ENV=name方式加载,而k8s在创建 Pod 时,也提供了其下容器环境变量配置的能力

配置示例

我们可以通过配置清单中的 envenvFrom(来自外部配置) 字段来设置环境变量

创建配置清单
1
busybox-deployment.yml
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
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox-deployment
spec:
selector:
matchLabels:
app: busybox
replicas: 1
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox:latest
resources:
limits:
memory: 20Mi
env:
- name: DEMO_VERSION
value: demov1
- name: DEMO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: DEMO_CONT_MEM
valueFrom:
resourceFieldRef:
containerName: busybox
resource: limits.memory
command: ['top']
参数解释

在清单中我们配置了三个环境变量

  • DEMO_VERSION:直接添加变量值demov1
  • DEMO_POD_NAME:结合valueFrom中fieldRef获取pod名称字段metadata.name
  • DEMO_CONT_MEM:结合valueFrom中resourceFieldRef获取容器资源字段limits.memory

什么是ConfigMap

ConfigMap是一种API对象,用来将非加密数据保存到键值对中,可以用作环境变量、命令行参数或者存储卷中的配置文件

​ 一个重要的需求就是应用的配置管理敏感信息的存储和使用(如:密码、Token 等)容器运行资源的配置安全管控身份认证等等

​ 对于应用的可变配置在 Kubernetes 中是通过一个 ConfigMap 资源对象来实现的,我们知道许多应用经常会有从配置文件、命令行参数或者环境变量中读取一些配置信息的需求,这些配置信息我们肯定不会直接写死到应用程序中去的,比如你一个应用连接一个 redis 服务,下一次想更换一个了的,还得重新去修改代码,重新制作一个镜像,这肯定是不可取的,而 ConfigMap 就给我们提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,还可以用来保存整个配置文件,比如我们可以用来配置一个 redis 服务的访问地址,也可以用来保存整个 redis 的配置文件。

ConfigMap的作用

​ ConfigMap可以将环境变量配置信息和容器镜像解耦,便于应用配置的修改。如果需要存储加密信息时可以使用Secret对象。

​ ConfigMap组件可以实现应用和配置分离,避免因为修改配置项而重新构建镜像,ConfigMap 用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件

和配置中心的区别

ConfigMap是没有apollo,nacos等配置中心强大的,但是这些注册中心是需要应用程序去做一个对接的而ConfigMap就是,你把配置写给我,我给你注入进去就可以了,如果你是volume的话,我给你挂载进去就可以了

​ 当然,我们是可以通过一些额外的手段可以做到,即使你的程序不支持热更新,我们也可以让它做一个reload操作的,是可以做到的;

​ 像redeis,mysql这些配置,只要你应用层面和apollo/nacos对接做了配置的话,那么 在apollo/nacos后台直接改个配置,这边就直接下发下去,就直接生效了。

​ 这个configmap可能更多的还是在一个简单的配置方面,它和你的应用代码的耦合度就没那么高。但是你想利用configmap去做apollo/nacos这样的一个事情,应该是可以做到的。 就是你想通过configmmap去实现一个,去开发一个类似于apollo这样的一个配置中心,应该是可以做到的。

如何使用

​ 只有通过 Kubernetes API 创建的 Pod 才能使用 ConfigMap,其他方式创建的(比如静态 Pod)不能使用;ConfigMap 文件大小限制为 1MB(ETCD 的要求

什么是Secret

一般情况下 ConfigMap 是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用 ConfigMap 就非常不妥了,因为 ConfigMap 是明文存储的,这个时候我们就需要用到另外一个资源对象了

Secret用来保存敏感信息,例如密码、OAuth 令牌和 ssh key 等等将这些信息放在 Secret 中比放在 Pod 的定义中或者 Docker 镜像中要更加安全和灵活

Secret 类型

Secret 主要使用的有以下几种类型

  • Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过 base64 –decode 解码得到原始数据,所有加密性很弱。
  • kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息,~/.docker/config.json 文件的序列化形式
  • kubernetes.io/service-account-token:用于 ServiceAccount, ServiceAccount 创建时 Kubernetes 会默认创建一个对应的 Secret 对象,Pod 如果使用了 ServiceAccount,对应的 Secret 会自动挂载到 Pod 目录 /run/secrets/kubernetes.io/serviceaccount 中。
  • kubernetes.io/ssh-auth:用于 SSH 身份认证的凭据
  • kubernetes.io/basic-auth:用于基本身份认证的凭据
  • bootstrap.kubernetes.io/token:用于节点接入集群的校验的 Secret

ConfigMap使用

创建ConfigMap

通过资源清单创建

ConfigMap 资源对象使用 key-value 形式的键值对来配置数据,这些数据可以在 Pod 里面使用,

创建资源清单
1
vi cm-demo.yaml

其中配置数据在 data 属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-demo
namespace: default
data:
data.name: admin
data.passworld: qwert
config: |
property.1=value-1
property.2=value-2
property.3=value-3
应用配置

我们可以执行apply应用配置

1
2
kubectl apply -f cm-demo.yaml
kubectl get cm -o wide

image-20220608162919670

查看配置

可以通过describe命令进行查看配置

1
kubectl describe cm cm-demo

image-20220609171629706

指定目录创建

们就可以使用 from-file 关键字来创建包含这个目录下面所有配置文件的 ConfigMap

创建测试文件

比如我们创建 /tmp/config/cm的目录,该目录下面包含一些配置文件,redis 和 mysql 的连接信息

1
2
3
4
5
6
mkdir -p /tmp/config/cm
echo host=127.0.0.1 > /tmp/config/cm/redis.conf
echo port=6379 >> /tmp/config/cm/redis.conf
echo host=127.0.0.1 > /tmp/config/cm/mysql.conf
echo port=3306 >> /tmp/config/cm/mysql.conf
ll /tmp/config/cm

image-20220608163009683

创建ConfigMap

其中 from-file 参数指定在该目录下面的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容。

1
2
kubectl create cm  cm-demo1 --from-file=/tmp/config/cm/
kubectl get cm -o wide

image-20220608163157630

查看配置
1
kubectl describe cm cm-demo1

我们可以看到两个 key 是 testcm 目录下面的文件名称,对应的 value 值就是文件内容。

image-20220608163451262

查看完整配置

如果文件里面的配置信息很大的话,describe 的时候可能不会显示对应的值,要查看完整的键值,可以使用如下命令:

1
kubectl get cm cm-demo1 -oyaml

image-20220608164546944

单个文件创建

除了通过文件目录进行创建,我们也可以使用指定的文件进行创建 ConfigMap

创建ConfigMap

我们以上面的配置文件为例,我们创建一个 redis 的配置的一个单独 ConfigMap 对象

1
2
kubectl create cm cm-demo2 --from-file=/tmp/config/cm/redis.conf
kubectl get cm -o wide

image-20220608165032970

查看配置
1
kubectl describe cm cm-demo2

们可以看到一个关联 redis.conf 文件配置信息的 ConfigMap 对象创建成功了

image-20220608165336167

多个文件创建
创建ConfigMap

--from-file 这个参数可以使用多次,可以同时指定多个配置文件创建

1
2
kubectl create cm cm-demo3 --from-file=/tmp/config/cm/redis.conf --from-file=/tmp/config/cm/mysql.conf 
kubectl get cm -o wide

image-20220608165632330

查看配置
1
kubectl describe cm cm-demo3

比如我们这里使用两次分别指定 redis.conf 和 mysql.conf 文件,就和直接指定整个目录是一样的效果了

image-20220608165727795

通过字符串创建

我们可以看到我们还可以直接使用字符串进行创建,过 --from-literal 参数传递配置信息,同样的,这个参数可以使用多次

创建ConfigMap

一般数据较小的话,可以直接在资源配置清单里写一下,数据量比较大的话,就可以写到文件里进行创建使用

1
2
kubectl applay configmap cm-demo4 --from-literal=db.host=localhost --from-literal=db.port=3306
kubectl get cm -o wide

image-20220608165959840

使用ConfigMap

我们创建了ConfigMap就是为了使用,下面我们来看下如何使用

使用方式

ConfigMap 这些配置数据可以通过很多种方式在 Pod 里使用,主要有以下几种方式:

  • 设置环境变量的值
  • 在容器里设置命令行参数
  • 在数据卷里面挂载配置文件
用于环境变量

Configmap 用于配置环境变量的好处是可以将环境配置信息和容器镜像解耦,便于应用配置的修改。

创建资源清单

们使用 ConfigMap 来填充我们的环境变量,如下所示的 Pod 资源对象

1
vi configmap1-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Pod
metadata:
name: configmap1-pod
spec:
containers:
- name: configmap1-pod
image: busybox
command: [ "/bin/sh", "-c", "env" ] #打印环境信息
env:
- name: DB_HOST #指定环境变量名称
valueFrom:
configMapKeyRef: #这个是引用的意思
name: cm-demo #引用cm-demo的configMap
key: db.host #注意:这个db.host仅仅只是cm-demo1这个ConnfigMap里的Key.
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo4
key: db.port
envFrom:
- configMapRef:
name: cm-demo1
应用配置

我们现在可以直接应用配置

1
2
kubectl apply -f configmap1-pod.yaml
kubectl get pod -o wide

这里可以先看下当前pod的状态,虽然后面会处于报错状态,但是是正常现象,因为pod执行完就退出了

image-20220609101936835

查看日志

因为我们的容器启动就是为了打印环境信息,现在我们来看一下打印的日志

1
kubectl logs configmap1-pod

我们可以看到 DB_HOST 和 DB_PORT 都已经正常输出了,另外的环境变量是因为我们这里直接把 cm-demo1 给注入进来了,所以把他们的整个键值给输出出来了,这也是符合预期的

image-20220609102009219

用户命令行参数

另外我们也可以使用 ConfigMap来设置命令行参数,ConfigMap 也可以被用来设置容器中的命令或者参数值

创建资源清单
1
vi configmap2-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: configmap2
spec:
containers:
- name: configmap2
image: busybox
command: [ "/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)" ] #打印命令行参数
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: cm-demo4
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo4
key: db.port
应用配置
1
kubectl apply -f configmap2-pod.yaml

image-20220609102323371

查看日志
1
kubectl logs configmap2

我们看到已经把我们configmap中配置的环境信息打印出来了

image-20220609102433551

用于数据卷挂载

通过数据卷使用,在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容

创建资源清单
1
vi configmap3-pod.yaml

在这里我们打印了挂载目录的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: configmap3
spec:
volumes:
- name: config-volume
configMap:
name: cm-demo2
containers:
- name: testcm3
image: busybox
command: [ "/bin/sh", "-c", "cat /etc/config/redis.conf" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config

这里使用了cm-demo2的configmap,我们先来查看以下内容

1
kubectl get cm cm-demo2 -oyaml

image-20220609103749771

应用配置
1
2
kubectl apply -f configmap3-pod.yaml
kubectl get pod -o wide

image-20220609103848785

查看日志

我们配置文件打印了配置文件,我们来看下

1
kubectl logs configmap3

我们看到已经把配置文件打印出来了

image-20220609104107750

配置更新

configmap有一个重要的功能就是进行配置更新,下面我们演示一下基于环境变量和挂载的配置更新

创建配置清单
环境变量

这里我们对configmap1-pod的配置清单进行修改

1
vi configmap1-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: configmap1-pod
spec:
containers:
- name: configmap1-pod
image: busybox
command: [ "/bin/sh", "-c", "env;sleep 600" ] #打印环境信息
env:
- name: USERNAME #指定环境变量名称
valueFrom:
configMapKeyRef: #这个是引用的意思
name: cm-demo #引用cm-demo的configMap
key: data.name #注意:这个data.name仅仅只是cm-demo这个ConnfigMap里的Key.
- name: PASSWORLD
valueFrom:
configMapKeyRef:
name: cm-demo
key: data.passworld

执行命令并且应用配置

1
2
kubectl apply -f configmap1-pod.yaml
kubectl get pod -o wide

image-20220609171943787

我们可以登录容器查看环境变量信息,执行以下命令可以在容器内部执行命令

1
kubectl exec configmap1-pod -- env

我们发现当前的环境变量的username是admin

image-20220609172017112

挂载方式

我们这里对configmap3作为的配置进行修改

1
vi configmap3-pod.yaml

这里我们将configmap3挂载到了/etc/config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: configmap3
spec:
volumes:
- name: config-volume
configMap:
name: cm-demo
containers:
- name: testcm3
image: busybox
command: [ "/bin/sh", "-c", "cat /etc/config/redis.conf;sleep 600" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config

执行命令并且应用配置

1
kubectl apply -f configmap3-pod.yaml

image-20220609172417710

我们可以登录容器查看环境变量信息,执行以下命令可以在容器内部执行命令

1
kubectl exec configmap3 -- cat /etc/config/data.name

我们发现username的值也是admin

image-20220609172520381

修改configmap

下面我们对configmap进行修改,将username改为root

修改configMap

我们需要对configMap的参数进行修改

1
vi cm-demo.yaml
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-demo
namespace: default
data:
data.name: root
data.passworld: qwert
config: |
property.1=value-1
property.2=value-2
property.3=value-3
应用配置

现在我们需要重新应用configMap

1
kubectl apply -f cm-demo.yaml

这样我们就更新了configMap

image-20220609173030997

查看配置

最后我们看下配置是否生效

环境变量查看

我们可以通过如下命令查看下配置是否生效

1
kubectl exec configmap1-pod -- env

我们发现没有任何变化,说明基于环境变量的configMap对于pod是不能够自动更新的需要手动更新

image-20220609173625632

挂载方式查看

我们查看下挂载方式的配置更新是否生效

1
kubectl exec configmap3 -- cat /etc/config/data.name

我们发现配置已经更新了

image-20220609173827736

Secret使用

创建Secret

Secret 资源包含2个键值对: data 和 stringData,data 字段用来存储 base64 编码的任意数据。

​ 提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串,data 和 stringData 的键必须由字母、数字、-,_ 或 . 组成。

通过data创建

这里我们对用户名和密码进行base64编码,比如我们来创建一个用户名为admin,密码为 123456Secret 对象

密码加密

首先我们需要先把用户名和密码做 base64 编码

1
2
echo -n "admin"|base64
echo -n "123456"|base64

根据用户名密码获取加密的信息

image-20220609105601406

创建资源清单

然后我们就可以利用上面编码过后的数据来编写一个 YAML 文件

1
vi secret-demo.yaml
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
应用配置

然后我们就可以使用 kubectl 命令来创建了

1
2
kubectl apply -f secret-demo.yaml
kubectl get secret -o wide

这样我们就创建了一个secret对象出来

image-20220609105949729

查看详情

上面我们看不到配置信息,我们可以使用describe关键字查看详情

1
kubectl describe secrets mysecret

这样我们就可以看到详情信息了

image-20220609110314467

但是我们发现还是看不到具体加密数据,我们可以通过如下的方式进行查看

1
kubectl get secrets mysecret -oyaml

image-20220609110424608

通过stringData创建

对于某些场景,你可能希望使用 stringData 字段,这字段可以将一个非 base64 编码的字符串直接放入 Secret 中, 当创建或更新该 Secret 时,此字段将被编码。

创建加密字符串

比如当我们部署应用时,使用 Secret 存储配置文件, 你希望在部署过程中,填入部分内容到该配置文件

1
2
3
apiUrl: "https://my.api.com/api/v1"
username: "<user>"
password: "<password>"
创建资源清单

那么我们就可以使用以下定义将其存储在 Secret 中

1
vi secret-demo2.yaml
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Secret
metadata:
name: mysecret2
type: Opaque
stringData: #注意这里使用的是stringData
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: admin
password: 123456
应用配置

比如我们直接创建上面的对象后重新获取对象的话 config.yaml 的值会被编码

1
kubectl apply -f secret-demo2.yaml

image-20220609111000352

查看详情

控制器会自动帮我们把非编码的values编码成base64,然后放到data属性中去!!!

1
kubectl get secrets mysecret2 -oyaml

image-20220609111333184

查看信息

因为使用的是base64进行加密的,我们依然可以通过base64 -d来解密

1
echo "YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiAxMjM0NTYK" |base64 -d

image-20220609111501334

通过命令创建

我们还可以通过kubectl create命令来创建Opaque类型的Secret资源

执行创建命令
1
kubectl create secret generic mysecret3 --from-literal=username=admin --from-literal=password=123456

这样我们就创建了一个secret

image-20220609143008249

查看详情

我们可以通过命令来查看secret的详细信息

1
kubectl get secret mysecret3 -oyaml

我们发现用户名密码已经被使用base64加密了

image-20220609143146544

使用Secret

使用方式

创建好 Secret对象后,有两种方式来使用它

  • 以环境变量的形式
  • 以Volume的形式挂载
用于环境变量
创建资源清单

首先我们来测试下环境变量的方式,同样的,我们来使用一个简单的busybox镜像来测试下

1
vi secret1-pod.yaml

主要需要注意的是上面环境变量中定义的 secretKeyRef 字段,和我们前文的 configMapKeyRef 类似,一个是从 Secret 对象中获取,一个是从 ConfigMap 对象中获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: secret1-pod
spec:
containers:
- name: secret1
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: USERNAME #环境变量名称
valueFrom:
secretKeyRef:
name: mysecret #引用的secret的名称
key: username #使用secret哪一个环境变量
- name: PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
应用配置
1
2
kubectl apply -f secret1-pod.yaml
kubectl get pod -o wide

因为我们设置后台运行,一旦启动就会停止

image-20220609143734656

查看日志

我们来查看以下日志,因为我们启动分时候会打印secret中的参数

1
kubectl logs secret1-pod

我们发现日志已经被打印出来了,可以看到有 USERNAME 和 PASSWORD 两个环境变量输出出来

image-20220609143917111

环境变量挂载使用

环境变量还有一种就是直接挂载的方式使用,和上面我们configMap使用的挂载ENV方式一样

创建资源清单

我们创建一个挂载的资源清单

1
vi secret2-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Pod
metadata:
name: secret2-pod
spec:
containers:
- name: secret2
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- secretRef:
name: mysecret #注意这里是直接挂载进来的
应用配置
1
kubectl apply -f secret2-pod.yaml

image-20220609145310800

查看详情

通过日志查看详情

1
kubectl logs secret2-pod

我们发现我们在secret中配置的参数都打印出来了

image-20220609145327938

数据卷挂载使用

下面我们验证以下以数据卷挂载的方式,和configmap很类似

创建资源清单

同样的我们用一个 Pod 来验证下 Volume 挂载,创建一个 Pod 文件

1
vi secret3-pod.yaml

这里我们将mysecret挂载到了/etc/secrets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: secret3-pod
spec:
containers:
- name: secret3
image: busybox
command: ["/bin/sh", "-c", "ls /etc/secrets;sleep 600"]
volumeMounts:
- name: secrets
mountPath: /etc/secrets
volumes:
- name: secrets
secret:
secretName: mysecret
应用配置
1
kubectl apply -f secret3-pod.yaml

image-20220609145907367

查看日志

因为启动打印了日志,我们可以查看以下日志输出

1
kubectl logs secret3-pod

因为我们执行了ls /etc/secrets命令可以看到secret属性挂载成了文件

image-20220609145959599

登录容器查看

我们还可以登录容器查看下内容

1
2
3
4
kubectl exec -it secret3-pod -- /bin/sh
#登录容器执行以下命令
cat /etc/secrets/username
cat /etc/secrets/password

可以看到文件内容就是我们配置的属性值

image-20220609150512637

挂载指定文件

我们发现上面挂载是按照key为文件挂载的,我们想要挂在到指定的一个文件怎么办呢?

​ 在 secretName 下面添加 items 指定 keypath,假如不想以key名作为配置文件名可以引入items 字段,在其中逐个指定要用相对路径path替换的key

创建资源清单
1
vi secret4-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: secret4-pod
namespace: default
spec:
containers:
- name: secret4
image: busybox
command: ["/bin/sh", "-c", "ls /etc/secrets/account.txt;sleep 600"]
volumeMounts:
- name: secrets
mountPath: /etc/secrets
volumes:
- name: secrets
secret:
secretName: mysecret
items:
- key: username # 原文件名(key的名称)
path: account.txt # 修改之后的文件名(key的名称)
应用配置
1
kubectl apply -f secret4-pod.yaml

image-20220609151856311

查看日志

我们看下日志打印的信息

1
kubectl logs secret4-pod

说明文件已经被挂载上去了

image-20220609152000183

登录容器查看

我们还可以登录容器查看下内容

1
2
3
4
5
6
kubectl exec -it secret4-pod -- /bin/sh
#登录容器执行以下命令
ls /etc/secrets/
cat /etc/secrets/account.txt

kubectl exec secret4-pod -- cat /etc/secrets/account.txt

可以看到文件内容就是我们配置的属性值

image-20220609152236368

配置更新

Secret有一个重要的功能就是进行配置更新,下面我们演示一下基于环境变量和挂载的配置更新

创建配置清单
环境变量

这里我们使用secret1-pod的配置

1
vi secret1-pod.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: secret1-pod
spec:
containers:
- name: secret1
image: busybox
command: [ "/bin/sh", "-c", "env;sleep 600" ]
env:
- name: USERNAME #环境变量名称
valueFrom:
secretKeyRef:
name: mysecret #引用的secret的名称
key: username #使用secret哪一个环境变量
- name: PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password

执行命令并且应用配置

1
kubectl apply -f secret1-pod.yaml

image-20220609154927982

我们可以登录容器查看环境变量信息,执行以下命令可以在容器内部执行命令

1
kubectl exec secret1-pod -- env

我们发现当前的环境变量的username是admin

image-20220609155556675

挂载方式

我们这里使用secret3作为的配置

1
vi secret3-pod.yaml

这里我们将mysecret挂载到了/etc/secrets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: secret3-pod
spec:
containers:
- name: secret3
image: busybox
command: ["/bin/sh", "-c", "ls /etc/secrets;sleep 600"]
volumeMounts:
- name: secrets
mountPath: /etc/secrets
volumes:
- name: secrets
secret:
secretName: mysecret

执行命令并且应用配置

1
kubectl apply -f secret3-pod.yaml

image-20220609160432205

我们可以登录容器查看环境变量信息,执行以下命令可以在容器内部执行命令

1
kubectl exec secret3-pod -- cat /etc/secrets/username

我们发现username的值也是admin

image-20220609160556597

修改secret

下面我们对secret进行修改,将username改为root

生成密钥

我们先生成root的base64的密钥

1
echo -n "root"|base64

image-20220609155758725

编辑资源清单

生成密钥后,我们就需要修改对应的secret了

1
vi secret-demo.yaml
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: cm9vdA==
password: MTIzNDU2
应用配置

现在我们需要重新应用secret

1
kubectl apply -f secret-demo.yaml

这样我们就更新了secret

image-20220609165858273

查看配置

最后我们看下配置是否剩下

环境变量查看

我们可以通过如下命令查看下配置是否生效

1
kubectl exec secret1-pod -- env

我们发现没有任何变化,说明基于环境变量的secret对于pod是不能够自动更新的需要手动更新

image-20220609170048985

挂载方式查看

我们查看下挂载方式的配置更新是否生效

1
kubectl exec secret3-pod -- cat /etc/secrets/username

我们发现配置已经更新了

image-20220609170331413

Secret和ConfigMap的区别

最后我们来对比下 SecretConfigMap这两种资源对象的异同点

相同点
  • key/value的形式
  • 属于某个特定的命名空间
  • 可以导出到环境变量
  • 可以通过目录/文件形式挂载
  • 通过 volume 挂载的配置信息均可热更新
不同点
  • Secret 可以被 ServerAccount 关联
  • Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
  • Secret 支持 Base64 加密
  • Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型
使用注意
  1. 同样 Secret 文件大小限制为 1MB(ETCD 的要求);
  2. Secret 虽然采用 Base64 编码,但是我们还是可以很方便解码获取到原始信息,所以对于非常重要的数据还是需要慎重考虑,可以考虑使用 Vault 来进行加密管理。

评论