跳转至

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 章的伏笔在此收拢):

  1. 一个 Pod 一个 IP,在全网唯一(如 10.0.12.3);
  2. 同 Pod 内容器经 localhost 互通(主容器调边车就是 http://localhost:3000);
  3. 同 Pod 内端口不许撞(一个 namespace 里不能两个 80)7。

5. ReplicaSet 与 Deployment:逐层加能力

单个 Pod 不够用:崩了怎么办?更新怎么办?所以有了阶梯9:

  Pod ──▶ ReplicaSet ──▶ Deployment
   裸单元    自愈+保副本数      +滚动更新+回滚

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. 可带走的

  1. master 管集群(奇数、≥3)、worker 跑 Pod;etcd 奇数、存集群状态2。
  2. CNI:Pod 全互通、全程无 NAT——K8s 只定规范,实现靠插件4。
  3. worker 三件套:kubelet(管 Pod)、容器运行时、kube-proxy(管 Service)5。
  4. Pod = 一个/多个共享 network namespace 的容器;pause 容器占位维系78。
  5. Pod 三定律:一个 IP、localhost 互通、端口不撞7。
  6. Pod→ReplicaSet(自愈扩缩)→Deployment(滚动+回滚)9。
  7. Service = 稳定 VIP + label selector + DNS 名;类型 ClusterIP/NodePort/ LoadBalancer/headless1011。
  8. 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」)

  1. 出处:「Understanding Kubernetes architecture」第 13–27 段(text/163-fm-understanding-kubernetes-architecture.txt:14,搜「set of servers」;:20,搜「workload」;:24,搜「small and odd」)。 ↩

  2. 出处:「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」)。 ↩↩↩

  3. 出处:「Kubernetes master nodes」第 1–7 段(text/164-fm-kubernetes-master-nodes.txt:1,搜「load balancer」;:3,搜「FQDN」)。 ↩

  4. 出处:「Understanding Kubernetes architecture」第 33–44 段(text/163-fm-understanding-kubernetes-architecture.txt:34,搜「flat network」;:36,搜「CNI」;:38,搜「without any Network Address Translation」)。 ↩↩↩

  5. 出处:「Introduction to local Kubernetes」的节点服务清单(text/166-fm-introduction-to-local-kubernetes.txt:4,搜「Kubelet」;:6,搜「Pod specifications」)。 ↩↩

  6. 出处:「Introduction to local Kubernetes」与「Introduction to Pods」开头的工具表(text/167-fm-introduction-to-pods.txt:4,搜「kind」;:3,搜「CI/CD」;:5,搜「Docker containers」)。 ↩

  7. 出处:「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」)。 ↩↩↩↩↩

  8. 出处:「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」)。 ↩↩↩

  9. 出处:「Kubernetes Services」第 1–10 段(Deployment/ReplicaSet 关系因转码顺序位于本文件开头:text/170-fm-kubernetes-services.txt:4,搜「self-healing」;:5,搜「rolling updates」;:6,搜「wrapper」)。 ↩↩↩↩

  10. 出处:「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」)。 ↩↩↩

  11. 出处:「Kubernetes Services」第 43–98 段(text/170-fm-kubernetes-services.txt:61,搜「apply」;:72,搜「get svc」;:76,搜「Endpoints」;:78,搜「short-lived test container」)。 ↩↩

  12. 出处:「Context-based routing」(text/171-fm-context-based-routing.txt:1,搜「nslookup」;:3,搜「delete svc」)。 ↩↩

  13. 出处:「Summary」的工具小结(text/173-fm-summary.txt:2,搜「GitOps」;:3,搜「Helm 3」;:5,搜「Kustomize」)。 ↩↩↩