一、Secret热更新背景¶
实际使用ConfigMap和Secret时,一般情况下都是直接使用文件创建,也就是使用--from-file=xxx的格式进行创建。创建的ConfigMap可能因为换行的问题,导致使用kubectl edit cm xxx时排版很乱,编辑起来很受影响。
另外,使用kubectl edit secret xxx时,由于Secret数据为加密数据,无法直接编辑。
二、通过YAML文件热更新Secret¶
1.定义一个yaml文件
[root@k8s-master01 conf]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
2.创建Secret
[root@k8s-master01 conf]# kubectl create -f secret.yaml
3.通过yaml文件更新Secret,修改username为YWRtaW4xMjM=
[root@k8s-master01 conf]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4xMjM=
password: MWYyZDFlMmU2N2Rm
[root@k8s-master01 conf]# kubectl replace -f secret.yaml
4.验证,观察到username变更为YWRtaW4xMjM=
[root@k8s-master01 conf]# kubectl get secret mysecret -oyaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4xMjM=
kind: Secret
metadata:
creationTimestamp: "2023-05-03T01:53:14Z"
name: mysecret
namespace: default
resourceVersion: "958931"
uid: 90337d19-6054-4b15-924b-65ba3a33dc8f
type: Opaque
三、通过Kubectl命令热更新Secret¶
1.将凭据保存到文件,其中-n 标志用来确保生成文件的文末没有多余的换行符。这很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,额外的换行符也会被编码。 你不需要对文件中包含的字符串中的特殊字符进行转义。
$ echo -n 'admin' > ./username.txt
$ echo -n 'S!B\*d$zDsb=' > ./password.txt
2.在 kubectl 命令中传递文件路径,默认键名为文件名。你也可以通过 --from-file=[key=]source 设置键名
$ kubectl create secret generic db-user-pass --from-file=username=./username.txt --from-file=password=./password.txt
3.检查 Secret 是否已创建
[root@k8s-master01 conf]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 10s
default-token-8s8wl kubernetes.io/service-account-token 3 52d
4.查看 Secret 的细节
[root@k8s-master01 conf]# kubectl describe secret db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
username: 5 bytes
password: 12 bytes
注意:kubectl get 和 kubectl describe 命令默认不显示 Secret 的内容。 这是为了防止 Secret 被意外暴露或存储在终端日志中.
5.查看你所创建的 Secret 内容
[root@k8s-master01 conf]# kubectl get secret db-user-pass -o jsonpath='{.data}'
{"password":"UyFCXCpkJHpEc2I9","username":"YWRtaW4="}
当然了,你也可以使用-oyaml查看你所创建的 Secret 内容
[root@k8s-master01 conf]# kubectl get secret db-user-pass -oyaml
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I9
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2023-05-03T01:38:58Z"
name: db-user-pass
namespace: default
resourceVersion: "877358"
uid: f609641c-7002-4079-9756-705fa18b5f44
type: Opaque
6.更新源文件,这里修改username为admin123
$ echo -n 'admin123' > ./username.txt
7.更新Secret
[root@k8s-master01 conf]# kubectl create secret generic db-user-pass --from-file=username=./username.txt --from-file=password=./password.txt --dry-run=client -oyaml | kubectl replace -f -
上面参数说明:
- db-user-pass:ConfigMap的名称
- generic:指定为通用型Secret
- --dry-run=client -oyaml:只运行命令,并不真正地创建,并以YAML的格式输出
- kubectl replace -f -:通过文件创建的Secret和ConfigMap不能被直接替换,但是通过YAML文件创建可以被替换,所以先使用dry-run -oyaml生成YAML文件,再进行replace即可实现热更新,该方法可以用于其他资源类型,通过YAML文件替换已经创建的资源也是可以的。
8.查看更改后的内容,观察到已更新
[root@k8s-master01 conf]# echo "admin123" | base64
YWRtaW4xMjMK
[root@k8s-master01 conf]# kubectl get secret db-user-pass -oyaml
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I9
username: YWRtaW4xMjMK
kind: Secret
metadata:
creationTimestamp: "2023-05-03T01:38:58Z"
name: db-user-pass
namespace: default
resourceVersion: "962391"
uid: f609641c-7002-4079-9756-705fa18b5f44
type: Opaque
注意:上面更新默认将字符串末尾换行符也进行了加密!
四、Secret限制¶
Secret在使用时有很多局限性,目前具有的限制如下:
- envFrom和valueFrom无法热更新环境变量
- 引用key必须存在
- envFrom配置环境变量,如果key是无效的,会直接跳过
- Secret和引用它的Pod需要在同一个命名空间
- SubPath无法热更新
- Secret最好不要太大
五、不可更改的Secret¶
Kubernetes 允许你将特定的 Secret(和 ConfigMap)标记为 不可更改(Immutable)。 禁止更改现有 Secret 的数据有下列好处:
- 防止意外(或非预期的)更新导致应用程序中断
- (对于大量使用 Secret 的集群而言,至少数万个不同的 Secret 供 Pod 挂载), 通过将 Secret 标记为不可变,可以极大降低 kube-apiserver 的负载,提升集群性能。 kubelet 不需要监视那些被标记为不可更改的 Secret。
你可以通过将 Secret 的 immutable 字段设置为 true 创建不可更改的 Secret。 例如:
1.将凭据保存到文件,其中-n 标志用来确保生成文件的文末没有多余的换行符。这很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,额外的换行符也会被编码。 你不需要对文件中包含的字符串中的特殊字符进行转义。
$ echo -n 'admin' > ./username.txt
$ echo -n 'S!B\*d$zDsb=' > ./password.txt
2.在 kubectl 命令中传递文件路径,默认键名为文件名。你也可以通过 --from-file=[key=]source 设置键名
$ kubectl create secret generic db-user-pass --from-file=username=./username.txt --from-file=password=./password.txt
3.检查 Secret 是否已创建
[root@k8s-master01 conf]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 10s
default-token-8s8wl kubernetes.io/service-account-token 3 52d
4.在线编辑Secret,在末尾处添加immutable: true
[root@k8s-master01 conf]# kubectl edit secret db-user-pass
...
...
#在末尾处添加
immutable: true
5.验证,再次进行在线编辑,提示不可更改
[root@k8s-master01 conf]# kubectl edit secret db-user-pass
