news 2026/8/6 11:22:29

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 方式支持热更新,环境变量方式不支持
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/6 11:22:02

深度掌控AMD Ryzen处理器:SMUDebugTool终极调试指南

深度掌控AMD Ryzen处理器&#xff1a;SMUDebugTool终极调试指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitc…

作者头像 李华
网站建设 2026/8/6 11:21:02

ncmdumpGUI:三步解锁网易云音乐ncm文件,实现跨设备播放自由

ncmdumpGUI&#xff1a;三步解锁网易云音乐ncm文件&#xff0c;实现跨设备播放自由 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经在网易云音乐下载…

作者头像 李华
网站建设 2026/8/6 11:20:58

慈溪建设局网站:数字化治理下的民生温度与城市更新的真实脉搏

在这个信息爆炸的时代,我们每天都被各种碎片化的数据包围,但真正能沉下心来,去关注一座城市如何生长、如何呼吸的,或许并不多。对于生活在慈溪这片热土上的居民,或是关注长三角一体化的观察者来说,城市建设早已不是遥不可及的黑盒游戏,而是关乎每一户人家供暖、每一条道…

作者头像 李华
网站建设 2026/8/6 11:20:49

LeetCode热题100——移动零

解法一&#xff1a;统计零 erase/remove&#x1f4a1; 解题思路这道题要求把数组中的所有 0 移到末尾&#xff0c;同时保持非零元素原来的相对顺序。第一种方法可以分成三步&#xff1a;遍历数组&#xff0c;统计一共有多少个 0。使用 remove() 配合 erase() 删除数组中的所有…

作者头像 李华
网站建设 2026/8/6 11:18:22

Oracle数据库Shared Pool与Buffer Cache内存优化实战

1. 问题现象与背景分析最近在排查一个Oracle数据库性能问题时&#xff0c;遇到了典型的"数据库卡死"现象&#xff1a;应用连接超时、SQL执行缓慢、甚至出现会话挂起。通过AWR报告分析发现&#xff0c;问题集中在Shared Pool和Buffer Cache的内存争用上。这种情况在OL…

作者头像 李华
网站建设 2026/8/6 11:18:16

手机直供电改造:解决移除电池后重启黑屏的硬件方案

1. 项目概述&#xff1a;手机直供电改造的“重启黑屏”困局 最近折腾了一个挺有意思的项目&#xff0c;也踩了不少坑&#xff0c;想和大家分享一下。核心就是标题里说的&#xff1a;给一部旧手机做直供电改造&#xff0c;拆掉内置电池&#xff0c;直接用外部的充电器或者充电宝…

作者头像 李华