当前位置: 首页 > news >正文

Kubernetes(K8s)笔记Day09 下 :加密配置管理中心 Secret 讲解与应用实例

一、Secret 概述

1.1 什么是 Secret?

简单来说,Secret 就是 ConfigMap 的“加密版”——专门用来存敏感数据的

Secret 是 Kubernetes 中用于保存敏感数据的资源对象,如密码、Token、密钥等。它的设计目的与 ConfigMap 类似——将配置与镜像解耦,但专门针对机密性数据。

ConfigMap vs Secret:ConfigMap 存放明文配置(如配置文件),Secret 存放敏感数据(如密码、私钥)。两者功能相似,但 Secret 在存储和传输中做了编码处理。

Secret 可以以Volume 挂载环境变量的方式被 Pod 使用。

需注意:Secret本质就是“加密版”的ConfigMap,二者在源码层面是同一种数据结构(data 字段)的不同包装,所以在语法上有惊人的相似度,使用方法也几乎完全一致

1.2 Secret 的可选类型

类型用途
generic(通用)最常用,用于存储密码、密钥等普通敏感数据
tls专门用于存储 TLS 私钥和证书
docker-registry用于存储私有 Docker 仓库的认证信息
kubernetes.io/service-account-token由 Kubernetes 自动创建,用于 ServiceAccount 身份认证

关于 ServiceAccount 的自动挂载:每个 ServiceAccount 创建时,Kubernetes 会为其自动创建一个对应的 Secret,并挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount目录下,用于 Pod 与 API Server 之间的认证通信。

1.3 Secret 的数据编码

Secret 的数据并非加密,而是Base64 编码。Base64 只是将原始数据转换成可打印字符,不属于真正的加密,可以轻松解码回原文。因此:

Secret 只是比 ConfigMap 多了一层编码,并非安全加密。对于极高安全要求的场景,建议配合外部加密工具(如 HashiCorp Vault)使用。

Base64 编码示例:

# 编码[root@hd1 ~]# echo -n 'admin' | base64YWRtaW4=[root@hd1 ~]# echo -n '123456' | base64MTIzNDU2# 解码[root@hd1 ~]# echo MTIzNDU2 | base64 -d123456

二、使用 Secret

