kubernetes|kubernetes secret私密凭据

kubernetes Secret官方地址
案例

  • 包含 SSH 密钥的 Pod
  • Secret 卷中以点号开头的文件(隐藏文件)
一、简介 Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌SSH 密钥。 将这些信息放在 secret 中比放在 Pod 或者 容器镜像 中来说更加安全和灵活


Secret 概览:
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在Pod 规约中或者镜像中。 用户可以创建 Secret,同时系统也创建了一些 Secret
Pod需要引用Secret,可以用三种方式之一来使用 Secret
  1. 作为挂载到一个或多个容器上的卷中的文件。
  2. 作为容器的环境变量
  3. 由 kubelet 在为 Pod 拉取镜像时使用(重点)

Secret类型:
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

kubernetes|kubernetes secret私密凭据
文章图片

查看详细信息:
kubectldescribesecretstest-file

kubernetes|kubernetes secret私密凭据
文章图片

删除名为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

kubernetes|kubernetes secret私密凭据
文章图片

再次删除名为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

kubernetes|kubernetes secret私密凭据
文章图片

默认情况下,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

kubernetes|kubernetes secret私密凭据
文章图片

四、在 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

kubernetes|kubernetes secret私密凭据
文章图片

可以看到 /etc/foo目录下挂载文件,是mysecret的secret的私密文件
4、查看容器 /etc/foo文件内容
kubectlexec -itmypod-- cat/etc/foo/username &&echo ""&& kubectlexec -itmypod-- cat/etc/foo/password && echo ""

kubernetes|kubernetes secret私密凭据
文章图片

五、将 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

kubernetes|kubernetes secret私密凭据
文章图片

username Secret 存储在 /etc/foo/item/username文件中而不是 /etc/foo/username 中。可以去除key: password 看看会发生什么(你会发现Secret password没有被映射)
六、Secret 文件权限
  • SON 规范不支持八进制符号,因此使用 256 值作为 0400 权限
  • 权限值为 0777,由于JSON 限制,必须以十进制格式指定模式,即 511
1、在 Pod 中使用mode指定Secret存放文件权限
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/

kubernetes|kubernetes secret私密凭据
文章图片

4、查看是否影响到其他Pod文件 拿secretvolumes-items与secretvolumes-modePod对比
kubernetes|kubernetes secret私密凭据
文章图片

七、挂载的 Secret 会被自动更新 当已经存储于卷中被使用的 Secret 被更新时被映射的键也将终将被更新。 组件 kubelet 在周期性同步时检查被挂载的 Secret 是不是最新的。 但是,它会使用其本地缓存的数值作为 Secret 的当前值
缓存的类型可以使用 KubeletConfiguration 结构 中的 ConfigMapAndSecretChangeDetectionStrategy 字段来配置。 它可以通过 watch 操作来传播(默认),基于 TTL 来刷新,也可以 将所有请求直接重定向到 API 服务器。 因此,从 Secret 被更新到将新 Secret 被投射到 Pod 的那一刻的总延迟可能与 kubelet 同步周期 + 缓存传播延迟一样长,其中缓存传播延迟取决于所选的缓存类型。 对应于不同的缓存类型,该延迟或者等于 watch 传播延迟,或者等于缓存的 TTL, 或者为 0。
说明:使用 Secret 作为子路径卷挂载的容器 不会收到 Secret 更新具体说明查看官方文档(子路径)
1、热更新名为mysecret的secrets
kubectl editsecretsmysecret

kubernetes|kubernetes secret私密凭据
文章图片

2、查看热更新的值速度 便于测试这里执行简单的脚本。
for i in {1..1000}; do kubectlexec-it secretvolumes-mode -- cat/etc/foo/item/password && echo -e "\t$i秒" &&sleep 1s; done

kubernetes|kubernetes secret私密凭据
文章图片

可以多测试几次, 最快我这边测试最快13秒最慢1分钟。
3、 禁止变更它们的数据有下列好处
  • 防止意外(或非预期的)更新导致应用程序中断
  • 通过将 Secret 标记为不可变来关闭kube-apiserver 对其的监视,从而显著降低 kube-apiserver 的负载,提升集群性能
使用这个特性需要启用 ImmutableEmphemeralVolumes 特性开关并将 Secret 或 ConfigMap 的 immutable 字段设置为 true. 例如:
kubernetes|kubernetes secret私密凭据
文章图片

再次热更新password,查看是否可以更新。
kubernetes|kubernetes secret私密凭据
文章图片

kubernetes|kubernetes secret私密凭据
文章图片

kubernetes|kubernetes secret私密凭据
文章图片

说明: 一旦一个 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私密凭据】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

kubernetes|kubernetes secret私密凭据
文章图片

3、查看容器环境变量
kubectllogssecret-testenvfrom-pod

kubernetes|kubernetes secret私密凭据
文章图片

九、kubelet在为 Pod 拉取镜像认证 实验步骤查看: kubernetes imagePullSecrets认证拉取私仓

    推荐阅读