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

📅 2026/8/6 11:22:34
Kubernetes(K8s)笔记Day09 下 :加密配置管理中心 Secret 讲解与应用实例
一、Secret 概述1.1 什么是 Secret简单来说Secret 就是 ConfigMap 的“加密版”——专门用来存敏感数据的Secret 是 Kubernetes 中用于保存敏感数据的资源对象如密码、Token、密钥等。它的设计目的与 ConfigMap 类似——将配置与镜像解耦但专门针对机密性数据。ConfigMap vs SecretConfigMap 存放明文配置如配置文件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 编码示例# 编码[roothd1 ~]# echo -n admin | base64YWRtaW4[roothd1 ~]# echo -n 123456 | base64MTIzNDU2# 解码[roothd1 ~]# echo MTIzNDU2 | base64 -d123456二、使用 Secret2.1 通过环境变量引入 SecretsecretKeyRef场景将 Secret 中的某个 key 的值注入为 Pod 容器的环境变量。语法kubectl create secret secret类型 secret名 --from-literalkeyvalue步骤1创建 Secret# 创建一个名为 mysql-password 类型为 generic 的 Secret包含 passwordheihei66[roothd1 ~]# kubectl create secret generic mysql-password --from-literalpasswordheihei66# 查看 Secret 列表[roothd1 ~]# kubectl get secretNAME TYPE DATA AGE mysql-password Opaque130s# 查看 Secret 详情注意实际值显示为字节数不展示原文[roothd1 ~]# kubectl get secret mysql-password -o yamlapiVersion: v1 data: password:aGVpaGVpNjYkind: Secret metadata: creationTimestamp:2026-08-05T12:30:32Zname: mysql-password namespace: default resourceVersion:253749uid: 47ee1b04-9fa9-4741-ba76-454d4271f1a2 type: Opaque[roothd1 ~]# kubectl describe secret mysql-passwordName: mysql-password Namespace: default Labels:noneAnnotations:noneType: Opaque Datapassword:8bytes#这里并不会显示出我们的数据信息#验证存入的是base64编码[roothd1 ~]# kubectl get secret mysql-password -o yamlapiVersion: v1 data: password:aGVpaGVpNjY#这里就是刚刚存入的数据并非明文步骤2创建 Pod 引用该 Secret[roothd1 ~]# 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的使用方法几乎完全一致[roothd1 ~]# kubectl apply -f pod-secret.yaml# 验证进入 Pod 查看环境变量[roothd1 ~]# kubectl exec -it pod-secret -- /bin/bash/# printenvMYSQL_ROOT_PASSWORDheihei662.2 通过 Volume 挂载 Secret使用yaml文件创建 Secret方法一手动创建加密数据步骤1手动创建包含 Base64 编码数据的 Secret[roothd1 ~]# echo -n admin | base64YWRtaW4[roothd1 ~]# echo -n 123456 | base64MTIzNDU2步骤2编写 Secret YAML 文件[roothd1 ~]# vim secret.yamlapiVersion:v1kind:Secretmetadata:name:mysecrettype:Opaquedata:username:YWRtaW4# base64 编码后的 adminpassword:MTIzNDU2# base64 编码后的 123456方法二使用stringData:可以让它自动生成注意我们使用stringData:可以让它自动生成[roothd1 ~]# vim secret.yamlapiVersion:v1kind:Secretmetadata:name:mysecrettype:OpaquestringData:#使用stringData: 直接配置明文即可username:adminpassword:123456[roothd1 ~]# kubectl apply -f secret.yaml[roothd1 ~]# kubectl get secret mysecret -o yamlapiVersion: v1 data: password: MTIzNDU2 username:YWRtaW4步骤3将 Secret 以 Volume 形式挂载到 Pod[roothd1 ~]# 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名称[roothd1 ~]# kubectl apply -f pod_secret_volume.yaml# 验证Secret 数据在 Pod 中被解密为明文[roothd1 ~]# kubectl exec -it pod-secret-volume -- /bin/bashrootpod-secret-volume:/# ls /etc/secretpassword username#已经翻译成明文rootpod-secret-volume:/# cat /etc/secret/usernameadmin rootpod-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你的邮箱地址导入我们阿里云容器镜像服务ACRAlibaba Cloud Container Registry 的凭证#会在当前 Namespace 下创建一个docker-registry类型名为 regcred 的 Secret[rooth1 ~]# kubectl create secret docker-registry regcred \--docker-serverregistry.cn-hangzhou.aliyuncs.com\--docker-usernamewmbenet126.com\--docker-password123.com.凭证获取步骤镜像服务管理后台进入镜像仓库步骤2在 Pod 中引用该 Secret 拉取私有镜像[rooth3 ~]# 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 \ --certpath/to/tls.cert \ #证书路径 --keypath/to/tls.key #私钥路径#生成证书和私钥[roothd1 ~]# openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout abc.key -out abc.crt#将证书和私钥变成secret[roothd1 ~]# kubectl create secret tls tls-secret --certabc.crt --keyabc.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 Secret3.1 案例要求用 Deployment 部署一个 MySQL 数据库将my.cnf做成 ConfigMap修改端口为33060传入 Pod 配置文件路径将 MySQL root 密码做成 Secret以环境变量方式传入 Pod3.2 实现步骤步骤1创建 ConfigMapMySQL 配置文件# mysql-configmap.yamlapiVersion:v1kind:ConfigMapmetadata:name:mysql-configdata:my.cnf:|[mysqld] port33060 socket/var/run/mysqld/mysqld.sock这段配置是把mysql的端口改成了33060并指定了sock文件的路径[roothd1 ~]# kubectl apply -f mysql-configmap.yaml步骤2创建 SecretMySQL root 密码这个就是我们在上文创建的[roothd1 ~]# kubectl create secret generic mysql-password --from-literalpassword123456步骤3创建 PVC持久化存储这里使用的是存储类还是我们之前创建的那个。忘记的可以回去看KubernetesK8s笔记Day06 持久化存储7.4的步骤5和步骤6把供应商和sc拉起来就行了# mysql-pvc.yamlapiVersion:v1kind:PersistentVolumeClaimmetadata:name:mysql-pv-claimspec:storageClassName:nfsaccessModes:-ReadWriteOnceresources:requests:storage:2Gi[roothd1 ~]# 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会变成文件以此挂载用来替换特定的配置文件[roothd1 ~]# kubectl apply -f mysql-deployment.yaml3.3 案例总结这个案例利用ConfigMap 实现配置文件外置端口修改利用Secret 实现密码安全注入环境变量利用PVC 实现数据持久化存储保留利用Deployment 的 Recreate 策略保障单实例存储安全最终完成了一个“配置可调、密码安全、数据不丢”的标准 MySQL 容器化部署四、扩展命令kubectl port-forwardkubectl port-forward能够在本地主机和Kubernetes 集群中的 Pod之间建立端口转发用于开发和调试场景。作用在不修改 Service 暴露配置如 LoadBalancer 或 NodePort的情况下直接从本地访问集群内部的服务或应用。kubectl delete pod --all常用命令# 监听宿主机的回环接口127.0.0.1kubectl port-forwardpod-name8000:8080# 监听宿主机的所有接口可被外部访问kubectl port-forward--address0.0.0.0pod-name8000: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_PASSWORDVolume 挂载将 Secret 作为文件挂载到目录TLS 证书、配置文件挂载imagePullSecrets私有仓库镜像拉取认证从阿里云 ACR 拉取镜像Secret 类型速查类型用途Opaque通用存储任意敏感数据密码、API Keykubernetes.io/dockerconfigjsonDocker 私有仓库认证kubernetes.io/tlsTLS 证书和私钥kubernetes.io/service-account-tokenServiceAccount 认证系统自动创建关键注意事项注意点说明Base64 不是加密Secret 仅做编码不提供真正的加密保护密钥大小限制Secret 数据大小 ≤ 1 MiB命名空间隔离Secret 只能被同一命名空间的 Pod 引用热更新支持Volume 方式支持热更新环境变量方式不支持