4、Kubernetes核心概念:Pod、Deployment、Service、Ingress、ConfigMap、Secret等资源详解

在完成Kubernetes集群的部署与基础验证之后,真正进入日常运维与业务交付时,我们面对的核心对象不再是物理节点或虚拟机,而是Kubernetes抽象出的各类资源对象(Resource Objects)。这些资源对象共同构成了声明式应用管理的基石。本章将深入剖析Pod、Deployment、Service、Ingress、ConfigMap与Secret这六大核心资源,从原理、操作到实战排障,帮助学员建立从“能用”到“会用”的认知跨越。理解这些资源之间的关系,是掌握Kubernetes调度、网络、存储与配置管理的关键前提。

Kubernetes 核心资源关系与流量链路图 用户 / 客户端 Ingress (7层路由) 域名/Host + Path → Service Service (4层负载均衡) ClusterIP:Port → Pod IP:Port Pod A (副本1) 容器1 (业务) 容器2 (Sidecar) IP: 10.244.1.11 Pod B (副本2) 容器1 (业务) 容器2 (Sidecar) IP: 10.244.2.12 Deployment (控制器) 期望副本数=2 滚动更新策略 ConfigMap 明文配置 (非敏感) Secret Base64编码 (敏感信息) 挂载/注入 环境变量 / 文件卷 外部流量 Ingress Service Pod 配置/密钥

上图清晰地展示了用户请求从外部进入集群后的完整路径,以及Deployment、ConfigMap、Secret与Pod之间的管理或注入关系。在后续的实战中,我们将围绕这张图逐一展开每个资源的细节。

4.1 Pod:最小调度单元与容器共享模型

核心原理

Pod是Kubernetes中可创建和部署的最小单元,也是调度、网络、存储的最小边界。一个Pod可以包含一个或多个容器,这些容器共享同一个网络命名空间(即共享IP和端口空间)、同一个UTS命名空间(主机名)以及可选的共享存储卷。这种设计使得Pod内的容器可以通过localhost直接通信,非常适合“主容器+辅助容器(Sidecar)”的协作模式,例如日志收集、流量代理、健康检查等。

Pod的生命周期是短暂的,它不会自愈。当Pod因节点故障、资源不足或应用崩溃而被删除时,Kubernetes不会直接重建同一个Pod,而是通过上层控制器(如Deployment)创建新的Pod来替代。因此,在生产环境中,我们几乎从不直接创建裸Pod,而是通过控制器管理。

判断方法与操作流程

判断一个Pod是否健康,通常需要结合存活探针(LivenessProbe)和就绪探针(ReadinessProbe)。存活探针决定何时重启容器,就绪探针决定何时将Pod加入Service的负载均衡池。创建Pod的常用命令如下:

# 直接创建Pod(不推荐生产使用)
kubectl run nginx-pod --image=nginx:1.25

# 查看Pod详情,重点关注Events字段
kubectl describe pod nginx-pod

# 查看Pod日志(多容器时需指定-c容器名)
kubectl logs nginx-pod -c main-container

案例拆解:多容器Pod的日志采集

假设我们有一个Java应用需要采集日志。传统方式是在虚拟机中安装Agent,但在Kubernetes中,我们采用Sidecar模式。在同一个Pod中,主容器运行Java应用,Sidecar容器运行Filebeat。两个容器共享一个emptyDir卷,Java应用将日志写入该卷,Filebeat读取并转发至Elasticsearch。这种模式的优点在于:日志采集逻辑与应用解耦,且随着Pod的扩缩容,日志采集能力自动伸缩。

经验提醒:Pod的restartPolicy默认为Always,适用于Deployment管理的Pod。但对于执行一次性任务的Job,应设置为OnFailure或Never,避免任务完成后容器反复重启。

常见误区与复盘

  • 误区1:认为Pod内的多个容器可以分别暴露不同端口给外部访问。实际上,Pod只有一个IP,端口共享,外部访问必须通过Service。
  • 误区2:忽略Pod的资源请求(requests)与限制(limits)。不设置资源限制可能导致节点资源被单个Pod耗尽,引发雪崩。
  • 复盘:在排查Pod一直处于Pending状态时,应优先检查kubectl describe pod中的调度事件,常见原因包括节点资源不足、节点亲和性不满足或存在污点。

