你大概听过这样的说法:上了 Kubernetes(常简称 K8s)之后,服务部署只要一条命令,机器挂了会自动把容器挪到别的节点上重启,扩容只要改一个数字。但真去装一套,又会发现节点起不来、Pod 一直 Pending、Service 访问不通,一堆名词看不懂。这篇文章不讲空洞的概念,而是把 Kubernetes 到底解决什么问题、内部由哪些组件组成、一个请求从提交到容器跑起来经历了哪些环节讲清楚,再给出真实的排查命令和部署架构判断方法。读完你能看懂集群里发生了什么,而不是只会照抄 YAML。
一、为什么需要容器编排
先说清楚 Kubernetes 出现之前的问题。容器(以 Docker 为代表)解决的是"把应用和它的运行环境打包在一起"的问题:一个镜像里包含了代码、依赖库、运行时,换台机器跑结果一样。这比传统的"把 war 包丢到 Tomcat 上,再对着文档装依赖"进步巨大。
但容器本身只解决了单机运行的问题。当你手上有几十个服务、上百个容器、十几台机器时,新的问题出现了:这个容器该放到哪台机器上?机器挂了怎么办?某个服务要扩到 5 个副本,谁去手动改?服务之间怎么互相找到对方?几百个容器的端口怎么分配不冲突?这些正是"编排"要解决的事。
Kubernetes 就是这类编排系统里使用最广的一个,它由 Google 开源,思路源自 Google 内部跑了多年的 Borg 系统。它的核心能力可以概括为四件事:调度(把容器放到合适的节点)、自愈(挂了自动重启或迁移)、扩缩容(按需调整副本数)、服务发现与负载均衡(让服务之间能找到彼此)。
一个关键认知是:Kubernetes 不只管理 Docker。它通过 CRI(容器运行时接口)对接多种容器运行时,现在主流是 containerd 和 CRI-O,Docker 本身在较新版本里已经不再作为默认运行时被直接使用(早期版本的 dockershim 已被移除)。所以你装的 Docker 和 Kubernetes 关心的"容器运行时"不是同一个层面的东西,后面会再解释。
二、核心对象:你实际操作的到底是什么
Kubernetes 里你几乎从不直接操作"容器"。你操作的是各种抽象对象,每个对象对应一份 YAML 声明。理解这些对象是理解 K8s 的第一步。
Pod 是最小调度单位。一个 Pod 里可以有一个或多个容器,它们共享网络命名空间(同一个 IP、同一个端口空间)和存储卷。绝大多数情况一个 Pod 只放一个业务容器,多个容器通常是"边车"模式,比如日志收集、代理。Pod 是临时的,它的 IP 会变,不适合作为稳定访问入口。
ReplicaSet 负责维持某个 Pod 的副本数量。你声明"Pod 要 3 份",它会持续对比实际数量和期望数量,少了就新建,多了就删掉。
Deployment 是管理无状态应用最常用的对象,它套在 ReplicaSet 之上,提供滚动更新和版本回滚能力。你改镜像版本,Deployment 会创建一个新的 ReplicaSet,逐步替换旧的 Pod,出问题可以一键回滚到上一个版本。
Service 为一组 Pod 提供稳定的访问入口。因为 Pod IP 会变,Service 会分配一个固定 IP(ClusterIP),并通过标签选择器把流量转发给后端 Pod,天然实现负载均衡。常见类型有 ClusterIP(集群内访问)、NodePort(在每台节点开一个端口对外)、LoadBalancer(对接云厂商负载均衡)。
Ingress 是集群的 HTTP/HTTPS 入口,通过域名和路径把外部流量转发到不同的 Service,还能统一处理 TLS 证书。它需要一个 Ingress Controller 才能真正工作。
ConfigMap 与 Secret 分别用来存放非敏感配置和敏感信息(密码、密钥、证书)。这样镜像不用改动就能适配不同环境。注意 Secret 默认只是 base64 编码,不是加密,真正的安全要靠集群的加密配置和权限控制。
Namespace 是逻辑隔离单元,把同一个集群里的资源分组,常见做法是按团队或按环境(dev/test/prod)划分。
下面是一份可以直接用的 Deployment 加 Service 示例,改动后即可应用。
# web-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests: # 调度依据:至少给这么多
cpu: 250m # 0.25 核
memory: 256Mi
limits: # 上限:超了会被限制或杀掉
cpu: "1"
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
# 应用配置(声明式,推荐)
kubectl apply -f web-deploy.yaml
# 查看对象状态
kubectl get deploy,rs,pod -o wide
kubectl get svc web-svc
# 查看 Pod 详情与事件(排障第一步)
kubectl describe pod
# 查看日志
kubectl logs --tail=100
三、控制平面:集群的"大脑"
Kubernetes 集群分成控制平面(Control Plane)和工作节点(Worker Node)两部分。控制平面负责决策,工作节点负责干活。控制平面包含四个核心组件。
kube-apiserver 是所有操作的唯一入口。无论你用 kubectl、Dashboard 还是其他组件,最终都是调用 API Server 的接口。它负责认证、鉴权、校验请求,然后把对象状态写入 etcd。可以理解为整个集群的"总前台"。
etcd 是分布式键值存储,保存集群的全部状态数据:有哪些节点、哪些 Pod、配置是什么。它是集群里最关键的组件,一旦数据丢失,集群状态就没了。所以 etcd 必须做备份,且对磁盘 IO 延迟极其敏感(后文 092 篇会展开)。
kube-scheduler 负责调度。当有新的 Pod 需要运行时,它根据资源请求、亲和性规则、污点容忍等条件,从众多节点里挑一个最合适的,告诉 API Server "把 Pod 绑到这个节点"。
kube-controller-manager 是一组控制器进程的集合。每个控制器只做一件事,且是"对比期望状态和实际状态,然后朝着期望状态努力"。比如 Deployment 控制器发现副本数不够就创建 Pod,节点控制器发现节点失联就做相应处理。
这套"期望状态"的思想是 Kubernetes 的灵魂:你在 YAML 里写"我要 3 个副本",这是期望状态;控制器不停地把实际状态收敛到期望状态。你不需要写"创建第 1 个、创建第 2 个"这样的过程式脚本。
四、工作节点:干活的组件
每台工作节点上运行三个关键组件。
kubelet 是节点上的"工头"。它接收 API Server 下发的 Pod 规格,确保对应的容器真的跑起来、健康检查通过。它还定期向控制平面汇报节点状态和资源使用。节点变 NotReady,第一步就是查 kubelet。
kube-proxy 负责实现 Service 的网络规则。它把发往 Service IP 的流量转发到后端某个 Pod,用的是 iptables 或 IPVS 模式。新版本也支持基于 eBPF 的替代方案(如 Cilium),性能更好但复杂度更高。
容器运行时(Container Runtime) 是真正拉起容器的组件,通过 CRI 接口对接 kubelet。主流是 containerd 和 CRI-O。你需要区分的层次是:kubelet 说"我要一个符合这个镜像的容器",运行时去拉镜像、按 OCI 规范把容器跑起来。
一个必须澄清的常见误解:Docker 和 Kubernetes 不是替代关系。Docker 既提供了打包镜像的方式(Dockerfile、镜像格式),也提供了一套运行时。Kubernetes 使用 Docker 镜像格式,但不用 Docker 引擎来运行容器,而是用 containerd 这类更底层的运行时。所以你本地用 docker build 打包镜像完全没问题,镜像推到仓库后 Kubernetes 照样能拉取运行。
五、一个请求的完整链路
把上面组件串起来,看一个 Pod 的诞生过程:你执行 kubectl apply -f web-deploy.yaml,请求发给 API Server,它校验后把 Deployment 对象写入 etcd。Deployment 控制器发现有新对象,创建一个 ReplicaSet;ReplicaSet 控制器再创建对应的 Pod 对象(此时 Pod 只是存在于 etcd 里的记录,还没真正运行)。调度器发现有待调度的 Pod,选一个节点并把 Pod 绑定上去。该节点的 kubelet 收到通知,调用容器运行时拉镜像、启动容器,然后上报状态。至此 Pod 变成 Running。
外部访问的链路则是:流量先到 Ingress 或 Service,kube-proxy 按规则转发到某个就绪的 Pod IP,容器内的进程处理请求并返回。整条链路每个环节出问题都会表现为"服务不可用",所以排障时要按链路逐段确认,而不是盲目重启。
六、声明式管理与常用命令
Kubernetes 推荐声明式管理:把想要的最终状态写进 YAML,交给集群去实现。对比一下两种风格,能帮你建立正确习惯。
| 维度 | 命令式(kubectl run/create 等) | 声明式(kubectl apply -f) |
|---|---|---|
| 描述内容 | 描述"要做什么动作" | 描述"最终要什么状态" |
| 可重复执行 | 重复执行可能报已存在 | 可反复执行,结果一致 |
| 版本管理 | 命令散落,难追溯 | YAML 入 Git,可审计可回滚 |
| 适用场景 | 临时调试、快速查看 | 生产环境、自动化流水线 |
# 查看集群整体状态
kubectl cluster-info
kubectl get nodes -o wide
# 查看所有命名空间的 Pod 及其所在节点
kubectl get pods -A -o wide
# 查看 Pod 详细状态与事件(最常用排障命令)
kubectl describe pod -n
# 进入容器排查
kubectl exec -it -- /bin/sh
# 端口转发到本地调试
kubectl port-forward svc/web-svc 8080:80
# 扩缩容
kubectl scale deploy web --replicas=5
# 查看滚动更新历史并回滚
kubectl rollout history deploy/web
kubectl rollout undo deploy/web
# 查看资源使用(需装 metrics-server)
kubectl top nodes
kubectl top pods
常见问题
Q:Kubernetes 和 Docker 到底什么关系?
Docker 负责"打包和单机运行容器",Kubernetes 负责"在集群里编排容器"。Kubernetes 使用 Docker 的镜像格式,但运行时用的是 containerd 等通过 CRI 对接的组件。两者是不同层次、可协作的关系。
Q:学习 Kubernetes 一定要先会 Docker 吗?
建议先理解镜像、容器、分层这几个概念,但不必精通 Docker 的所有命令。掌握 Dockerfile 和镜像构建即可,剩下的精力放在 K8s 的对象模型上。
Q:Pod 和应用是什么映射关系?
一般来说一个应用进程对应一个 Pod 里的一个容器。一个 Pod 里塞多个业务容器是不推荐的,除非它们确实需要共享网络和存储(如边车代理)。
Q:Service 的 ClusterIP 能在集群外访问吗?
不能。ClusterIP 只在集群内部有效。要外部访问用 NodePort(每台节点放一个端口,暴露面大)、LoadBalancer(需云支持)或 Ingress(推荐,统一入口)。
Q:为什么我改了 YAML,Pod 却没重启?
只有会影响 Pod 模板的字段(如镜像、环境变量、资源请求)改动才会触发滚动更新。改 Service、ConfigMap 本身不会让 Pod 重启,需要额外机制(如挂载触发或手动重启)。
Q:单机能不能跑 Kubernetes?
可以,用 minikube、kind 或 k3s 这类轻量方案体验。但单机没有高可用意义,只适合学习和开发,不要用于生产。
总结
Kubernetes 解决的是多机多容器场景下的调度、自愈、扩缩容和服务发现问题,本质是一个"把实际状态持续收敛到期望状态"的系统。理解"期望状态"这个词,比记住任何命令都重要。
你日常操作的是抽象对象而不是容器:Pod 是最小调度单位,ReplicaSet 维持副本数,Deployment 管无状态应用和滚动更新,Service 提供稳定入口,Ingress 管集群入口,ConfigMap/Secret 管配置,Namespace 做隔离。
控制平面由 API Server(唯一入口)、etcd(状态存储)、Scheduler(调度)、Controller Manager(控制器)组成;工作节点由 kubelet、kube-proxy 和容器运行时组成。排障时按这个链路逐段确认,效率远高于盲目重启。
Kubernetes 和 Docker 不是替代关系,前者用镜像格式但不直接用 Docker 引擎。生产环境坚持声明式管理,把 YAML 纳入版本控制,才能获得可审计、可回滚的能力。
最后提醒一点:Kubernetes 的复杂度是有代价的。一两个小服务、几台机器,用它反而增加负担。后面 092 篇会讲集群该怎么规划规模,094 篇会讲什么时候才真正值得上云原生。
企业QQ咨询




