一、三台服务器,二十个容器,docker-compose 撑不住了
云间书店开分店,服务器从 1 台变 3 台。小陈发现 docker-compose 不好使了:
docker-compose 的局限:
① 只能在"一台机器"上编排 —— 3 台服务器要各管各的
② 没有自动调度 —— 容器不会自己跑到"空闲的那台"去
③ 没有自动扩容 —— 流量大了不会自动多开几个容器
④ 没有自愈 —— 一台机器挂了,它上面的容器不会自动迁移
⑤ 没有跨机网络 —— 各机器的容器互相发现是个难题
结论:单机编排用 compose,跨机集群要用 Kubernetes!
老周:"K8s 是什么?它是 Google 开源的容器编排平台——管理'一群服务器上的所有容器',自动调度、自动扩容、自动自愈。它是容器世界的'操作系统':Docker 是进程,K8s 是管理所有进程的操作系统。"
二、K8s 的架构:Master 和 Worker
"先看 K8s 的骨架。"老周画:
Kubernetes 集群架构:
┌────────────────────────────────────────┐
│ 控制平面(Master/Control Plane)—— 大脑 │
│ ├─ kube-apiserver :所有请求的入口 │
│ ├─ scheduler :决定 Pod 跑哪台机器 │
│ ├─ controller :保证"期望状态"(说3个就3个)│
│ └─ etcd :集群的"数据库"(状态) │
├────────────────────────────────────────┤
│ 工作节点(Worker Node)—— 干活的 │
│ ├─ Node1 ── kubelet + 容器运行时(Docker) │
│ │ └─ 跑着一些 Pod │
│ ├─ Node2 ── kubelet + 容器运行时 │
│ │ └─ 跑着一些 Pod │
│ └─ Node3 ── kubelet + 容器运行时 │
│ └─ 跑着一些 Pod │
└────────────────────────────────────────┘
"关键概念:声明式管理(Declarative)——你告诉 K8s'我想要 3 个 web 容器',K8s 保证任何时候都有 3 个(多了杀掉、少了补上)。你不指挥细节,你声明目标,K8s 自己搞定。 这就是 K8s 和手动操作的本质区别。"
三、第一个 K8s 对象:Pod
"K8s 最小的调度单位不是容器,是 Pod。"老周说:
Pod(豆荚):
一组"紧耦合的容器"的集合(通常 1 个主容器 + 几个辅助容器)
- 同一个 Pod 里的容器共享网络(同一个 IP)和存储
- Pod 是"临时"的:挂了就被 K8s 重建(新 IP)
类比:
容器 = 进程
Pod = 一个"工作单元"(一小组进程待在一起)
节点 = 一台机器
集群 = 整个机房
示例:云间书店的 AI 服务 Pod
Pod "ai-pod":
├── 主容器:ai-recommend(AI 荐书服务)
└── 辅助容器:sidecar(日志收集,共享日志文件)
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ai-pod
spec:
containers:
- name: ai-recommend
image: harbor.yunjian.com/library/ai:v1.2.3
ports:
- containerPort: 8000
"不过注意:生产上你很少直接创建 Pod——因为 Pod 挂了就没了。你要的是'永远有 Pod 在跑',这就要用 Deployment。"
四、Deployment:声明"我要几个 Pod"
"Deployment 是管理 Pod 的'指挥官'——它保证集群里始终有指定数量的 Pod。"老周说:
# deployment.yaml —— 云间书店 API 服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deploy
spec:
replicas: 3 # 声明:我要 3 个副本
selector:
matchLabels:
app: api
template: # Pod 模板
metadata:
labels:
app: api
spec:
containers:
- name: api
image: harbor.yunjian.com/library/api:v1.2.3
ports:
- containerPort: 5000
resources: # 资源限制(K8s 也要配!)
requests: # 申请量(调度依据)
cpu: 250m
memory: 256Mi
limits: # 上限(Cgroup)
cpu: 500m
memory: 512Mi
# 部署 / 查看 / 扩容 / 滚动更新
kubectl apply -f deployment.yaml # 部署
kubectl get pods # 看 Pod
kubectl scale deploy api-deploy --replicas=5 # 手动扩容到 5 个
kubectl set image deploy api-deploy api=...:v1.3.0 # 滚动更新(不中断!)
kubectl rollout undo deploy api-deploy # 回滚到上一版本
"Deployment 的三个能力:确保副本数、滚动更新(逐个替换,不中断服务)、一键回滚。 你只需要声明'要 3 个',Pod 挂了它自动补,更新时它逐个换——这就是'自愈 + 零停机发布'。"
五、Service:稳定的入口
"Pod 是临时的,IP 会变。Service 给一组 Pod 提供一个稳定的入口。"老周说:
# service.yaml —— 给 api-deploy 提供固定入口
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector: # 挑哪些 Pod(按标签)
app: api
ports:
- port: 5000 # Service 的端口
targetPort: 5000 # 转发到 Pod 的端口
type: ClusterIP # 集群内部访问
Service 三种类型:
ClusterIP :集群内部访问(默认,只能集群内)
NodePort :通过"节点 IP:端口"从外部访问
LoadBalancer:云厂商负载均衡器(外部直接访问,生产常用)
工作方式:
外部 → LoadBalancer → Service(api-service:5000) → 3 个 api Pod(自动负载均衡)
Pod 挂了换了 IP 也没关系——Service 永远在,Pod 一直换
"Service = 稳定门牌号;Pod = 随时换房的住户。 门牌号永远不变,住户随便换——对外部来说,服务一直是稳定的。"
六、K8s 进阶三件套:HPA、ConfigMap、存储
"入门之后,还有三个进阶概念,先混个脸熟:"老周说:
① HPA(Horizontal Pod Autoscaler)弹性伸缩:
根据 CPU/内存/流量,自动增减 Pod 数量
→ 双十一流量涨了?自动从 3 个 Pod 扩到 20 个
→ 流量降了?自动缩回 3 个
② ConfigMap / Secret 配置管理:
ConfigMap:非敏感配置(如开关、URL)
Secret :敏感配置(密码、密钥,Base64 加密存储)
→ 配置和镜像分离,改配置不用重新打镜像!
③ 存储(PV/PVC):
PV(PersistentVolume):一块"持久化存储"(像数据卷)
PVC(PersistentVolumeClaim):Pod 申请用一块存储
→ 容器/Pod 随便换,数据在 PV 里不丢(和 Docker Volume 一个道理)
# hpa.yaml —— 自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-deploy
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # CPU 超 60% 就扩容
"HPA 是'自动档'——云间书店双十一再也不用半夜爬起来手动加服务器了。K8s 帮你盯着指标,自己扩、自己缩。"
七、章末:老周的第八、九层总结
第八层:K8s 入门
├── 架构:Master(大脑)+ Worker(干活)
├── 声明式:说目标,不指挥细节("要3个"就保持3个)
├── Pod:最小调度单位(一组容器)
├── Deployment:保证副本数 + 滚动更新 + 回滚
└── Service:稳定入口(ClusterIP/NodePort/LoadBalancer)
第九层:K8s 进阶
├── HPA:按指标自动扩缩容
├── ConfigMap/Secret:配置与镜像分离
└── PV/PVC:持久化存储(数据不随 Pod 丢)
"小陈,K8s 是很深的海洋,这一章只是带你'见了海'。但你已经知道核心思想了:声明目标,机器干活。 有了 K8s,云间书店的容器能跨机器调度、自动扩容、自动自愈——基础设施真正'活'了。"
"师傅,那代码改了之后,怎么自动变成新镜像、自动部署到 K8s?"小陈问,"难道还手动 build、手动 kubectl apply?"
"好问题!这就引出了容器时代最重要的自动化——CI/CD。下一章,我们打通'提交代码 → 自动构建 → 自动测试 → 自动部署'的流水线,让云间书店的发布变成'一键全自动'。"