4.2 Deployment:声明式应用管理控制器

核心原理

Deployment是Kubernetes中最常用的无状态应用控制器,它负责管理Pod的副本数、滚动更新、回滚以及故障自愈。Deployment通过ReplicaSet来间接管理Pod。每次更新Deployment的Pod模板时,Deployment会创建一个新的ReplicaSet,并逐步增加新ReplicaSet的副本数,同时减少旧ReplicaSet的副本数,从而实现平滑升级。

操作流程与策略

Deployment支持两种更新策略:RollingUpdate(默认)和Recreate。滚动更新允许我们控制maxSurge(最大峰值副本数)和maxUnavailable(最大不可用副本数)。例如,设置maxSurge: 25%和maxUnavailable: 25%,意味着在更新过程中,Pod总数最多比期望副本数多25%,且至少有75%的副本保持可用。

# 创建Deployment
kubectl create deployment web-app --image=nginx:1.25 --replicas=3

# 滚动更新镜像版本
kubectl set image deployment/web-app nginx=nginx:1.26

# 查看滚动更新状态
kubectl rollout status deployment/web-app

# 如果更新失败,回滚到上一个版本
kubectl rollout undo deployment/web-app

案例拆解:一次失败的滚动更新

某团队将web-app的镜像从v1.0升级到v2.0。升级后,新版本的Pod启动时因依赖的数据库配置错误而崩溃。由于设置了就绪探针,新Pod一直处于未就绪状态。此时,maxUnavailable为25%,意味着有1个旧Pod被终止,但新Pod未就绪,导致服务容量下降。监控系统告警后,运维人员执行kubectl rollout undo deployment/web-app,集群立即将ReplicaSet回滚至v1.0,服务恢复。复盘发现,问题根源在于CI流水线未在测试环境验证v2.0的配置兼容性。

风险提示:不要在生产环境直接使用kubectl edit deployment修改镜像版本,应通过kubectl set image或修改YAML文件并kubectl apply,确保变更可审计、可回滚。

常见误区与总结

  • 误区:将Deployment用于有状态应用(如数据库)。Deployment无法保证Pod的稳定标识和持久化存储,应使用StatefulSet。
  • 总结:Deployment是“无状态服务”的标配,掌握其滚动更新机制是保障发布安全的核心技能。

4.3 Service:稳定的访问入口与负载均衡

核心原理

由于Pod的IP是动态变化的,我们需要Service为一组Pod提供稳定的虚拟IP(ClusterIP)和DNS名称。Service通过Label Selector选择后端Pod,并自动维护Endpoints列表。当Pod发生扩缩容或重建时,Service无需修改,客户端始终通过固定的ClusterIP或域名访问。

Service的四种类型中,ClusterIP是默认类型,仅在集群内部可访问;NodePort在ClusterIP基础上,在每个节点上开放一个静态端口(30000-32767),供外部访问;LoadBalancer通常由云提供商实现,创建外部负载均衡器;ExternalName用于将服务映射到集群外部的DNS名称。

操作流程与排查

# 创建Service,暴露Deployment的80端口
kubectl expose deployment web-app --port=80 --target-port=8080 --type=ClusterIP

# 查看Service的Endpoints
kubectl get endpoints web-app

# 临时端口转发,用于本地调试
kubectl port-forward service/web-app 8080:80

当访问Service不通时,排查路径应为:Service → Endpoints → Pod IP → 容器端口。最常见的问题是Label Selector不匹配,导致Endpoints为空。

案例拆解:NodePort端口冲突

某集群中,运维人员手动创建了一个NodePort Service,指定nodePort: 30080。但随后另一个团队部署应用时,也尝试使用30080端口,导致创建失败。Kubernetes默认的NodePort端口范围是30000-32767,且不允许冲突。解决方案是:除非有特殊合规要求,否则不显式指定nodePort,让集群自动分配。

核心要点:Service的targetPort是容器实际监听的端口,而port是Service暴露的端口。两者可以不同,这为应用迁移提供了灵活性。

4.4 Ingress:七层路由与统一入口

核心原理

