【k8s教程笔记】第七章 k8s存储 第三节 Secret详解
一、ConfigMap回顾与Secret的引出
- 上一小节讲解了
ConfigMap资源对象,作用与传统环境的配置中心一致,用于将服务的配置文件抽离,实现配置的热更新 ConfigMap的热更新必须通过卷插件的方式实现,同时支持Immutable字段:开启后停止对ConfigMap变更的监听,可降低etcd压力,避免非预期的恶意修改,适合确认存储数据不需要变更的场景- 但
ConfigMap存在明显局限性:所有数据以明文存储,不适合存储敏感数据;相比将敏感数据直接写在Pod定义或镜像中,Secret存储更安全、更灵活,因此引出专门用于存储敏感数据的Secret资源对象
二、Secret核心定义与安全机制
2.1 核心定义
Secret是Kubernetes中用于存储敏感数据的资源对象,仅建议存储密码、OS文件、SSH令牌、证书、认证凭据等敏感数据,非敏感数据存储属于冗余操作(ConfigMap即可满足需求)。Secret同样支持热更新,灵活性与ConfigMap一致。
2.2 安全机制说明
- 编码≠加密:
Secret的安全机制基于编码实现,编码是可逆的(只要拿到编码对照表即可解码);而加密(尤其是非对称加密)的加解密密钥不同,不可逆,两者是完全不同的概念。 - 集群层面的安全增强设计:
- 仅将
Secret分发到需要访问该Secret的Pod所在节点,不会全集群所有节点存储该数据 Secret仅存储在节点内存(易失性存储)中,不会写入物理磁盘(非失性存储),节点删除Secret后数据会自动清理,无需手动擦除磁盘- Kubernetes 1.7版本后,etcd会对
Secret进行加密存储,直接读取etcd也无法获取明文,但可通过特定手段解密
- 仅将
- 安全边界:
Secret的安全性仅能作为基础保护手段,不能作为唯一的安全措施。如果数据敏感度极高(泄露可导致集群所有服务、数据被窃取),需要配合第三方加密工具使用,因为Secret本质是编码而非强加密,集群管理员可通过命令直接解码获取明文。
三、Secret常见类型分类
Secret分为多种细分类型,常见类型包括:
- Opaque:默认类型,专门用于存储任意敏感数据,存储的数据需要经过编码,无法直接看到原始明文,是最常用的
Secret类型 - kubernetes.io/service-account-token:ServiceAccount相关凭据,后续安全章节会重点讲解
- kubernetes.io/dockercfg:~/.dockercfg文件的序列化形式
- kubernetes.io/dockerconfigjson:适配Docker认证凭据存储,旧版Docker(如1.7.x版本)会在用户家目录下的
~/.docker/config文件保存镜像仓库的认证信息,新版Docker已废弃该文件,改用~/.docker/config.json存储用户认证凭据,该类型用于将Docker认证凭据存储到Kubernetes集群 - kubernetes.io/basic-auth:用于存储Ingress基于用户ACL认证的用户名密码凭据
- kubernetes.io/ssh-auth:用于存储SSH认证密钥
- kubernetes.io/tls:用于存储HTTPS证书
- bootstrap.kubernetes.io/token:用于存储引导令牌(Token)
四、Opaque类型Secret的创建与使用
Opaque是Secret的默认类型,是日常使用最广泛的类型,具体规范如下:
4.1 基础规则
- 未显式指定
Secret类型时,默认类型为Opaque,逻辑和Service未指定类型默认ClusterIP一致 - 创建Opaque类型
Secret需使用kubectl create secret generic子命令
4.2 核心编码要求
Secret的data字段的Value值必须经过Base64编码后才能写入资源清单,该要求是强制的:
- 未编码的值在被Pod使用时会被自动解码,必然出现乱码,无法正常使用
- Base64编码/解码是通用算法,和节点特征、指纹无关,任意环境执行相同输入的结果一致
- 编码示例:
echo -n "admin" | base64编码结果为YWRtaW4=;密码EFRD经Base64编码后为RUZSRA== - 解码示例:
echo -n "YWRtaW4=" | base64 -d可解码得到原始明文admin
4.3 资源清单结构示例
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
password: <Base64编码后的密码值>
username: <Base64编码后的用户名值>
4.4 实战操作演示
- 编写Secret资源清单文件
secret.yaml,填入Base64编码后的数据 - 执行
kubectl create -f secret.yaml创建Secret - 执行
kubectl get secret可查看Secret基本信息,仅显示Key和字节长度,不会显示明文Value - 执行
kubectl describe secret <secret-name>同样不会显示明文Value - 若需要获取明文Value,可执行
kubectl get secret <secret-name> -o yaml导出完整资源清单,再对data字段的Value执行Base64解码即可得到原始数据
五、Secret的使用方式(环境变量引用示例)
Secret可通过环境变量、卷插件等方式被Pod使用,以环境变量引用为例:
- 在Deployment的容器配置中,通过
valueFrom.secretKeyRef字段指定要引用的Secret名称和Key - 示例:配置环境变量
test_user引用Secretmy-secret中的username字段,环境变量test_password引用my-secret中的password字段 - Pod启动后,容器内执行
env命令即可看到自动解码后的明文值,无需手动处理解码逻辑
六、安全注意事项
Secret的Value仅经过Base64编码,并非强加密,集群管理员可直接解码获取明文,不能作为唯一的安全保护手段- 敏感度极高的数据需要配合其他加密方案使用,避免仅依赖
Secret存储 - 仅将
Secret分发给需要的Pod,减少暴露面
AI 总结
本节主要讲解Kubernetes中用于存储敏感数据的Secret资源,首先通过对比ConfigMap的明文存储局限性引出Secret的适用场景,明确了Secret的编码安全机制、集群层面的三层安全增强设计、7种常见细分类型;重点演示了默认Opaque类型的创建规范、Base64编码的强制要求、查看方式以及环境变量引用方式;最后强调了Secret仅能作为基础安全手段、不能作为唯一敏感数据保护方案的边界,为后续存储相关的实验操作打下基础。