K8s Secret :敏感数据管理的正确姿势
Secret 是什么
Secret 是 K8s 里专门用来存储少量敏感数据的资源对象,说白了,就是给你存密码、密钥、仓库账号这些不能随便暴露的内容的。
它最核心的作用,就是把敏感数据和你的配置、代码彻底分开:你把敏感数据存到 Secret 里,你的 Pod 配置里只需要引用这个 Secret 的名字就行,不用把明文写在配置里。
这样一来,就算你把整个配置文件夹分享给同学,或者传到 GitHub 存档,别人也看不到你的敏感数据,不会出现泄露的问题。
而且它还有几个很实用的特性:
它的内容只会存在节点的内存临时文件系统里,不会写到硬盘上,就算重启虚拟机,这些数据也会被清掉,不会留下残留
它是命名空间隔离的,同一个集群里,不同命名空间的 Pod 用不了别的命名空间的 Secret,安全性很高
单个 Secret 最多存 1MiB 的数据,刚好用来存小的敏感数据,不适合存大文件
Secret 的 3 种核心用法
1. 给应用注入敏感数据
这是最基础的用法,把 Secret 里的内容,通过环境变量的方式,传给你的应用容器,应用直接读环境变量就能拿到敏感数据。
先把你的敏感数据存到 Secret 里:
kubectl create secret generic mysqlpass --from-literal=password=你的密码然后在 Pod 的配置里,引用这个 Secret:
env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysqlpass key: password整个配置里,再也没有明文密码了,就算你把这个配置分享出去,也不会泄露你的敏感数据。
2. 拉私有镜像的凭证
最容易卡住的问题:自己搭的私有仓库,本地能拉镜像,到 K8s 里就拉不动了。
这是因为 K8s 里是 kubelet 帮你拉镜像,它没有你的仓库登录凭证,这时候你就可以把你的仓库凭证存成 Secret,然后告诉 kubelet,拉镜像的时候用这个凭证:
kubectl create secret docker-registry my-registry-secret \ --docker-server=你的仓库地址 \ --docker-username=你的账号 \ --docker-password=你的密码 \ --docker-email=你的邮箱然后在 Pod 的配置里,加上imagePullSecrets:
spec: imagePullSecrets: - name: my-registry-secret containers: - name: my-app image: 你的仓库地址/你的镜像:v1就这么一行,kubelet 拉镜像的时候,自动就会用这个凭证登录仓库,镜像一下就能拉下来了。
3. 把密钥挂载成文件
如果你的敏感数据是文件,比如 SSH 私钥、证书,那你可以把 Secret 挂载成容器里的文件,应用直接读文件就能拿到数据,这个方式比环境变量更安全,因为环境变量会被子进程继承,很容易泄露,而文件就不会有这个问题。
kubectl create secret generic ssh-key --from-file=你的私钥文件路径然后在 Pod 的配置里,把 Secret 挂载到对应的目录:
volumes: - name: ssh-volume secret: secretName: ssh-key containers: - name: my-app volumeMounts: - name: ssh-volume mountPath: /root/.ssh readOnly: true这样容器里的/root/.ssh/id_rsa,就是你的私钥,应用直接读就行,安全又方便。
用 Secret 一定要注意的 5 个点
别把 Base64 当加密:很多人以为 Secret 里的数据是加密的,其实不是,它只是做了个 Base64 编码,任何人只要能拿到你的 Secret,一秒就能解码拿到明文,Secret 的安全靠的是权限控制,不是编码。
环境变量不会自动更新:如果你用环境变量的方式注入 Secret,那你更新 Secret 之后,环境变量不会变,必须重启 Pod 才能生效,但是如果是挂载文件的方式,就会自动更新,不用重启。
Secret 不能跨命名空间用:Secret 是命名空间隔离的,你在 default 创建的 Secret,别的命名空间的 Pod 用不了,要想用的话,得把 Secret 复制过去。
别把 Secret 的配置传到 Git:就算是 Secret 的配置,也别传到公共仓库,会泄露你的敏感数据,最好单独存在本地。
特权容器要谨慎用:如果你的容器是以特权模式运行的,那它就能访问整个节点上的所有 Secret,所以特权容器别随便用。
