K8S(十)—— Kubernetes核心组件详解:Pod控制器与配置资源管理
文章目录
- 前言
- 一、Pod控制器
- 1.1 Pod控制器概述
- 1.1.1 核心功能
- 1.2 Pod控制器的类型
- 1.3 Deployment控制器
- 1.3.1 核心特点
- 1.3.2 部署案例
- 1.3.3 查看与修改控制器配置
- 1.4 StatefulSet控制器(有状态应用)
- 1.4.1 核心特点
- 1.4.2 核心组件
- 1.4.3 关键问题解析
- 1.4.4 部署案例(StatefulSet + NFS持久卷)
- 步骤1:定义Headless Service
- 步骤2:定义StatefulSet配置
- 步骤3:创建与验证
- 步骤4:滚动更新
- 步骤5:Pod名称解析验证
- 1.4.5 StatefulSet总结
- 无状态与有状态
- 无状态(Stateless):
- 有状态(Stateful):
- 常规 Service 和无头服务(Headless Service)区别:
- Service:
- Headless Service:
- 1.5 DaemonSet控制器
- 1.5.1 核心功能
- 1.5.2 部署案例
- 1.6 Job控制器
- 1.6.1 核心功能
- 1.6.2 部署案例1(计算π值)
- 1.6.3 部署案例2(失败重试演示)
- 1.7 CronJob控制器
- 1.7.1 核心功能
- 1.7.2 部署案例(每分钟打印消息)
- 1.8 无状态 vs 有状态应用对比
- 1.9 常规Service与Headless Service对比
- 1.10 附录:Kubernetes服务发现机制
- 1.11 总结
- 二、配置资源管理
- 2.1 Secret(密钥管理)
- 2.1.1 概念
- 2.1.2 Secret类型
- 2.1.3 创建Secret的方式
- 方式1:命令行创建(从文件)
- 方式2:YAML文件创建(Base64编码)
- 2.1.4 使用Secret的方式
- 方式1:作为Volume挂载到Pod
- 方式2:作为环境变量注入Pod
- 2.2 ConfigMap(配置管理)
- 2.2.1 概念
- 2.2.2 创建ConfigMap的方式
- 方式1:从目录创建
- 方式2:从指定文件创建
- 方式3:从字面值创建(键值对)
- 2.2.3 在Pod中使用ConfigMap的方式
- 方式1:作为环境变量注入
- 方式2:作为命令行参数使用
- 方式3:以Volume形式挂载
- 2.2.4 ConfigMap热更新机制
- 2.2.5 触发Pod滚动更新
- 2.3 Secret与ConfigMap对比总结
- 总结
前言
在Kubernetes(K8s)集群管理中,Pod作为最小部署单元,其生命周期的自动化管理与配置数据的安全高效运维是核心需求。
Pod控制器(工作负载)通过定义期望状态实现Pod的自动扩缩容、故障重建、滚动更新等能力,而配置资源(Secret与ConfigMap)则专门处理敏感信息与普通配置的存储与使用,二者共同构成了K8s应用部署的基础框架。
本文将详细解析各类Pod控制器的特性、应用场景及配置方式,并深入探讨Secret与ConfigMap的使用技巧,帮助开发者与运维人员高效管理K8s集群中的应用资源。
一、Pod控制器
1.1 Pod控制器概述
Pod控制器(Controller) 又称为工作负载(Workload),是Kubernetes中位于用户与Pod之间的中间层组件。其核心职责是持续监控集群中Pod的实际状态,并通过动态调整(如创建、删除、重启Pod)确保实际状态与用户定义的期望状态一致。
1.1.1 核心功能
- 副本数量保障:严格保证集群中运行的Pod副本数量与用户指定的数量一致,避免因节点故障等原因导致的副本缺失。
- 故障自愈:当Pod因容器崩溃、节点离线等原因异常退出时,根据预设的重启策略自动重建Pod,提升应用可用性。
- 弹性伸缩:支持手动或自动(结合HPA)调整Pod副本数量,应对业务流量的动态变化。
- 版本管理:提供滚动更新、版本回滚能力,确保应用升级过程中业务不中断。
1.2 Pod控制器的类型
Kubernetes提供了多种类型的Pod控制器,分别适用于不同的应用场景,具体如下表所示:
控制器 | 功能说明 | 典型应用场景 |
---|---|---|
ReplicaSet | 保证指定数量的Pod副本始终运行,支持基于标签的Pod选择与滚动扩缩容;通常不直接使用,而是作为Deployment的底层组件。 | 无状态应用的副本管理(底层支持) |
Deployment | 基于ReplicaSet实现,提供声明式部署、滚动升级、版本回滚、历史版本管理等增强功能。 | Web服务、API接口等无状态应用 |
StatefulSet | 专为有状态应用设计,提供稳定的Pod名称、网络标识(DNS)与持久存储,支持有序部署与删除。 | 数据库(MySQL、PostgreSQL)、分布式协调服务(Zookeeper、etcd) |
DaemonSet | 确保集群中每个(或指定)节点上运行且仅运行一个Pod副本,节点新增时自动部署,节点移除时自动清理。 | 日志收集(Fluentd、Logstash)、监控代理(Prometheus Node Exporter)、存储插件(Ceph、GlusterFS客户端) |
Job | 用于执行一次性任务,任务完成(Pod成功退出)后自动终止,支持失败重试机制。 | 数据迁移、批处理计算、安全扫描 |
CronJob | 基于时间调度的周期性任务(类似Linux的Crontab),可定义任务执行频率与保留策略。 | 定期数据备份、日志清理、定时通知 |
1.3 Deployment控制器
Deployment是Kubernetes中最常用的控制器之一,主要用于管理无状态应用,通过封装ReplicaSet实现了更强大的应用生命周期管理能力。
1.3.1 核心特点
- 无状态应用适配:适用于所有Pod副本完全一致(无本地状态依赖)的应用,如Web服务器、API服务等。
- 滚动更新:升级应用时,逐步替换旧Pod(先创建新Pod,再删除旧Pod),避免业务中断。
- 版本回滚:支持回滚到历史版本,应对升级失败场景。
- 声明式配置:通过YAML文件定义期望状态,K8s自动协调实际状态与期望状态。
1.3.2 部署案例
步骤1:创建Deployment配置文件
vim nginx-deployment.yaml
# nginx-deployment.yaml
apiVersion: apps/v1 # Deployment的API版本,固定为apps/v1
kind: Deployment # 资源类型为Deployment
metadata:name: nginx-deployment # Deployment名称labels:app: nginx # 为Deployment添加标签,用于资源关联
spec:replicas: 3 # 期望的Pod副本数量selector:matchLabels: # 标签选择器,用于关联需要管理的Podapp: nginxtemplate: # Pod模板,定义Pod的具体配置metadata:labels:app: nginx # Pod的标签,需与selector.matchLabels一致spec:containers:- name: nginx # 容器名称image: nginx:1.15.4 # 容器镜像ports:- containerPort: 80 # 容器暴露的端口
步骤2:创建Deployment资源
kubectl create -f nginx-deployment.yaml
步骤3:验证部署结果
# 查看Pod、Deployment、ReplicaSet状态
kubectl get pods,deploy,rs
1.3.3 查看与修改控制器配置
查看Deployment详细配置:
kubectl edit deployment/nginx-deployment
配置中关键字段说明:
apiVersion: apps/v1
kind: Deployment
metadata:annotations:deployment.kubernetes.io/revision: "1"creationTimestamp: "2021-04-19T08:13:50Z"generation: 1labels:app: nginx #Deployment资源的标签name: nginx-deploymentnamespace: defaultresourceVersion: "167208"selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deploymentuid: d9d3fef9-20d2-4196-95fb-0e21e65af24a
spec:progressDeadlineSeconds: 600replicas: 3 #期望的pod数量,默认是1revisionHistoryLimit: 10selector:matchLabels:app: nginxstrategy:rollingUpdate:maxSurge: 25% #升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值maxUnavailable: 25% #升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值type: RollingUpdate #滚动升级template:metadata:creationTimestamp: nulllabels:app: nginx #Pod副本关联的标签spec:containers:- image: nginx:1.15.4 #镜像名称imagePullPolicy: IfNotPresent #镜像拉取策略name: nginxports:- containerPort: 80 #容器暴露的监听端口protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: Always #容器重启策略schedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
......
修改spec.containers.image为nginx:1.16,查看结果
查看历史版本:
kubectl rollout history deployment nginx-deployment
1.4 StatefulSet控制器(有状态应用)
StatefulSet专为有状态应用设计,解决了Deployment无法满足的稳定标识、有序部署、独立存储等需求。
1.4.1 核心特点
- 稳定存储:通过PVC(PersistentVolumeClaim)为每个Pod分配独立的持久化存储,确保Pod重建后数据不丢失。
- 稳定网络标识:Pod名称固定为
<statefulset-name>-<ordinal-index>
(如myapp-0、myapp-1),DNS域名格式为<pod-name>.<service-name>.<namespace>.svc.cluster.local
,便于集群内服务发现。 - 有序部署与删除:部署时按序号从0到N-1依次创建Pod,确保前置Pod就绪后再创建后续Pod;删除时按序号从N-1到0依次销毁。
- 依赖Headless Service:需要配合无头服务(Headless Service)实现Pod的DNS解析。
1.4.2 核心组件
- Headless Service(无头服务):无ClusterIP,通过DNS直接返回Pod的IP地址,为StatefulSet的Pod提供稳定的网络标识。
- volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
- StatefulSet控制器:管理Pod的生命周期,确保按序部署、更新与销毁。
1.4.3 关键问题解析
-
为什么需要Headless Service?
Deployment的Pod名称是随机字符串(如nginx-deploy-7f89d6f45-2xqk9),无固定标识;而StatefulSet要求Pod标识稳定(名称、网络地址),Headless Service通过DNS记录直接绑定Pod名称与IP,实现稳定访问。 -
为什么需要volumeClaimTemplates?
有状态应用(如数据库)每个节点需独立存储(数据不共享),而Deployment的Pod模板中定义的存储卷为共享卷;volumeClaimTemplates可自动为每个Pod创建独立PVC,确保存储隔离。
1.4.4 部署案例(StatefulSet + NFS持久卷)
步骤1:定义Headless Service
vim stateful-headless.yaml
# stateful-headless.yaml
apiVersion: v1
kind: Service
metadata:name: myapp-svc # 服务名称,将用于Pod的DNS解析
spec:ports:- port: 80name: web # 端口名称,可选clusterIP: None # 设为None表示无头服务selector:app: myapp-pod # 关联标签,需与StatefulSet的Pod标签一致
创建服务:
kubectl apply -f stateful-headless.yaml
步骤2:定义StatefulSet配置
vim stateful-demo.yaml
# stateful-demo.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: myapp # StatefulSet名称
spec:serviceName: myapp-svc # 关联的Headless Service名称(必须存在)replicas: 3 # 副本数量selector:matchLabels:app: myapp-pod # 标签选择器,关联Podtemplate:metadata:labels:app: myapp-pod # Pod标签,需与selector一致spec:containers:- name: myappimage: ikubernetes/myapp:v1 # 容器镜像ports:- containerPort: 80name: webvolumeMounts:- name: myappdata # 挂载卷名称,需与volumeClaimTemplates.name一致mountPath: /usr/share/nginx/html # 容器内挂载路径volumeClaimTemplates: # 存储卷申请模板- metadata:name: myappdata # 卷名称,与volumeMounts.name对应annotations: #动态PV创建时,使用annotations在PVC里声明一个StorageClass对象的标识进行关联volume.beta.kubernetes.io/storage-class: nfs-client-storageclassspec:accessModes: ["ReadWriteOnce"] # 访问模式(单节点读写)resources:requests:storage: 2Gi # 申请的存储大小
解析上例:
- 由于 StatefulSet 资源依赖于一个实现存在的 Headless 类型的 Service 资源,所以需要先定义一个名为 myapp-svc 的 Headless Service 资源,用于为关联到每个 Pod 资源创建 DNS 资源记录。
- 接着定义了一个名为 myapp 的 StatefulSet 资源,它通过 Pod 模板创建了 3 个 Pod 资源副本,并基于 volumeClaimTemplates 向前面创建的PV进行了请求大小为 2Gi 的专用存储卷。
步骤3:创建与验证
# 创建StatefulSet
kubectl apply -f stateful-demo.yaml# 查看状态(sts为StatefulSet的缩写)
kubectl get sts,pvc,pv,pods
步骤4:滚动更新
StatefulSet的更新按序号从高到低(如2→1→0)依次进行,确保每个Pod更新完成并就绪后再处理下一个:
# 编辑StatefulSet,修改镜像版本(如将ikubernetes/myapp:v1改为v2)
kubectl edit sts myapp# 观察更新过程
# 它将以与 Pod 终止相同的顺序进行(从最大的序数到最小的序数),每次更新一个 Pod。在更新其前身之前,它将等待正在更新的 Pod 状态变成正在运行并就绪。
kubectl get pods -w
步骤5:Pod名称解析验证
StatefulSet的Pod可通过固定DNS域名访问:
# 进入其中一个Pod
kubectl exec -it myapp-0 /bin/sh# 解析其他Pod的DNS(格式:<pod-name>.<service-name>.<namespace>.svc.cluster.local)
nslookup myapp-1.myapp-svc.default.svc.cluster.local
1.4.5 StatefulSet总结
无状态与有状态
无状态(Stateless):
- Deployment 认为所有的 Pod 都是一样的。
- 无需考虑顺序要求。
- 不关心 Pod 在哪个 Node 上运行。
- 可以随意扩容和缩容。
有状态(Stateful):
- 实例之间存在差别,每个实例有其独特性,且元数据不同(如 etcd, zookeeper)。
- 实例之间的关系是对等的,且依赖外部存储的应用。
常规 Service 和无头服务(Headless Service)区别:
Service:
- 一组 Pod 的访问策略,提供 Cluster-IP 群集之间的通信。
- 提供负载均衡和服务发现。
Headless Service:
- 无头服务,不需要 Cluster-IP。
- 直接通过 DNS 记录解析被代理 Pod 的 IP 地址。
1.5 DaemonSet控制器
DaemonSet确保集群中每个节点(或符合条件的节点)运行且仅运行一个Pod副本,适用于需要在所有节点部署的系统级服务。
1.5.1 核心功能
- 节点全覆盖:新节点加入集群时,自动部署对应的Pod;节点移除时,自动删除Pod。
- 资源独占:每个节点仅运行一个副本,避免资源浪费。
- 系统级任务:常用于部署日志收集、监控代理、存储插件等节点级服务。
1.5.2 部署案例
vim ds.yaml
# ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:name: nginx-daemonset # DaemonSet名称labels:app: nginx
spec:selector:matchLabels:app: nginx # 标签选择器,关联Podtemplate:metadata:labels:app: nginx # Pod标签spec:containers:- name: nginximage: nginx:1.15.4 # 容器镜像ports:- containerPort: 80 # 暴露端口
创建并验证:
kubectl apply -f ds.yaml# 查看Pod(每个节点将有一个以nginx-daemonSet-为前缀的Pod)
kubectl get pods
1.6 Job控制器
Job用于执行一次性任务(如数据迁移、批处理),任务完成后Pod自动终止,不会重启。
1.6.1 核心功能
- 任务完成即终止:当Pod成功退出(exit code=0),Job标记为完成。
- 失败重试:支持配置失败重试次数,避免临时错误导致任务终止。
- 并行执行:可配置并行运行的Pod数量(可选)。
应用场景:数据迁移、批处理、安全扫描、离线数据处理
1.6.2 部署案例1(计算π值)
vim job.yaml
# job.yaml
apiVersion: batch/v1
kind: Job
metadata:name: pi # Job名称
spec:template:spec:containers:- name: piimage: perl # 基于perl镜像执行计算command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] # 计算π的2000位小数restartPolicy: Never # 任务失败后不重启Pod(Job中仅允许Never或OnFailure,否则Job将不间断运行)backoffLimit: 4 # 失败重试次数(默认6次)
操作步骤:
# 提前拉取镜像(避免部署时等待)
docker pull perl# 创建Job
kubectl apply -f job.yaml# 查看Pod状态(完成后状态为Completed)
kubectl get pods# 查看任务结果
kubectl logs <pod-name> # 替换为实际Pod名称,如pi-5tqrb# 清理Job资源
kubectl delete -f job.yaml
1.6.3 部署案例2(失败重试演示)
vim job-limit.yaml
# job-limit.yaml
apiVersion: batch/v1
kind: Job
metadata:name: busybox
spec:template:spec:containers:- name: busyboximage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 10; date; exit 1"] # 执行后以错误码1退出(模拟失败)restartPolicy: NeverbackoffLimit: 2 # 最多重试2次
================================================================
#command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
容器启动后执行的命令:sleep 10 → 先睡眠 10 秒date → 打印当前日期exit 1 → 以 退出码 1 结束容器(即任务失败)
验证重试机制:
kubectl apply -f job-limit.yaml# 查看Job和Pod状态(将创建3个Pod:1个初始+2次重试)
kubectl get job,pods# 查看Job事件(确认重试次数超限)
kubectl describe job busybox
1.7 CronJob控制器
CronJob基于时间调度周期性任务,类似Linux的Crontab,适用于定时备份、定时通知、日志清理等场景。
1.7.1 核心功能
- 时间调度:支持Cron表达式定义执行频率(如每分钟、每天凌晨)。
- 任务生命周期:自动创建Job执行任务,可配置历史任务保留数量。
- 并发控制:支持配置并发策略(允许、禁止、替换)。
1.7.2 部署案例(每分钟打印消息)
vim cronjob.yaml
# cronjob.yaml
apiVersion: batch/v1beta1 # 注意:Kubernetes 1.21+版本使用batch/v1,旧版本可能为batch/v1beta1
kind: CronJob
metadata:name: hello # CronJob名称
spec:schedule: "*/1 * * * *" # Cron表达式(每分钟执行一次)jobTemplate: # 任务模板(定义具体执行的Job)spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello from the Kubernetes cluster # 执行命令:打印时间和消息restartPolicy: OnFailure # 任务失败时重启容器
================================================================
#cronjob其它可用参数的配置
spec:concurrencyPolicy: Allow #要保留的失败的完成作业数(默认为1)schedule: '*/1 * * * *' #作业时间表。在此示例中,作业将每分钟运行一次startingDeadlineSeconds: 15 #pod必须在规定时间后的15秒内开始执行,若超过该时间未执行,则任务将不运行,且标记失败successfulJobsHistoryLimit: 3 #要保留的成功完成的作业数(默认为3)terminationGracePeriodSeconds: 30 #job存活时间 默认不设置为永久jobTemplate: #作业模板。这类似于工作示例
操作步骤:
# 创建CronJob
kubectl create -f cronjob.yaml# 查看CronJob状态
kubectl get cronjob
# 查看生成的Pod(每分钟创建一个,完成后状态为Completed)
kubectl get pods# 查看任务输出
kubectl logs <pod-name> # 替换为实际Pod名称,如hello-1621587180-mffj6# 清理资源
kubectl delete cronjob hello
# 如果报错:Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)
# 解决办法:绑定一个cluster-admin的权限
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
1.8 无状态 vs 有状态应用对比
对比项 | 无状态应用(Deployment) | 有状态应用(StatefulSet) |
---|---|---|
Pod名称 | 随机生成(如nginx-deploy-7f89d6f45-2xqk9) | 固定有序(如myapp-0、myapp-1) |
存储方式 | 共享存储或无持久卷 | 每个Pod独立PVC(数据隔离) |
网络标识 | 不固定(通过Service负载均衡) | 稳定DNS名称(<pod-name>.<service-name>) |
扩缩容顺序 | 无序(同时创建/删除) | 有序(0→N-1创建,N-1→0删除) |
应用示例 | Web服务、API接口 | 数据库、分布式协调服务(ZooKeeper) |
1.9 常规Service与Headless Service对比
服务类型 | 是否有ClusterIP | 访问方式 | 主要作用 |
---|---|---|---|
常规Service | 有 | 通过ClusterIP负载均衡访问 | 为无状态应用提供统一访问入口与负载均衡 |
Headless Service | 无 | 直接解析到Pod的IP地址 | 为StatefulSet提供稳定的Pod DNS解析能力 |
1.10 附录:Kubernetes服务发现机制
Kubernetes通过内置DNS组件实现集群内服务发现,不同版本使用的DNS组件如下:
- 1.3版本之前:SkyDNS
- 1.3 ~ 1.11版本:KubeDNS
- 1.11版本之后:CoreDNS(当前主流)
Pod间通信域名格式:
<pod-name>.<service-name>.<namespace>.svc.cluster.local
例如:myapp-0.myapp-svc.default.svc.cluster.local(myapp-0为Pod名称,myapp-svc为Headless Service名称,default为命名空间)
1.11 总结
控制器 | 是否有状态 | 功能简述 |
---|---|---|
Deployment | ❌ | 无状态应用部署、滚动升级 |
ReplicaSet | ❌ | 保证副本数量,通常由 Deployment 管理 |
StatefulSet | ✅ | 有状态应用,稳定网络与存储 |
DaemonSet | ❌ | 每个节点运行一个 Pod |
Job | ❌ | 一次性任务 |
CronJob | ❌ | 周期性任务 |
二、配置资源管理
在Kubernetes中,配置资源用于管理应用的配置信息与敏感数据,避免将配置硬编码到镜像或Pod定义中,提升配置灵活性与安全性。
2.1 Secret(密钥管理)
2.1.1 概念
Secret用于存储集群中的敏感数据,如密码、Token、SSH密钥、TLS证书等。其核心作用是将敏感信息与Pod定义分离,通过权限控制(RBAC)限制访问,降低数据泄露风险。
2.1.2 Secret类型
类型 | 说明 |
---|---|
kubernetes.io/service-account-token | K8s自动创建,用于Pod访问APIServer的认证令牌;默认挂载到Pod的/run/secrets/kubernetes.io/serviceaccount 目录。 |
Opaque | 默认类型,用户自定义敏感数据(如密码、密钥),数据以Base64编码存储(注意:Base64编码并非加密,需通过权限控制保护)。 |
kubernetes.io/dockerconfigjson | 存储私有Docker仓库的认证信息,供kubelet拉取私有镜像时使用。 |
kubernetes.io/tls | 存储SSL/TLS证书与私钥,常用于Ingress或服务间加密通信。 |
使用前提:Pod必须显式引用Secret才能使用其数据。
使用方式:
- 作为 Volume 文件 挂载。
- 作为 环境变量。
- kubelet 拉取镜像时使用认证信息。
应用场景:凭据管理
官方文档:https://kubernetes.io/docs/concepts/configuration/secret/
2.1.3 创建Secret的方式
方式1:命令行创建(从文件)
# 创建存储用户名和密码的文件
echo -n 'zhangsan' > username.txt # -n避免添加换行符
echo -n 'abc1234' > password.txt# 从文件创建Opaque类型的Secret
kubectl create secret generic mysecret --from-file=username.txt --from-file=password.txt
查看Secret:
# 列出所有Secret
kubectl get secrets# 查看Secret详情(数据将以Base64显示)
kubectl describe secret mysecret
方式2:YAML文件创建(Base64编码)
步骤1:对敏感数据进行Base64编码
echo -n 'zhangsan' | base64 # 输出:emhhbmdzYW4=
echo -n 'abc1234' | base64 # 输出:YWJjMTIzNA==
步骤2:编写YAML配置
vim secret.yaml
# secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mysecret1 # Secret名称
type: Opaque # 类型为用户自定义
data:username: emhhbmdzYW4= # Base64编码的用户名password: YWJjMTIzNA== # Base64编码的密码
步骤3:创建Secret
kubectl apply -f secret.yaml# 验证创建结果
kubectl get secret mysecret1 -o yaml
2.1.4 使用Secret的方式
方式1:作为Volume挂载到Pod
将Secret数据以文件形式挂载到容器的指定目录,适用于需要读取配置文件的场景。
vim pod-with-secret-volume.yaml
# pod-with-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: nginximage: nginxvolumeMounts:- name: secrets # 挂载卷名称,与volumes.name一致mountPath: "/etc/secrets" # 容器内挂载路径readOnly: true # 只读权限(推荐)volumes:- name: secretssecret:secretName: mysecret # 引用的Secret名称
验证:
kubectl apply -f pod-with-secret-volume.yaml# 进入Pod查看挂载的文件
kubectl exec -it mypod -- ls /etc/secrets # 显示username.txt和password.txt
kubectl exec -it mypod -- cat /etc/secrets/username.txt # 显示zhangsan
方式2:作为环境变量注入Pod
将Secret数据注入为容器的环境变量,适用于应用通过环境变量读取配置的场景。
vim pod-with-secret-env.yaml
# pod-with-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:name: mypod1
spec:containers:- name: nginximage: nginxenv:- name: TEST_USER # 环境变量名称valueFrom:secretKeyRef:name: mysecret1 # 引用的Secret名称key: username # 引用的Secret中的key- name: TEST_PASSWORDvalueFrom:secretKeyRef:name: mysecret1key: password
验证:
kubectl apply -f pod-with-secret-env.yaml# 查看环境变量
kubectl exec -it mypod1 -- printenv | grep TEST # 显示TEST_USER=zhangsan,TEST_PASSWORD=abc1234
2.2 ConfigMap(配置管理)
2.2.1 概念
ConfigMap用于存储非敏感的配置数据(如应用参数、配置文件内容),与Secret类似,但数据以明文存储,适用于不需要加密的配置场景(如日志级别、服务地址)。
2.2.2 创建ConfigMap的方式
方式1:从目录创建
# 创建配置文件目录
mkdir /opt/configmap/# 创建示例配置文件
cat > /opt/configmap/game.properties << EOF
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
EOFcat > /opt/configmap/ui.properties << EOF
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
EOF# 从目录创建ConfigMap(自动包含目录下所有文件)
kubectl create configmap game-config --from-file=/opt/configmap/
# --from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
方式2:从指定文件创建
# 从单个或多个文件创建
kubectl create configmap game-config-2 \--from-file=/opt/configmap/game.properties \--from-file=/opt/configmap/ui.properties
方式3:从字面值创建(键值对)
# 直接指定键值对创建
kubectl create configmap special-config \--from-literal=special.how=very \--from-literal=special.type=good
2.2.3 在Pod中使用ConfigMap的方式
方式1:作为环境变量注入
vim pod-with-configmap-env.yaml
# pod-with-configmap-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: env-confignamespace: default
data:log_level: INFO
---
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: busyboximage: busybox:1.28.4command: ["/bin/sh", "-c", "env"] # 输出环境变量env:# 单个key注入- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-config # 引用的ConfigMap名称key: special.how # 引用的key- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:# 整个ConfigMap注入(所有key作为环境变量)- configMapRef:name: env-config # 假设存在名为env-config的ConfigMaprestartPolicy: Never
验证:
kubectl apply -f pod-with-configmap-env.yaml# 查看环境变量输出
kubectl logs test-pod # 包含SPECIAL_HOW_KEY=very,SPECIAL_TYPE_KEY=good,log_level= INFO
方式2:作为命令行参数使用
通过环境变量引用ConfigMap数据,再在命令行中使用:
vim pod-with-configmap-cmd.yaml
# pod-with-configmap-cmd.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod2
spec:containers:- name: busyboximage: busybox:1.28.4command: - /bin/sh- -c- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY) $(log_level)"env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never
验证:
kubectl apply -f pod-with-configmap-cmd.yamlkubectl logs test-pod2 # 输出:very good INFO
方式3:以Volume形式挂载
将ConfigMap数据以文件形式挂载到容器,在这个文件中,键就是文件名,键值就是文件内容,适用于配置文件场景:
vim pod-with-configmap-volume.yaml
# pod-with-configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod3
spec:containers:- name: busyboximage: busybox:1.28.4command: ["/bin/sh", "-c", "sleep 3600"] # 保持容器运行volumeMounts:- name: config-volume # 挂载卷名称mountPath: /etc/config # 容器内挂载路径volumes:- name: config-volumeconfigMap:name: special-config # 引用的ConfigMap名称restartPolicy: Never
验证:
kubectl apply -f pod-with-configmap-volume.yaml# 查看挂载的文件
kubectl exec -it test-pod3 -- ls /etc/config # 显示special.how和special.type
kubectl exec -it test-pod3 -- cat /etc/config/special.how # 输出:very
2.2.4 ConfigMap热更新机制
当ConfigMap内容更新后,以
Volume方式
挂载的文件会在约10秒内自动同步(无需重启Pod),但环境变量方式注入的配置不会自动更新。
示例验证:
1、创建初始ConfigMap:
vim log-config.yaml
# log-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: log-config
data:log_level: INFO
kubectl apply -f log-config.yaml
2、 创建使用该ConfigMap的Deployment:
vim deploy-with-configmap-volume.yaml
# test-pod4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:replicas: 1selector:matchLabels:app: my-nginxtemplate:metadata:labels:app: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: log-config
kubectl apply -f deploy-with-configmap-volume.yaml
kubectl get po
3、查看初始配置:
kubectl exec -it my-nginx-c6df7db54-pkwtn -- cat /etc/config/log_level # 输出:INFO
4、更新ConfigMap:
kubectl edit configmap log-config # 将log_level改为DEBUG
5、验证更新(约10秒后):
kubectl exec -it my-nginx-c6df7db54-pkwtn -- cat /etc/config/log_level # 输出:DEBUG
Volume 挂载的数据约 10 秒后同步更新。
环境变量不会自动更新。
2.2.5 触发Pod滚动更新
由于
环境变量方式
无法自动更新,且部分应用不支持动态读取配置文件,此时需手动触发Pod重启以加载新配置
1、创建以环境变量使用log-config的Deployment
vim deploy-with-configmap-env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:replicas: 1selector:matchLabels:app: my-nginxtemplate:metadata:labels:app: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80env:- name: log_levelvalueFrom:configMapKeyRef:name: log-configkey: log_levelkubectl apply -f deploy-with-configmap-env.yaml
kubectl get po
2、查看初始配置
kubectl exec -it my-nginx-6f59c9b5d7-vhmw7 -- printenv|grep log
3、更新ConfigMap:
kubectl edit configmap log-config # 将log_level改为DEBUG
4、更新 ConfigMap不会更新ENV
kubectl exec -it my-nginx-6f59c9b5d7-vhmw7 -- printenv|grep log
5、触发滚动更新
# 更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改 version/config 来触发滚动更新
# 通过更新Pod模板的注解触发Deployment滚动更新
kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20251016" }}}}}'
查看更新结果
kubectl get pods
kubectl exec -it my-nginx-845cdf9976-2zd4s -- printenv|grep log
PS:更新 ConfigMap 后:
- 使用该 ConfigMap 挂载的 Env 不会同步更新。
- 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。
2.3 Secret与ConfigMap对比总结
对比项 | Secret | ConfigMap |
---|---|---|
存储内容 | 敏感信息(密码、密钥、证书) | 非敏感配置(参数、配置文件) |
数据存储格式 | Base64编码(非加密,需权限保护) | 明文存储 |
主要使用方式 | Volume挂载、环境变量、镜像拉取凭证 | Volume挂载、环境变量、命令参数 |
自动更新支持 | Volume挂载延迟更新,环境变量不更新 | Volume挂载延迟更新,环境变量不更新 |
安全性要求 | 高(需通过RBAC严格控制访问) | 普通(默认允许读取) |
总结
本文详细介绍了Kubernetes中Pod控制器与配置资源管理的核心内容。Pod控制器作为工作负载的核心,通过Deployment、StatefulSet、DaemonSet、Job、CronJob等不同类型,分别满足了无状态应用、有状态应用、节点级服务、一次性任务、周期性任务的管理需求,实现了Pod的自动化部署、伸缩、更新与故障自愈。
配置资源管理中,Secret与ConfigMap通过分离配置与应用代码,提升了配置的灵活性与安全性:Secret用于敏感数据的存储与访问控制,ConfigMap用于非敏感配置的管理,二者支持Volume挂载与环境变量注入等多种使用方式,适配不同应用的配置读取习惯。
掌握这些组件的特性与使用技巧,能够帮助开发者与运维人员更高效地部署、管理Kubernetes集群中的应用,确保应用的稳定性、安全性与可扩展性。