Kubernetes 入门 — 从集群 anatomy 到 Pod、Deployment 与 Service¶
这一章把第 14 章的任务清单变成具体对象。 读完你会画出一张集群图 (master/worker/etcd 各就各位),说清 Pod 为什么不是"容器的同义词", 以及为什么访问一个服务永远通过 Service 而不是直接找 Pod。 主线例子:两个副本的 hello 应用——ReplicaSet 管活,Service 给个稳定门牌, DNS 让别的 Pod 按名字敲门。
1. 集群的 anatomy¶
一组服务器(虚拟机或裸金属),每台非 master 即 worker(书里特意说明: K8s 语境里"node"专指跑负载的 worker;master 不跑业务)1。
数量纪律,两条都关乎高可用2:
| 组件 | 数量规则 | 原因 |
|---|---|---|
| etcd 集群(分布式键值库,存集群全部状态) | 奇数 | Raft 共识协议的协调要求 |
| master 节点 | 奇数,生产至少 3 | 互成共识组;绝不能生产单 master |
etcd 存的是"集群的状态"——拓扑、在跑什么服务、网络设置、secrets——
不含应用自己产出的数据。它使命攸关,任何要高可用的环境都不该只跑单 etcd2。
master 前面还应放一个负载均衡器,配一个众所周知的域名(如
admin.example.com),所有管理工具都走这个 LB,而不是直连某台 master 的
公网 IP3。
网络底座:所有节点由物理网络(underlay)相连;K8s 为整个集群定义 一张扁平网络,但不提供实现——只定义 CNI(容器网络接口)规范, 实现交给第三方插件。CNI 的要求很简单也很硬4:
集群里任何一个 Pod 能直达任何其他 Pod,中间不允许 NAT; 节点上的进程与 Pod 之间同样互通,双向无 NAT。
2. master 与 worker 里面各有什么¶
master 节点运行管理面组件(API server——一切操作的入口与鉴权点; scheduler——决定 Pod 去哪;controller 们——持续调和期望状态)。 worker 节点上跑三样5:
- kubelet:首要的节点代理,按 Pod 规格确保本机所有容器的容器在跑且健康 (Pod 规格是 YAML/JSON 写的声明文件);
- 容器运行时:真正拉镜像、起容器(containerd/runc,第 03 章那对积木);
- kube-proxy:实现 Service 的虚拟 IP 与负载转发。
3. 本地集群三选一¶
第 02 章装好的工具在这里复用,书里给的对照表(要点):Docker Desktop 勾一下 最省事(单节点);minikube 功能全、适合折腾;kind(Kubernetes IN Docker) 集群跑在 Docker 容器里,快而可复现,CI/CD 的首选6。三者给的都是 真 Kubernetes API,本章所有例子一视同仁。
4. Pod:K8s 的原子单元,不是"一个容器"¶
K8s 里不能直接跑容器,只能跑 Pod。Pod 是一个或多个同地协作容器的抽象, 它们共享同一套内核 namespace(尤其 network namespace)——Swarm 里 没有对应物7。
机制上,Pod 靠 pause 容器实现:K8s 先起一个几乎什么都不干的 pause 容器,
它的唯一职责是替这个 Pod 占住并维系那组 namespace;之后 Pod 里的其他容器
用 Docker 的 --net container:pause 特性复用这个现成 namespace,
不新建 veth。书里用纯 Docker 命令模拟了全过程8:
docker container run --detach --name pause nginx:alpine ← 占位
docker container run --name main -d -it \
--net container:pause alpine:latest ash ← 加入它的 netns
docker exec -it main /bin/sh
/ # wget -qO- localhost ← 直接摸到 pause 里的 nginx
/ # ip a show eth0 ← 两个容器 eth0 同一个 IP——Pod 的指纹[^8]
由此推出的 Pod 三定律(第 10 章的伏笔在此收拢):
- 一个 Pod 一个 IP,在全网唯一(如 10.0.12.3);
- 同 Pod 内容器经 localhost 互通(主容器调边车就是
http://localhost:3000); - 同 Pod 内端口不许撞(一个 namespace 里不能两个 80)7。
5. ReplicaSet 与 Deployment:逐层加能力¶
单个 Pod 不够用:崩了怎么办?更新怎么办?所以有了阶梯9:
ReplicaSet 定义并治理一组完全相同的 Pod,三大特性: 自愈、可扩缩、尽最大努力调和期望状态9。 Deployment 是给 ReplicaSet 的包装对象,加上滚动更新与回滚—— 第 14 章的零停机部署,在这里就是改一行镜像 tag 的事(第 16 章实操)9。
6. Service:给飘忽的 Pod 一个稳定门牌¶
问题:Pod 来来去去(崩溃重建、调度搬家),IP 不稳定;可客户端
(比如 Web API 要调 payments、shipping、ordering)只想写
http://payments:300010。
Service 就是答案:为 ReplicaSet/Deployment 提供稳定端点。
它有一个全集群唯一的虚拟 IP(VIP)和一个全集群唯一的端口;
通过 selector(基于 label 的选择器,如 app=web)圈定要代理的 Pod——
每个 K8s 对象都可以挂任意个 label。配套的 DNS 自动给 Service 加名字,
集群内按名访问10。
书里的动手流程(主线例子的骨架)11:
① ReplicaSet 起两个 Pod(镜像会回显自己是谁,便于看负载分流)
② ClusterIP Service:selector 圈住它们;get endpoints 能看到两个 Pod IP
③ 集群里起个短命测试容器 curl 服务名 → DNS 解析 + 流量在两个 Pod 间轮转
④ 扩到三副本 → endpoints 自动多一个,Service 零改动[^11]
Service 的类型按暴露范围递进(书里演示了前几种):ClusterIP(默认, 仅集群内)、NodePort(每个节点开同一个高端口,外部可经节点 IP 访问)、 LoadBalancer(云厂商接负载均衡器)、以及无 VIP 的 headless(DNS 直接 返回所有 Pod IP,给客户端自己挑)。对外按 URL 分流(第 10 章 Traefik 的 集群版)由 Ingress(更新的 Gateway API)承担12。
7. 生态三件套¶
章末盘点了围绕 K8s 的三个高频工具(第 14 章预告过,这里落地)13:
- Helm 3:K8s 的包管理器,把一整套 manifest 打成 chart,参数化模板, 一条命令装复杂应用;
- Kustomize:不改原文件,用 overlay/patch 做环境定制(第 11 章 overrides 思想的 K8s 原生版);
- GitOps(Argo CD / Flux):manifest 进 Git 当唯一事实源,控制器盯仓库 自动调和集群——可审计、可回滚。
8. 作者的判断与证据¶
- "Pod 是不可直接跑容器的执行单元"是 K8s 与 Docker/Swarm 最本质的概念 差异,书用 pause 容器机制把"为什么"讲透了78。
- 对象阶梯(Pod→ReplicaSet→Deployment)是精心设计的责任分层: 每层只加一种能力,换来组合的自由(你也可以裸用 ReplicaSet,只是没人这么干)。
- CNI 的"无 NAT 全互通"是硬约束——它解释了为什么 K8s 网络的插件生态 百花齐放 yet 行为一致4。
- 工具三件套是生态共识,非作者一家之言13。
判断(我们的,不是书里的): 本章概念与未来章节的对应关系值得现在记住: Pod≈第 14 章的"执行单元"、Deployment≈"复制式服务+滚动更新"、 Service≈"接线员/负载均衡"、Ingress≈"第 7 层路由"、 kubelet≈"节点上的代理人"、etcd≈"期望状态的账本"。 以后每见到一个新 K8s 对象,先问"它自动化的是十二项任务里的哪一项"—— 这个习惯比背 API 耐用得多。 如果错,会错在: Service 的 VIP 实现在历史上有过 iptables/IPVS/eBPF 多代, 未来可能继续变;但"稳定端点 + selector + DNS"的语义不变。
9. 边界与局限¶
- 本章停在"介绍":滚动更新的参数与回滚实操、探针的配置,全在第 16 章。
- 网络实现留白:CNI 只给规范,Calico/Cilium 等插件的差异(性能、策略能力) 未比较。
- 存储只字未提:PV/PVC/StorageClass 在本书整体着墨少,StatefulSet 只在 第 05 章 patterns 里露过名。
- 安全面没展开:RBAC、NetworkPolicy、Pod 安全标准都留给读者去查 (书卡 notCovered 已如实记录)。
10. 可带走的¶
- master 管集群(奇数、≥3)、worker 跑 Pod;etcd 奇数、存集群状态2。
- CNI:Pod 全互通、全程无 NAT——K8s 只定规范,实现靠插件4。
- worker 三件套:kubelet(管 Pod)、容器运行时、kube-proxy(管 Service)5。
- Pod = 一个/多个共享 network namespace 的容器;pause 容器占位维系78。
- Pod 三定律:一个 IP、localhost 互通、端口不撞7。
- Pod→ReplicaSet(自愈扩缩)→Deployment(滚动+回滚)9。
- Service = 稳定 VIP + label selector + DNS 名;类型 ClusterIP/NodePort/ LoadBalancer/headless1011。
- Ingress/Gateway API 按 URL 分流;Helm/Kustomize/GitOps 是日常三件套1213。
11. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| master/worker 定义 | Understanding Kubernetes architecture | text/163-fm-understanding-kubernetes-architecture.txt:14(搜「set of servers」) · text/163-fm-understanding-kubernetes-architecture.txt:20(搜「workload」) |
| etcd 与奇数纪律 | Understanding Kubernetes architecture | text/163-fm-understanding-kubernetes-architecture.txt:50(搜「distributed key-value」) · text/163-fm-understanding-kubernetes-architecture.txt:52(搜「odd」) · text/163-fm-understanding-kubernetes-architecture.txt:58(搜「never run only a single」) |
| CNI 无 NAT 规则 | Understanding Kubernetes architecture | text/163-fm-understanding-kubernetes-architecture.txt:36(搜「CNI」) · text/163-fm-understanding-kubernetes-architecture.txt:39(搜「without any」) |
| LB 与 FQDN | Kubernetes master nodes | text/164-fm-kubernetes-master-nodes.txt:1(搜「load balancer」) · text/164-fm-kubernetes-master-nodes.txt:4(搜「FQDN」) |
| 单节点集群警示 | Cluster nodes | text/165-fm-cluster-nodes.txt:3(搜「single-node」) |
| kubelet 等三服务 | Introduction to local Kubernetes | text/166-fm-introduction-to-local-kubernetes.txt:4(搜「Kubelet」) · text/166-fm-introduction-to-local-kubernetes.txt:6(搜「Pod specifications」) |
| 本地三工具对照 | Introduction to local Kubernetes | text/167-fm-introduction-to-pods.txt:4(搜「kind」) · text/167-fm-introduction-to-pods.txt:5(搜「containers」) |
| Pod 定义与 IP | Introduction to Pods | text/167-fm-introduction-to-pods.txt:16(搜「atomic units」) · text/167-fm-introduction-to-pods.txt:27(搜「IP address」) · text/167-fm-introduction-to-pods.txt:33(搜「own port」) |
| pause 容器机制 | Introduction to Pods | text/167-fm-introduction-to-pods.txt:61(搜「pause」) · text/167-fm-introduction-to-pods.txt:65(搜「--net」) · text/167-fm-introduction-to-pods.txt:95(搜「--detach」) |
| localhost 互通与同一 IP | Introduction to Pods | text/167-fm-introduction-to-pods.txt:78(搜「localhost」) · text/167-fm-introduction-to-pods.txt:126(搜「same IP address」) |
| ReplicaSet 三特性 | Kubernetes Services | text/170-fm-kubernetes-services.txt:4(搜「self-healing」) · text/170-fm-kubernetes-services.txt:6(搜「wrapper」) |
| Service 问题与答案 | Kubernetes Services | text/170-fm-kubernetes-services.txt:20(搜「payments」) · text/170-fm-kubernetes-services.txt:29(搜「stable endpoints」) · text/170-fm-kubernetes-services.txt:37(搜「virtual IP」) · text/170-fm-kubernetes-services.txt:40(搜「selector」) |
| 动手:endpoints 与扩缩 | Kubernetes Services | text/170-fm-kubernetes-services.txt:71(搜「apply」) · text/170-fm-kubernetes-services.txt:76(搜「Endpoints」) · text/170-fm-kubernetes-services.txt:78(搜「test container」) |
| headless 与 nslookup | Context-based routing | text/171-fm-context-based-routing.txt:1(搜「nslookup」) |
| 三工具 | Popular tools: GitOps, Helm 3, and Kustomize | text/173-fm-summary.txt:2(搜「GitOps」) · text/173-fm-summary.txt:4(搜「Helm 3」) · text/173-fm-summary.txt:6(搜「Kustomize」) |
-
出处:「Understanding Kubernetes architecture」第 13–27 段(
text/163-fm-understanding-kubernetes-architecture.txt:14,搜「set of servers」;:20,搜「workload」;:24,搜「small and odd」)。 ↩ -
出处:「Understanding Kubernetes architecture」第 47–67 段(
text/163-fm-understanding-kubernetes-architecture.txt:50,搜「distributed key-value」;:52,搜「Raft」;:58,搜「never run only a single etcd」;:62,搜「at least three master nodes」)。 ↩↩↩ -
出处:「Kubernetes master nodes」第 1–7 段(
text/164-fm-kubernetes-master-nodes.txt:1,搜「load balancer」;:3,搜「FQDN」)。 ↩ -
出处:「Understanding Kubernetes architecture」第 33–44 段(
text/163-fm-understanding-kubernetes-architecture.txt:34,搜「flat network」;:36,搜「CNI」;:38,搜「without any Network Address Translation」)。 ↩↩↩ -
出处:「Introduction to local Kubernetes」的节点服务清单(
text/166-fm-introduction-to-local-kubernetes.txt:4,搜「Kubelet」;:6,搜「Pod specifications」)。 ↩↩ -
出处:「Introduction to local Kubernetes」与「Introduction to Pods」开头的工具表(
text/167-fm-introduction-to-pods.txt:4,搜「kind」;:3,搜「CI/CD」;:5,搜「Docker containers」)。 ↩ -
出处:「Introduction to Pods」第 14–40 段(
text/167-fm-introduction-to-pods.txt:15,搜「cannot run containers directly」;:19,搜「share the same」;:27,搜「unique」;:32,搜「own port」)。 ↩↩↩↩↩ -
出处:「Introduction to Pods」第 41–150 段(
text/167-fm-introduction-to-pods.txt:61,搜「pause container」;:65,搜「--net」;:95,搜「--detach」;:115,搜「wget」;:126,搜「same IP address」)。 ↩↩↩ -
出处:「Kubernetes Services」第 1–10 段(Deployment/ReplicaSet 关系因转码顺序位于本文件开头:
text/170-fm-kubernetes-services.txt:4,搜「self-healing」;:5,搜「rolling updates」;:6,搜「wrapper」)。 ↩↩↩↩ -
出处:「Kubernetes Services」第 12–42 段(
text/170-fm-kubernetes-services.txt:21,搜「should never have to care」;:26,搜「come and go」;:29,搜「stable endpoints」;:36,搜「virtual IP」;:40,搜「selector」)。 ↩↩↩ -
出处:「Kubernetes Services」第 43–98 段(
text/170-fm-kubernetes-services.txt:61,搜「apply」;:72,搜「get svc」;:76,搜「Endpoints」;:78,搜「short-lived test container」)。 ↩↩ -
出处:「Context-based routing」(
text/171-fm-context-based-routing.txt:1,搜「nslookup」;:3,搜「delete svc」)。 ↩↩ -
出处:「Summary」的工具小结(
text/173-fm-summary.txt:2,搜「GitOps」;:3,搜「Helm 3」;:5,搜「Kustomize」)。 ↩↩↩