kubernetes Secret官方地址
案例
- 包含 SSH 密钥的 Pod
- Secret 卷中以点号开头的文件(隐藏文件)
保存敏感信息
,例如密码
、OAuth 令牌
和 SSH 密钥
。 将这些信息放在 secret 中比放在 Pod
或者 容器镜像
中来说更加安全和灵活
Secret 概览:
Secret 是一种包含
少量敏感信息例如密码、令牌或密钥的对象
。 这样的信息可能会被放在Pod 规约中或者镜像中
。 用户可以创建 Secret
,同时系统也创建了一些 Secret
。Pod需要引用Secret,可以用
三种方式之一来使用 Secret
- 作为挂载到一个或多个容器上的卷中的文件。
- 作为容器的环境变量
- 由 kubelet 在为 Pod 拉取镜像时使用(重点)
Secret有三种类型:
1、Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,加密性弱。
2、kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息,保证镜像的安全性。
3、kubernetes.io/service-account-token: 用于被serviceaccount引用。`serviceaccout创建时Kubernetes会默认创建对应的secret`。Pod如果使用了serviceaccount,对应的secret会`自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中`。
Secret 格式:
kubectlcreatesecretgeneric -h
kubectl create secret generic NAME [--type=string] [--from-file=[key=]source]
[--from-literal=key1=value1] [--dry-run=server|client|none] [options]
二、Secret 用法
mkdir -p /root/kubernetes/Secrets
1、文件格式:
创建隐藏类型文件:
echo -n 'admin' > /root/kubernetes/Secrets/.username.txt
echo -n 'root' > /root/kubernetes/Secrets/.password.txt
生成secret
kubectl create secret generic test-file \
--from-file=/root/kubernetes/Secrets/.username.txt \
--from-file=/root/kubernetes/Secrets/.password.txt
文章图片
查看详细信息:
kubectldescribesecretstest-file
文章图片
删除名为test-file的secrets
kubectldelete secretstest-file
或者如下方式:
kubectl create secret generic test-file \
--from-file=.username.txt=/root/kubernetes/Secrets/.username.txt \
--from-file=.password.txt=/root/kubernetes/Secrets/.password.txt
文章图片
再次删除名为test-file的secrets
kubectldelete secretstest-file
2、字面格式
好处: 您
无需对文件中保存
(–from-file)的密码中的特殊字符执行转义操作
。kubectlcreate secretgeneric literal-test \
--from-literal=username=admin \
--from-literal=password='root@'
查看详情
kubectlget secrets&&kubectldescribesecretsliteral-test
文章图片
默认情况下,kubectl get 和 kubectl describe 避免显示密码的内容。
这是为了防止机密被意外地暴露给旁观者或存储在终端日志中。
接下来我们根据三种类型分别进行演示
三、Opaque Secret 将固定字符转换为base64格式
echo -n 'admin' | base64
解析base64格式
echo "cm9vdA==" |base64 --decode
将随机字符转换为base64格式
head -c 12 /dev/urandom | base64
1、使用 data 字段将两个字符串存储在 Secret 中,请按如下所示将它们转换为 base64:
echo -n 'admin' | base64
输出类似于:
YWRtaW4=echo -n 'root' | base64
输出类似于:
cm9vdA==
2、现在可以像这样写一个 Secret 对象:
cat <secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: cm9vdA==
EOF
3、使用 kubectl apply 创建 Secret 对象:
kubectl apply -f secret.yaml
4、查看生成secret
kubectlget secrets
5、解码 Secret信息
kubectlgetsecretsmysecret-o yaml |grep -E"^data" -A 2
文章图片
四、在 Pod中使用卷挂载Secret 文件 普通
1、在 Pod 中使用存放在挂载卷中 Secret 的例子
vimsecretvolumes.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: nginx
volumeMounts:
- name: foo#与volumes名称一致
mountPath: "/etc/foo"#挂载绝对路径
readOnly: true#只读
volumes:
- name: foo#与volumeMounts名称一致
secret:
secretName: mysecret#secret的名字
2、使用 kubectl apply 创建 Pod 资源
kubectl apply -f secretvolumes.yaml
3、查看secret挂载到容器
kubectlexec -itmypod-- ls/etc/foo
文章图片
可以看到 /etc/foo目录下挂载文件,是mysecret的secret的私密文件
4、查看容器 /etc/foo文件内容
kubectlexec -itmypod-- cat/etc/foo/username &&echo ""&& kubectlexec -itmypod-- cat/etc/foo/password && echo ""
文章图片
五、将 Secret 键名映射到特定路径 1、在 Pod 中使用items指定Secret存放目录
vim secretvolumes_items.yaml
apiVersion: v1
kind: Pod
metadata:
name: secretvolumes-items
spec:
containers:
- name: secretvolumes-items
image: nginx
volumeMounts:
- name: foo#与volumes名称一致
mountPath: "/etc/foo"#挂载绝对路径
readOnly: true#只读
volumes:
- name: foo#与volumeMounts名称一致
secret:
secretName: mysecret#secret的名字
items:
- key: username#secret名称的中的键
path: item/username#对应的目标路径
- key: password#secret名称中的键
path: item/password#对应的目标路径
2、使用 kubectl apply 创建 Pod 资源
kubectlapply -f secretvolumes_items.yaml
3、查看Secret映射
kubectlexec -itsecretvolumes-items -- ls /etc/foo/item
文章图片
username Secret
存储在 /etc/foo/item/username文件中而不是 /etc/foo/username 中
。可以去除key: password 看看会发生什么(你会发现Secret password没有被映射)六、Secret 文件权限
- SON 规范不支持八进制符号,因此
使用 256 值作为 0400 权限
权限值为 0777
,由于JSON 限制,必须以十进制格式指定模式,即 511
。
vim secretvolumes_mode.yaml
apiVersion: v1
kind: Pod
metadata:
name: secretvolumes-mode
spec:
containers:
- name: secretvolumes-mode
image: nginx
volumeMounts:
- name: foo#与volumes名称一致
mountPath: "/etc/foo"#挂载绝对路径
readOnly: true#只读
volumes:
- name: foo#与volumeMounts名称一致
secret:
secretName: mysecret#secret的名字
items:
- key: username#secret名称的中的键
path: item/username#对应的目标路径
mode: 511#username文件权限为777
- key: password#secret名称中的键
path: item/password#对应的目标路径
mode: 256#password文件权限为400
2、使用 kubectl apply 创建 Pod 资源
kubectlapply -f secretvolumes_mode.yaml
3、查看Secret映射文件的权限
kubectlexec-it secretvolumes-mode -- ls-l /etc/foo/item/
文章图片
4、查看是否影响到其他Pod文件 拿secretvolumes-items与secretvolumes-modePod对比
文章图片
七、挂载的 Secret 会被自动更新 当已经存储于卷中被
使用的 Secret 被更新时
,被映射的键也将终将被更新
。 组件 kubelet 在周期性同步时检查被挂载的 Secret 是不是最新的
。 但是,它会使用其本地缓存的数值作为 Secret 的当前值
。缓存的类型可以使用 KubeletConfiguration 结构 中的 ConfigMapAndSecretChangeDetectionStrategy 字段来配置
。 它可以通过 watch 操作来传播(默认),基于 TTL 来刷新,也可以 将所有请求直接重定向到 API 服务器
。 因此,从 Secret 被更新到将新 Secret 被投射到 Pod 的那一刻的总延迟
可能与 kubelet 同步周期 + 缓存传播延迟一样长
,其中缓存传播延迟取决于所选的缓存类型
。 对应于不同的缓存类型,该延迟或者等于 watch 传播延迟,或者等于缓存的 TTL, 或者为 0。
说明:使用 Secret 作为子路径卷挂载的容器 不会收到 Secret 更新具体说明查看官方文档(子路径)
1、热更新名为mysecret的secrets
kubectl editsecretsmysecret
文章图片
2、查看热更新的值速度 便于测试这里执行简单的脚本。
for i in {1..1000};
do kubectlexec-it secretvolumes-mode -- cat/etc/foo/item/password && echo -e "\t$i秒" &&sleep 1s;
done
文章图片
可以多测试几次, 最快我这边测试最快13秒最慢1分钟。
3、 禁止变更它们的数据有下列好处
- 防止意外(或非预期的)
更新导致应用程序中断
- 通过将 Secret 标记为不可变来关闭
kube-apiserver 对其的监视
,从而显著降低 kube-apiserver 的负载,提升集群性能
并将 Secret 或 ConfigMap 的 immutable 字段设置为 true
. 例如:文章图片
再次热更新password,查看是否可以更新。
文章图片
文章图片
文章图片
说明: 一旦一个 Secret 或 ConfigMap 被
标记为不可变
,撤销此操作或者更改 data 字段的内容都是不可能的。只能删除并重新创建这个 Secret
。现有的 Pod 将维持对已删除 Secret 的挂载点 - 建议重新创建这些 Pod。
八、以环境变量的形式使用 Secrets 以环境变量的形式使用 Secrets
方式一 valueFrom:
1、使用来自环境变量中的 Secret值的 Pod
vim secretenv.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: secret-env-pod
image: redis
env:
- name: SECRET_USERNAME#环境变量名称
valueFrom:#来源
secretKeyRef:#secret编号
name: mysecret#secret名字
key: username#键值名username
- name: SECRET_PASSWORD #环境变量名称
valueFrom:#来源
secretKeyRef:#secret编号
name: mysecret#secret名字
key: password#键值名username
restartPolicy: Never
2、使用 kubectl apply 创建 Pod 资源
kubectlapply -f secretenv.yaml
3、查看容器环境变量
kubectlexec -itsecret-env-pod-- env |grepSECRET
【kubernetes|kubernetes secret私密凭据】
文章图片
方式二 envFrom:
1、使用来自环境变量中的 Secret值的 Pod
vimsecretenvFrom.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-testenvfrom-pod
spec:
containers:
- name: secret-testenvfrom-pod
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- secretRef:
name: mysecret#secret名称
restartPolicy: Never
2、使用 kubectl apply 创建 Pod 资源
kubectlapply-f secretenvFrom.yaml
文章图片
3、查看容器环境变量
kubectllogssecret-testenvfrom-pod
文章图片
九、kubelet在为 Pod 拉取镜像认证 实验步骤查看: kubernetes imagePullSecrets认证拉取私仓
推荐阅读
- kubernetes|@kubernetes(k8s) 应用配置管理(ConfigMap、subPath、Secret)
- java|云原生爱好者周刊(服务网格的困境与破局)
- 运维|云原生爱好者周刊(VMware Tanzu 社区版发布,无任何限制!)
- java|云原生爱好者周刊(Grafana Loki 免费电子书)
- kubernetes|云原生爱好者周刊(好家伙,Rust 也成立云原生组织了)
- docker|基于Rust-vmm实现Kubernetes运行时
- kubernetes|K8s 系列(五) - 浅谈 CSI
- docker|Kubernetes基础知识与k8s多节点案例配置
- 大白话|图解 K8S(06)(调度利器之污点与容忍度(压力驱逐))