2.1 通过环境变量引入 Secret(secretKeyRef

场景:将 Secret 中的某个 key 的值注入为 Pod 容器的环境变量。

语法:kubectl create secret <secret类型> <secret名> --from-literal=<key>=<value>

步骤1:创建 Secret

# 创建一个名为 mysql-password ,类型为 generic 的 Secret,包含 password=heihei66[root@hd1 ~]# kubectl create secret generic mysql-password --from-literal=password=heihei66# 查看 Secret 列表[root@hd1 ~]# kubectl get secretNAME TYPE DATA AGE mysql-password Opaque130s# 查看 Secret 详情(注意:实际值显示为字节数,不展示原文)[root@hd1 ~]# kubectl get secret mysql-password -o yamlapiVersion: v1 data: password:aGVpaGVpNjY=kind: Secret metadata: creationTimestamp:"2026-08-05T12:30:32Z"name: mysql-password namespace: default resourceVersion:"253749"uid: 47ee1b04-9fa9-4741-ba76-454d4271f1a2 type: Opaque[root@hd1 ~]# kubectl describe secret mysql-passwordName: mysql-password Namespace: default Labels:<none>Annotations:<none>Type: Opaque Data====password:8bytes#这里并不会显示出我们的数据信息#验证存入的是base64编码[root@hd1 ~]# kubectl get secret mysql-password -o yamlapiVersion: v1 data: password:aGVpaGVpNjY=#这里就是刚刚存入的数据,并非明文

步骤2:创建 Pod 引用该 Secret

[root@hd1 ~]# cat pod-secret.yamlapiVersion:v1kind:Podmetadata:name:pod-secretlabels:app:myappspec:containers:-name:myappimage:mysql:8.0imagePullPolicy:IfNotPresentports:-name:mysqlcontainerPort:3306env:-name:MYSQL_ROOT_PASSWORD# Pod 中的环境变量名,这个环境变量,对于使用官方 MySQL 容器镜像来说是必须的valueFrom:#与 secretKeyRef 作用一致secretKeyRef:name:mysql-password# Secret 名称key:password# 指定Secret 中的 key

可以看得出来,secret和ConfigMap的使用方法几乎完全一致

[root@hd1 ~]# kubectl apply -f pod-secret.yaml# 验证:进入 Pod 查看环境变量[root@hd1 ~]# kubectl exec -it pod-secret -- /bin/bash/# printenvMYSQL_ROOT_PASSWORD=heihei66

2.2 通过 Volume 挂载 Secret

使用yaml文件创建 Secret

方法一:手动创建加密数据

步骤1:手动创建包含 Base64 编码数据的 Secret

[root@hd1 ~]# echo -n 'admin' | base64YWRtaW4=[root@hd1 ~]# echo -n '123456' | base64MTIzNDU2

步骤2:编写 Secret YAML 文件

[root@hd1 ~]# vim secret.yamlapiVersion:v1kind:Secretmetadata:name:mysecrettype:Opaquedata:username:YWRtaW4=# base64 编码后的 adminpassword:MTIzNDU2# base64 编码后的 123456

方法二:使用stringData:可以让它自动生成
注意,我们使用stringData:可以让它自动生成

[root@hd1 ~]# vim secret.yamlapiVersion:v1kind:Secretmetadata:name:mysecrettype:OpaquestringData:#使用stringData: 直接配置明文即可username:"admin"password:"123456"
[root@hd1 ~]# kubectl apply -f secret.yaml[root@hd1 ~]# kubectl get secret mysecret -o yamlapiVersion: v1 data: password: MTIzNDU2 username:YWRtaW4=

步骤3:将 Secret 以 Volume 形式挂载到 Pod

[root@hd1 ~]# vim pod_secret_volume.yamlapiVersion:v1kind:Podmetadata:name:pod-secret-volumespec:containers:-name:myappimage:docker.io/library/nginx:latestimagePullPolicy:IfNotPresentvolumeMounts:-name:secret-volumemountPath:/etc/secretreadOnly:truevolumes:-name:secret-volumesecret:#指定类型为secretsecretName:mysecret#secret名称
[root@hd1 ~]# kubectl apply -f pod_secret_volume.yaml# 验证:Secret 数据在 Pod 中被解密为明文[root@hd1 ~]# kubectl exec -it pod-secret-volume -- /bin/bashroot@pod-secret-volume:/# ls /etc/secretpassword username#已经翻译成明文root@pod-secret-volume:/# cat /etc/secret/usernameadmin root@pod-secret-volume:/# cat /etc/secret/password123456

关键理解:Secret 存储在 etcd 中是 Base64 编码的,但挂载到 Pod 后,kubelet 会自动解码,所以容器内读取到的是明文

2.3 Docker 私有仓库认证:docker-registry类型

场景:Pod 需要从私有 Docker 仓库拉取镜像时,需要提供仓库认证信息。

步骤1:创建 docker-registry 类型的 Secret

创建一个docker镜像仓库类型的Secret,命名为regcred
格式为:
kubectl create secret docker-registry regcred \ --docker-server=<你的镜像仓库服务器> \ --docker-username=<你的用户名> \ --docker-password=<你的密码> \ --docker-email=<你的邮箱地址>

导入我们阿里云容器镜像服务(ACR,Alibaba Cloud Container Registry) 的凭证

#会在当前 Namespace 下创建一个docker-registry类型,名为 regcred 的 Secret[root@h1 ~]# kubectl create secret docker-registry regcred \--docker-server=registry.cn-hangzhou.aliyuncs.com\--docker-username=wmbenet@126.com\--docker-password=123.com.

凭证获取步骤:
镜像服务
管理后台
进入镜像仓库

步骤2:在 Pod 中引用该 Secret 拉取私有镜像

[root@h3 ~]# cat pod_secret_docker.yamlapiVersion:v1kind:Podmetadata:name:private-regspec:containers:-name:private-reg-containerimage:<your-private-image># 替换为你的私有镜像地址imagePullSecrets:# 【核心字段】拉取镜像时使用的凭证列表-name:regcred# 引用上一步创建的 Secret

注意imagePullSecrets字段设置在 Pod 级别,而非容器级别,表示拉取该 Pod 的所有镜像时使用的认证信息。

2.4 TLS 证书与私钥:tls类型

场景:为 Ingress 或服务间通信配置 TLS 证书。

语法:
kubectl create secret tls tls-secret \ --cert=path/to/tls.cert \ #证书路径 --key=path/to/tls.key #私钥路径

#生成证书和私钥[root@hd1 ~]# openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout abc.key -out abc.crt#将证书和私钥变成secret[root@hd1 ~]# kubectl create secret tls tls-secret --cert=abc.crt --key=abc.keysecret/tls-secret created

这个 Secret 的应用场景示例:

我们创建的这个 tls-secret,最典型的用法是挂载到 Ingress(网关) 上,让集群对外提供 HTTPS 服务

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:example-ingressspec:tls:-hosts:-www.myapp.comsecretName:tls-secret# 引用你刚才创建的 TLS Secretrules:-host:www.myapp.comhttp:paths:-path:/backend:service:name:my-serviceport:number:80

三、综合案例:部署 MySQL 并集成 ConfigMap + Secret

3.1 案例要求

  1. 用 Deployment 部署一个 MySQL 数据库
  2. my.cnf做成 ConfigMap,修改端口为33060,传入 Pod 配置文件路径
  3. 将 MySQL root 密码做成 Secret,以环境变量方式传入 Pod

3.2 实现步骤

步骤1:创建 ConfigMap(MySQL 配置文件)

# mysql-configmap.yamlapiVersion:v1kind:ConfigMapmetadata:name:mysql-configdata:my.cnf:|[mysqld] port=33060 socket=/var/run/mysqld/mysqld.sock

这段配置是把mysql的端口改成了33060,并指定了sock文件的路径

[root@hd1 ~]# kubectl apply -f mysql-configmap.yaml

步骤2:创建 Secret(MySQL root 密码)

这个就是我们在上文创建的

[root@hd1 ~]# kubectl create secret generic mysql-password --from-literal=password=123456

步骤3:创建 PVC(持久化存储)

这里使用的是存储类,还是我们之前创建的那个。忘记的可以回去看:Kubernetes(K8s)笔记Day06: 持久化存储7.4的步骤5和步骤6,把供应商和sc拉起来就行了

# mysql-pvc.yamlapiVersion:v1kind:PersistentVolumeClaimmetadata:name:mysql-pv-claimspec:storageClassName:nfsaccessModes:-ReadWriteOnceresources:requests:storage:2Gi
[root@hd1 ~]# kubectl apply -f mysql-pvc.yaml

步骤4:创建 Deployment(整合所有配置)

# mysql-deployment.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:mysqlspec:selector:matchLabels:app:mysqlstrategy:type:Recreate# 重建策略:先删旧 Pod,再建新 Pod(不是滚动更新!)template:metadata:labels:app:mysqlspec:containers:-image:mysql:8.0name:mysqlenv:-name:MYSQL_ROOT_PASSWORD#这个是注入mysql密码的标准的变量名称valueFrom:# 从外部资源取值secretKeyRef:#使用secret导入环境变量(依旧是mysql的密码)name:mysql-password#指定导入的secret名称key:password# Secret 中的键名ports:-containerPort:33060name:mysqlvolumeMounts:# 【存储挂载】容器内的挂载点-name:mysql-persistent-storagemountPath:/var/lib/mysql# MySQL 数据目录(存放库表文件)-name:mysql-config-volumemountPath:/etc/my.cnfsubPath:my.cnf#关键点,加上这个,在挂载的时候就不会完全覆盖目标路径,而是把特定文件导入,只替换这一个文件volumes:-name:mysql-persistent-storagepersistentVolumeClaim:claimName:mysql-pv-claim-name:mysql-config-volumeconfigMap:# 使用 ConfigMap 作为配置源name:mysql-config# ConfigMap 名称

这个配置文件利用了configmap的特性( secret 也一样),configmap的字段挂载进pod会变成文件,以此挂载用来替换特定的配置文件

[root@hd1 ~]# kubectl apply -f mysql-deployment.yaml

3.3 案例总结

这个案例利用ConfigMap 实现配置文件外置(端口修改),利用Secret 实现密码安全注入(环境变量),利用PVC 实现数据持久化(存储保留),利用Deployment 的 Recreate 策略保障单实例存储安全,最终完成了一个“配置可调、密码安全、数据不丢”的标准 MySQL 容器化部署

四、扩展命令:kubectl port-forward

kubectl port-forward能够在本地主机Kubernetes 集群中的 Pod之间建立端口转发,用于开发和调试场景。

作用:在不修改 Service 暴露配置(如 LoadBalancer 或 NodePort)的情况下,直接从本地访问集群内部的服务或应用。

kubectl delete pod --all

常用命令

# 监听宿主机的回环接口(127.0.0.1)kubectl port-forward<pod-name>8000:8080# 监听宿主机的所有接口(可被外部访问)kubectl port-forward--address0.0.0.0<pod-name>8000:8080

示例:如果你在集群中运行了一个 Web 应用(Pod 内监听 8080 端口),想在本机浏览器查看,执行kubectl port-forward <pod-name> 8000:8080后,即可通过http://127.0.0.1:8000访问该应用。

五、核心知识点速查

ConfigMap vs Secret 对比

特性ConfigMapSecret
用途存储非机密配置数据存储敏感数据(密码、密钥、证书)
数据格式明文Base64 编码(非加密,仅编码)
大小限制≤ 1 MiB≤ 1 MiB
使用方式环境变量 / Volume环境变量 / Volume / imagePullSecrets
热更新Volume 方式支持Volume 方式支持

Secret 使用方式总结

使用方式适用场景示例
环境变量(secretKeyRef将单个 key 注入为环境变量MySQL 密码注入为MYSQL_ROOT_PASSWORD
Volume 挂载将 Secret 作为文件挂载到目录TLS 证书、配置文件挂载
imagePullSecrets私有仓库镜像拉取认证从阿里云 ACR 拉取镜像

Secret 类型速查

类型用途
Opaque(通用)存储任意敏感数据(密码、API Key)
kubernetes.io/dockerconfigjsonDocker 私有仓库认证
kubernetes.io/tlsTLS 证书和私钥
kubernetes.io/service-account-tokenServiceAccount 认证(系统自动创建)

关键注意事项

注意点说明
Base64 不是加密Secret 仅做编码,不提供真正的加密保护
密钥大小限制Secret 数据大小 ≤ 1 MiB
命名空间隔离Secret 只能被同一命名空间的 Pod 引用
热更新支持Volume 方式支持热更新,环境变量方式不支持
http://www.cnnetsun.cn/news/3868227.html

相关文章:

  • 深度掌控AMD Ryzen处理器:SMUDebugTool终极调试指南
  • ncmdumpGUI:三步解锁网易云音乐ncm文件,实现跨设备播放自由
  • 慈溪建设局网站:数字化治理下的民生温度与城市更新的真实脉搏
  • LeetCode热题100——移动零
  • Oracle数据库Shared Pool与Buffer Cache内存优化实战
  • 手机直供电改造:解决移除电池后重启黑屏的硬件方案
  • MySQL数据库核心操作与优化实战指南
  • MySQL事务ACID特性与InnoDB日志机制详解
  • 揭秘2024网站建设云尚网络如何通过匠心独运打造行业标杆品牌并赋能企业数字化转型
  • 3分钟极速配置:告别GitHub网络延迟的终极加速方案
  • Sigmoid激活函数:从神经网络基础到梯度消失问题解析
  • 计算机毕业设计之基于spring boot的外卖平台小程序
  • Ubuntu 22.04 安装 SSH 服务与远程调试环境配置指南
  • 西宁网站建设开发怎么选?避开这些坑才是真省钱,本地团队告诉你大实话
  • AI 焦虑下,前端该何去何从
  • HarmonyOS 7 / API 26 折叠屏断点适配:页面宽度变化后列表、详情和弹窗怎么稳定
  • MinIO对象存储:轻量级云原生解决方案部署指南
  • 深入解析黑龙江省建设厅网站如何助力百姓办事与行业发展
  • nnUNet and its customization
  • FigmaCN:3分钟实现Figma完整中文界面的终极指南
  • Redis双写一致性:从延时双删到分布式锁与CDC的解决方案
  • ChatGPT教育插件实战指南:从原理到教学应用全解析
  • 测测动次打次我说的
  • 做青岛商网站建设,如何让企业官网从“能看”到“好用”?资深运营人的掏心窝子建议
  • 网站流量月增40%实战分析:从数据拆解到可复现增长策略
  • 品牌域名回购注意事项
  • Unity TextMesh Pro中文显示“口口”乱码:原理剖析与全平台解决方案
  • 龙华新区网站建设指南:如何打造真正转化率高、用户体验佳的数字化品牌门面
  • DeepSeek LeetCode 3821. 二进制中恰好K个1的第N小整数 Python3实现
  • QKeyMapper:Windows平台终极跨设备按键映射解决方案