K8S(十)—— Kubernetes核心组件详解:Pod控制器与配置资源管理

文章目录

  • 前言
  • 一、Pod控制器
    • [1.1 Pod控制器概述](#1.1 Pod控制器概述)
      • [1.1.1 核心功能](#1.1.1 核心功能)
    • [1.2 Pod控制器的类型](#1.2 Pod控制器的类型)
    • [1.3 Deployment控制器](#1.3 Deployment控制器)
      • [1.3.1 核心特点](#1.3.1 核心特点)
      • [1.3.2 部署案例](#1.3.2 部署案例)
      • [1.3.3 查看与修改控制器配置](#1.3.3 查看与修改控制器配置)
    • [1.4 StatefulSet控制器(有状态应用)](#1.4 StatefulSet控制器(有状态应用))
    • [1.5 DaemonSet控制器](#1.5 DaemonSet控制器)
      • [1.5.1 核心功能](#1.5.1 核心功能)
      • [1.5.2 部署案例](#1.5.2 部署案例)
    • [1.6 Job控制器](#1.6 Job控制器)
      • [1.6.1 核心功能](#1.6.1 核心功能)
      • [1.6.2 部署案例1(计算π值)](#1.6.2 部署案例1(计算π值))
      • [1.6.3 部署案例2(失败重试演示)](#1.6.3 部署案例2(失败重试演示))
    • [1.7 CronJob控制器](#1.7 CronJob控制器)
      • [1.7.1 核心功能](#1.7.1 核心功能)
      • [1.7.2 部署案例(每分钟打印消息)](#1.7.2 部署案例(每分钟打印消息))
    • [1.8 无状态 vs 有状态应用对比](#1.8 无状态 vs 有状态应用对比)
    • [1.9 常规Service与Headless Service对比](#1.9 常规Service与Headless Service对比)
    • [1.10 附录:Kubernetes服务发现机制](#1.10 附录:Kubernetes服务发现机制)
    • [1.11 总结](#1.11 总结)
  • 二、配置资源管理
  • 总结

前言

在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配置文件

yaml 复制代码
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:          # 标签选择器,用于关联需要管理的Pod
      app: nginx
  template:               # Pod模板,定义Pod的具体配置
    metadata:
      labels:
        app: nginx        # Pod的标签,需与selector.matchLabels一致
    spec:
      containers:
      - name: nginx       # 容器名称
        image: nginx:1.15.4  # 容器镜像
        ports:
        - containerPort: 80  # 容器暴露的端口

步骤2:创建Deployment资源

bash 复制代码
kubectl create -f nginx-deployment.yaml

步骤3:验证部署结果

bash 复制代码
# 查看Pod、Deployment、ReplicaSet状态
kubectl get pods,deploy,rs

1.3.3 查看与修改控制器配置

查看Deployment详细配置

bash 复制代码
kubectl edit deployment/nginx-deployment

配置中关键字段说明:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2021-04-19T08:13:50Z"
  generation: 1
  labels:
    app: nginx					#Deployment资源的标签
  name: nginx-deployment
  namespace: default
  resourceVersion: "167208"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
  uid: d9d3fef9-20d2-4196-95fb-0e21e65af24a
spec:
  progressDeadlineSeconds: 600
  replicas: 3					#期望的pod数量,默认是1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%				#升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
      maxUnavailable: 25%		#升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
    type: RollingUpdate			#滚动升级
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx				#Pod副本关联的标签
    spec:
      containers:
      - image: nginx:1.15.4				#镜像名称
        imagePullPolicy: IfNotPresent	#镜像拉取策略
        name: nginx
        ports:
        - containerPort: 80				#容器暴露的监听端口
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always				#容器重启策略
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
......
修改spec.containers.image为nginx:1.16,查看结果

查看历史版本

bash 复制代码
kubectl rollout history deployment nginx-deployment

1.4 StatefulSet控制器(有状态应用)

StatefulSet专为有状态应用设计,解决了Deployment无法满足的稳定标识、有序部署、独立存储等需求。

1.4.1 核心特点

  1. 稳定存储 :通过PVC(PersistentVolumeClaim)为每个Pod分配独立的持久化存储,确保Pod重建后数据不丢失。
  2. 稳定网络标识 :Pod名称固定为<statefulset-name>-<ordinal-index>(如myapp-0、myapp-1),DNS域名格式为<pod-name>.<service-name>.<namespace>.svc.cluster.local,便于集群内服务发现。
  3. 有序部署与删除:部署时按序号从0到N-1依次创建Pod,确保前置Pod就绪后再创建后续Pod;删除时按序号从N-1到0依次销毁。
  4. 依赖Headless Service:需要配合无头服务(Headless Service)实现Pod的DNS解析。

1.4.2 核心组件

  1. Headless Service(无头服务):无ClusterIP,通过DNS直接返回Pod的IP地址,为StatefulSet的Pod提供稳定的网络标识。
  2. volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
  3. 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
yaml 复制代码
vim  stateful-headless.yaml
# stateful-headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc  # 服务名称,将用于Pod的DNS解析
spec:
  ports:
  - port: 80
    name: web      # 端口名称,可选
  clusterIP: None  # 设为None表示无头服务
  selector:
    app: myapp-pod # 关联标签,需与StatefulSet的Pod标签一致

创建服务:

bash 复制代码
kubectl apply -f stateful-headless.yaml
步骤2:定义StatefulSet配置
yaml 复制代码
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      # 标签选择器,关联Pod
  template:
    metadata:
      labels:
        app: myapp-pod    # Pod标签,需与selector一致
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1  # 容器镜像
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - 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-storageclass
    spec:
      accessModes: ["ReadWriteOnce"]  # 访问模式(单节点读写)
      resources:
        requests:
          storage: 2Gi  # 申请的存储大小

解析上例:

  • 由于 StatefulSet 资源依赖于一个实现存在的 Headless 类型的 Service 资源,所以需要先定义一个名为 myapp-svc 的 Headless Service 资源,用于为关联到每个 Pod 资源创建 DNS 资源记录。
  • 接着定义了一个名为 myapp 的 StatefulSet 资源,它通过 Pod 模板创建了 3 个 Pod 资源副本,并基于 volumeClaimTemplates 向前面创建的PV进行了请求大小为 2Gi 的专用存储卷。
步骤3:创建与验证
bash 复制代码
# 创建StatefulSet
kubectl apply -f stateful-demo.yaml

# 查看状态(sts为StatefulSet的缩写)
kubectl get sts,pvc,pv,pods
步骤4:滚动更新

StatefulSet的更新按序号从高到低(如2→1→0)依次进行,确保每个Pod更新完成并就绪后再处理下一个:

bash 复制代码
# 编辑StatefulSet,修改镜像版本(如将ikubernetes/myapp:v1改为v2)
kubectl edit sts myapp

# 观察更新过程
# 它将以与 Pod 终止相同的顺序进行(从最大的序数到最小的序数),每次更新一个 Pod。在更新其前身之前,它将等待正在更新的 Pod 状态变成正在运行并就绪。
kubectl get pods -w
步骤5:Pod名称解析验证

StatefulSet的Pod可通过固定DNS域名访问:

bash 复制代码
# 进入其中一个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):
  1. Deployment 认为所有的 Pod 都是一样的。
  2. 无需考虑顺序要求。
  3. 不关心 Pod 在哪个 Node 上运行。
  4. 可以随意扩容和缩容。
有状态(Stateful):
  1. 实例之间存在差别,每个实例有其独特性,且元数据不同(如 etcd, zookeeper)。
  2. 实例之间的关系是对等的,且依赖外部存储的应用。

常规 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 部署案例

yaml 复制代码
vim ds.yaml 
# ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset  # DaemonSet名称
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx  # 标签选择器,关联Pod
  template:
    metadata:
      labels:
        app: nginx  # Pod标签
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4  # 容器镜像
        ports:
        - containerPort: 80  # 暴露端口

创建并验证:

bash 复制代码
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(计算π值)

yaml 复制代码
vim job.yaml
# job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi  # Job名称
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl  # 基于perl镜像执行计算
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]  # 计算π的2000位小数
      restartPolicy: Never  # 任务失败后不重启Pod(Job中仅允许Never或OnFailure,否则Job将不间断运行)
  backoffLimit: 4  # 失败重试次数(默认6次)

操作步骤:

bash 复制代码
# 提前拉取镜像(避免部署时等待)
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(失败重试演示)

yaml 复制代码
vim job-limit.yaml
# job-limit.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: busybox
spec:
  template:
    spec:
      containers:
        - name: busybox
          image: busybox
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-c", "sleep 10; date; exit 1"]  # 执行后以错误码1退出(模拟失败)
      restartPolicy: Never
  backoffLimit: 2  # 最多重试2次
================================================================
#command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
容器启动后执行的命令:
    sleep 10 → 先睡眠 10 秒
    date → 打印当前日期
    exit 1 → 以 退出码 1 结束容器(即任务失败)

验证重试机制:

bash 复制代码
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 部署案例(每分钟打印消息)

yaml 复制代码
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: hello
            image: busybox
            args:
            - /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:						#作业模板。这类似于工作示例 

操作步骤:

bash 复制代码
# 创建CronJob
kubectl create -f cronjob.yaml

# 查看CronJob状态
kubectl get cronjob
bash 复制代码
# 查看生成的Pod(每分钟创建一个,完成后状态为Completed)
kubectl get pods

# 查看任务输出
kubectl logs <pod-name>  # 替换为实际Pod名称,如hello-1621587180-mffj6

# 清理资源
kubectl delete cronjob hello
bash 复制代码
# 如果报错: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才能使用其数据。

使用方式

  1. 作为 Volume 文件 挂载。
  2. 作为 环境变量
  3. kubelet 拉取镜像时使用认证信息

应用场景:凭据管理

官方文档:https://kubernetes.io/docs/concepts/configuration/secret/


2.1.3 创建Secret的方式

方式1:命令行创建(从文件)
bash 复制代码
# 创建存储用户名和密码的文件
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:

bash 复制代码
# 列出所有Secret
kubectl get secrets

# 查看Secret详情(数据将以Base64显示)
kubectl describe secret mysecret
方式2:YAML文件创建(Base64编码)

步骤1:对敏感数据进行Base64编码

bash 复制代码
echo -n 'zhangsan' | base64  # 输出:emhhbmdzYW4=
echo -n 'abc1234' | base64   # 输出:YWJjMTIzNA==

步骤2:编写YAML配置

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

bash 复制代码
kubectl apply -f secret.yaml

# 验证创建结果
kubectl get secret mysecret1 -o yaml


2.1.4 使用Secret的方式

方式1:作为Volume挂载到Pod

将Secret数据以文件形式挂载到容器的指定目录,适用于需要读取配置文件的场景。

yaml 复制代码
vim pod-with-secret-volume.yaml
# pod-with-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: secrets  # 挂载卷名称,与volumes.name一致
      mountPath: "/etc/secrets"  # 容器内挂载路径
      readOnly: true  # 只读权限(推荐)
  volumes:
  - name: secrets
    secret:
      secretName: mysecret  # 引用的Secret名称

验证:

bash 复制代码
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数据注入为容器的环境变量,适用于应用通过环境变量读取配置的场景。

yaml 复制代码
vim pod-with-secret-env.yaml
# pod-with-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: TEST_USER  # 环境变量名称
        valueFrom:
          secretKeyRef:
            name: mysecret1  # 引用的Secret名称
            key: username    # 引用的Secret中的key
      - name: TEST_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key: password

验证:

bash 复制代码
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:从目录创建
bash 复制代码
# 创建配置文件目录
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
EOF

cat > /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:从指定文件创建
bash 复制代码
# 从单个或多个文件创建
kubectl create configmap game-config-2 \
  --from-file=/opt/configmap/game.properties \
  --from-file=/opt/configmap/ui.properties    
方式3:从字面值创建(键值对)
bash 复制代码
# 直接指定键值对创建
kubectl create configmap special-config \
  --from-literal=special.how=very \
  --from-literal=special.type=good

2.2.3 在Pod中使用ConfigMap的方式

方式1:作为环境变量注入
yaml 复制代码
vim pod-with-configmap-env.yaml
# pod-with-configmap-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: ["/bin/sh", "-c", "env"]  # 输出环境变量
    env:
      # 单个key注入
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config  # 引用的ConfigMap名称
            key: special.how      # 引用的key
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      # 整个ConfigMap注入(所有key作为环境变量)
      - configMapRef:
          name: env-config  # 假设存在名为env-config的ConfigMap
  restartPolicy: Never

验证:

bash 复制代码
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数据,再在命令行中使用:

yaml 复制代码
vim pod-with-configmap-cmd.yaml
# pod-with-configmap-cmd.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: 
	- /bin/sh
	- -c
	- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY) $(log_level)"
    env:
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      - configMapRef:
          name: env-config
  restartPolicy: Never

验证:

bash 复制代码
kubectl apply -f pod-with-configmap-cmd.yaml

kubectl logs test-pod2  # 输出:very good INFO
方式3:以Volume形式挂载

将ConfigMap数据以文件形式挂载到容器,在这个文件中,键就是文件名,键值就是文件内容,适用于配置文件场景:

yaml 复制代码
vim pod-with-configmap-volume.yaml
# pod-with-configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: ["/bin/sh", "-c", "sleep 3600"]  # 保持容器运行
    volumeMounts:
    - name: config-volume  # 挂载卷名称
      mountPath: /etc/config  # 容器内挂载路径
  volumes:
  - name: config-volume
    configMap:
      name: special-config  # 引用的ConfigMap名称
  restartPolicy: Never

验证:

bash 复制代码
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:

yaml 复制代码
vim log-config.yaml
# log-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
data:
  log_level: INFO
bash 复制代码
kubectl apply -f log-config.yaml

2、 创建使用该ConfigMap的Deployment:

yaml 复制代码
vim deploy-with-configmap-volume.yaml
# test-pod4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: log-config
bash 复制代码
kubectl apply -f deploy-with-configmap-volume.yaml
kubectl get po

3、查看初始配置:

bash 复制代码
kubectl exec -it my-nginx-c6df7db54-pkwtn -- cat /etc/config/log_level  # 输出:INFO

4、更新ConfigMap:

bash 复制代码
kubectl edit configmap log-config  # 将log_level改为DEBUG

5、验证更新(约10秒后):

bash 复制代码
kubectl exec -it my-nginx-c6df7db54-pkwtn -- cat /etc/config/log_level  # 输出:DEBUG

Volume 挂载的数据约 10 秒后同步更新。

环境变量不会自动更新。

2.2.5 触发Pod滚动更新

由于环境变量方式无法自动更新,且部分应用不支持动态读取配置文件,此时需手动触发Pod重启以加载新配置

1、创建以环境变量使用log-config的Deployment

bash 复制代码
vim deploy-with-configmap-env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
        env:
          - name: log_level
            valueFrom:
              configMapKeyRef:
                name: log-config
                key: log_level

kubectl apply -f deploy-with-configmap-env.yaml 
kubectl get po

2、查看初始配置

bash 复制代码
kubectl exec -it my-nginx-6f59c9b5d7-vhmw7 -- printenv|grep log

3、更新ConfigMap:

bash 复制代码
kubectl edit configmap log-config  # 将log_level改为DEBUG

4、更新 ConfigMap不会更新ENV

bash 复制代码
kubectl exec -it my-nginx-6f59c9b5d7-vhmw7 -- printenv|grep log

5、触发滚动更新

bash 复制代码
# 更新 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" }}}}}'

查看更新结果

bash 复制代码
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集群中的应用,确保应用的稳定性、安全性与可扩展性。

相关推荐
m0_651593913 小时前
企业级订单系统架构设计:领域驱动 vs 数据驱动实践指南
java·系统架构·领域驱动ddd
WangMing_X3 小时前
C#上位机软件:2.5 体验CLR实现多语言混合编程
java·开发语言·c#
青云交4 小时前
Java 大视界 -- Java 大数据在智慧交通停车场智能管理与车位预测中的应用实践
java·数据采集·数据清洗·智慧交通·停车场智能管理·智能收费系统·车位预测
豐儀麟阁贵4 小时前
4.4数组的基本操作
java·开发语言·数据结构·算法
组合缺一4 小时前
全球首个支持 IETF JSONPath (RFC 9535) 标准的 Java 框架,Snack4-Jsonpath v4.0.0 发布
java·开发语言·json·jsonpath
智海观潮4 小时前
JVM垃圾回收器、内存分配与回收策略
java·大数据·jvm
vx Biye_Design4 小时前
servlet宠物医院管理系统-计算机毕业设计源码77418
java·vue.js·spring·servlet·eclipse·mybatis
程序员小凯4 小时前
Spring Boot API文档与自动化测试详解
java·spring boot·后端
照物华4 小时前
构建优雅的 Spring Boot Starter:Bean 注册与属性绑定的两大机制
java·spring boot