Ingress是Kubernetes的API对象,用于管理集群外部访问集群内服务的HTTP/HTTPS路由。与Service的4层负载均衡不同,Ingress工作在7层,可以根据域名、URL路径将请求转发到不同的Service。Ingress本身不提供流量转发能力,它需要配合Ingress Controller(如Nginx Ingress Controller、Traefik)才能生效。Ingress Controller是一个运行在集群中的负载均衡器,它监听Ingress资源的变化并动态更新其配置。

配置示例与判断方法

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

判断Ingress是否生效,可以执行kubectl get ingress查看ADDRESS字段是否已分配,以及kubectl logs -n ingress-nginx查看Controller日志。

案例拆解:灰度发布中的Ingress应用

某电商平台需要将新版本推荐服务灰度上线。团队创建了两个Deployment:recommend-v1和recommend-v2,分别对应两个Service。通过Ingress的nginx.ingress.kubernetes.io/canary注解,将5%的流量转发至v2版本。观察监控指标无异常后,逐步将权重调整至100%,最终完成全量发布。这种基于Ingress的灰度策略无需修改应用代码,且回滚迅速。

注意:Ingress资源本身不提供TLS证书管理。证书应存储在Secret中,并在Ingress的tls字段中引用。证书过期是Ingress HTTPS访问失败的常见原因。

4.5 ConfigMap与Secret:配置与敏感信息管理

核心原理

ConfigMap用于存储非敏感的配置信息,如环境变量、配置文件内容。Secret用于存储敏感信息,如密码、API密钥、TLS证书。Secret的存储格式为Base64编码,但这只是编码,并非加密。在Kubernetes 1.24及以上版本,Secret支持可选的静态加密(Encryption at Rest)。

两者都可以通过环境变量或挂载卷的方式注入Pod。挂载卷方式支持热更新(ConfigMap更新后,Pod内的文件内容会同步更新,但环境变量方式不会)。

操作流程与安全实践

# 从字面值创建ConfigMap
kubectl create configmap app-config --from-literal=LOG_LEVEL=info

# 从文件创建Secret
kubectl create secret generic db-secret --from-file=./password.txt

# 在Pod中通过卷挂载Secret
# volumes:
# - name: secret-volume
#   secret:
#     secretName: db-secret

案例拆解:配置热更新与不可变ConfigMap

一个Java应用从/etc/config/application.yml读取配置。运维人员更新了ConfigMap中的数据,但应用并未感知。排查发现,应用只在启动时读取一次配置文件。解决方案有两种:一是应用支持监听文件变化并重载;二是使用sha256sum注解,在ConfigMap内容变化时触发Deployment滚动更新。此外,对于生产环境,建议将ConfigMap设置为immutable: true,防止误修改。

安全提醒:避免在ConfigMap中存储任何形式的密码或密钥。Secret的Base64编码很容易被解码,应结合RBAC权限控制限制Secret的访问范围,并启用静态加密。

常见误区与总结

  • 误区:认为Secret是安全的。实际上,任何有权访问集群的人都可以通过kubectl get secret -o yaml解码查看。
  • 总结:ConfigMap与Secret是应用配置与代码分离的最佳实践,也是实现12-Factor应用的关键。
资源对象 作用层级 核心作用 是否自愈 典型使用场景
Pod 计算 最小调度与运行单元 否 单实例容器组、Sidecar模式
Deployment 工作负载 管理无状态Pod的副本与更新 是 Web服务、API服务、Worker
Service 网络 提供稳定的虚拟IP与负载均衡 - 集群内部服务发现与访问
Ingress 网络 七层HTTP/HTTPS路由 - 域名访问、URL路径转发、TLS终止
ConfigMap 配置 存储非敏感配置 - 环境变量、配置文件注入
Secret 配置 存储敏感信息(Base64) - 数据库密码、TLS证书、API密钥

通过本章的详解,我们应当明确:Pod是基础,Deployment是保障,Service是桥梁,Ingress是门户,ConfigMap与Secret是养分。在实际部署中,这六大资源往往协同工作。掌握它们之间的依赖关系与排查思路,是进行后续集群运维、监控告警与故障恢复的必备能力。在下一阶段的实战中,我们将基于这些核心概念,构建一个完整的微服务应用,并模拟多种故障场景进行演练。