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 格式:

kubectl  create  secret  generic -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 secret私密凭据_第1张图片
查看详细信息:

kubectl  describe  secrets   test-file

kubernetes secret私密凭据_第2张图片
删除名为test-file的secrets

kubectl  delete secrets  test-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 secret私密凭据_第3张图片

再次删除名为test-file的secrets

kubectl  delete secrets  test-file

2、字面格式
好处: 您无需对文件中保存(–from-file)的密码中的特殊字符执行转义操作

kubectl  create secret  generic literal-test \
--from-literal=username=admin \
--from-literal=password='root@'

查看详情

kubectl  get secrets   &&  kubectl  describe   secrets  literal-test

kubernetes secret私密凭据_第4张图片
默认情况下,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 <<EOF >  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

kubectl  get secrets

5、解码 Secret信息

kubectl  get  secrets  mysecret  -o yaml |grep -E  "^data" -A 2

在这里插入图片描述

四、在 Pod中使用卷挂载Secret 文件

普通

1、在 Pod 中使用存放在挂载卷中 Secret 的例子

vim  secretvolumes.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挂载到容器

kubectl  exec -it  mypod  -- ls  /etc/foo

在这里插入图片描述
可以看到 /etc/foo目录下挂载文件,是mysecret的secret的私密文件

4、查看容器 /etc/foo文件内容

kubectl  exec -it  mypod  -- cat  /etc/foo/username &&  echo ""  && kubectl  exec -it  mypod  -- 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 资源

kubectl  apply -f secretvolumes_items.yaml

3、查看Secret映射

kubectl  exec -it  secretvolumes-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

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 资源

kubectl  apply -f secretvolumes_mode.yaml

3、查看Secret映射文件的权限

kubectl  exec  -it secretvolumes-mode -- ls  -l /etc/foo/item/

在这里插入图片描述

4、查看是否影响到其他Pod文件

拿secretvolumes-items与secretvolumes-modePod对比
kubernetes secret私密凭据_第5张图片

七、挂载的 Secret 会被自动更新

当已经存储于卷中被使用的 Secret 被更新时被映射的键也将终将被更新。 组件 kubelet 在周期性同步时检查被挂载的 Secret 是不是最新的。 但是,它会使用其本地缓存的数值作为 Secret 的当前值

缓存的类型可以使用 KubeletConfiguration 结构 中的 ConfigMapAndSecretChangeDetectionStrategy 字段来配置。 它可以通过 watch 操作来传播(默认),基于 TTL 来刷新,也可以 将所有请求直接重定向到 API 服务器。 因此,从 Secret 被更新到将新 Secret 被投射到 Pod 的那一刻的总延迟可能与 kubelet 同步周期 + 缓存传播延迟一样长,其中缓存传播延迟取决于所选的缓存类型。 对应于不同的缓存类型,该延迟或者等于 watch 传播延迟,或者等于缓存的 TTL, 或者为 0。

说明:使用 Secret 作为子路径卷挂载的容器 不会收到 Secret 更新具体说明查看官方文档(子路径)

1、热更新名为mysecret的secrets

kubectl edit  secrets  mysecret

kubernetes secret私密凭据_第6张图片

2、查看热更新的值速度

便于测试这里执行简单的脚本。

for i in {1..1000};do kubectl  exec  -it secretvolumes-mode -- cat  /etc/foo/item/password && echo -e "\t$i秒" &&  sleep 1s;done

kubernetes secret私密凭据_第7张图片
可以多测试几次, 最快我这边测试最快13秒最慢1分钟。

3、 禁止变更它们的数据有下列好处

  • 防止意外(或非预期的)更新导致应用程序中断
  • 通过将 Secret 标记为不可变来关闭kube-apiserver 对其的监视,从而显著降低 kube-apiserver 的负载,提升集群性能

使用这个特性需要启用 ImmutableEmphemeralVolumes 特性开关并将 Secret 或 ConfigMap 的 immutable 字段设置为 true. 例如:

kubernetes secret私密凭据_第8张图片
再次热更新password,查看是否可以更新。
kubernetes secret私密凭据_第9张图片
kubernetes secret私密凭据_第10张图片
在这里插入图片描述
说明: 一旦一个 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 资源

kubectl  apply -f secretenv.yaml

3、查看容器环境变量

kubectl  exec -it  secret-env-pod   -- env |grep  SECRET

在这里插入图片描述

方式二 envFrom:

1、使用来自环境变量中的 Secret值的 Pod

vim  secretenvFrom.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 资源

kubectl  apply   -f secretenvFrom.yaml

kubernetes secret私密凭据_第11张图片

3、查看容器环境变量

kubectl  logs  secret-testenvfrom-pod

kubernetes secret私密凭据_第12张图片

九、kubelet在为 Pod 拉取镜像认证

实验步骤查看: kubernetes imagePullSecrets认证拉取私仓

你可能感兴趣的:(kubernetes,初级篇)