Pod
为什么需要 Pod?
容器本身是单进程模型,但现实中的应用可能需要多个协作进程(例如主进程+辅助进程),而超亲密关系的容器协作可能需要满足以下功能:
- 共享网络:所有容器共享同一个IP和端口空间。
- 共享存储:容器A将日志写入到本地,容器B可以直接读取这个文件。
- 共享生命周期:同时启动,同时终止。
使用原生Docker完全可以实现以上功能,但这种配置需要手动管理,且缺乏统一的抽象层,容易出错,尤其在分布式系统中难以维护。 Pod将这些共享机制封装为一个原子单元,简化了配置,并确保这些容器始终作为一个整体被调度和管理。
Deployment/StatefulSet
为什么需要 Deployment?
Docker本身缺乏对多容器集群的管理能力,无法直接满足复杂应用在生产环境中的管理需求, Deployment的目的是提供一系列高级功能来简化复杂环境下容器化应用的生命周期管理。
功能 | Docker | Kubernetes Deployment |
---|---|---|
副本管理 | 需手动操作 | 自动维护副本数量 |
滚动更新 | 不支持 | 支持分批替换,零停机 |
回滚机制 | 无 | 一键回滚到历史版本 |
自愈能力 | 有限(需配置重启策略) | 自动重建故障 Pod |
跨节点集群管理 | 不支持 | 内置支持 |
声明式配置 | 不支持 | 通过 YAML 定义期望状态 |
为什么需要 StatefulSet?
StatefulSet在Deployment的基础上,加上了稳定的网络标识、有序部署、有序扩展等功能:
行为 | StatefulSet | Deployment |
---|---|---|
Pod 名称 | 固定(如 mysql-0 ) | 随机生成(如 web-5d79d5c5f6 ) |
DNS 网络标识 | 与 Pod 名称绑定 | 通过 Service 负载均衡,无法定位单个 Pod |
滚动更新策略 | 逆序(默认)或自定义 | 无序并行 |
目的是为了解决主从分布式架构的系统隐患:
- 网络标识不固定,那就无法在配置中固定主节点,当主节点重启后的Pod无法自动继承主节点这一角色,而从节点的数据不一定是完整的, 如果数据不完整的从节点选举为新的主节点,则会出现数据丢失的问题。
- 由于PVC独立于Pod,并行滚动更新会同时存在新旧的Pod绑定到同一个PVC(先创建后删除),最终有可能新旧Pod同时写入同一PVC导致数据损坏。
- 而无序滚动更新有可能首先删除主节点,此时仍存活的所有从节点如果缺乏协调机制,可能导致选举失败或出现多个主节点。
容器网络模型
组件 | 核心功能 | 作用层次 | 典型场景 | 依赖关系 |
---|---|---|---|---|
CNI | 实现 Pod 间网络连通(跨节点通信) | 基础设施层 | 确保 Pod 之间可以直接通过 IP 通信 | 底层网络插件(如 Calico、Flannel) |
Service | 为一组 Pod 提供负载均衡和稳定访问入口 | 服务抽象层 | 集群内部服务暴露、负载均衡 | 依赖 CNI 的网络连通性 |
Ingress | 管理外部 HTTP/HTTPS 流量到内部 Service 的路由 | 应用层(L7) | 外部访问路由、域名和路径分发 | 依赖 Service 和 CNI |
DNS 服务发现 | 将 Service 和 Pod 名称解析为 IP 地址 | 服务发现层 | 服务间通过名称(而非 IP)通信 | 依赖 Service 和 CoreDNS |