第 1 章:Kubernetes 核心概念总览------Pod、Deployment、Service 一次搞懂
本专栏目标:从零开始,既讲透 Kubernetes 的核心概念,也带你亲手搭出一个可运行的生产级集群,并掌握现代 GitOps 运维方式。
专栏完整目录
- 核心概念总览(本章)
- Pod:从 YAML 到调度全流程
- Deployment:从 YAML 到零停机发布
- StatefulSet:从无状态到有状态应用管理
- Service:从 ClusterIP 到负载均衡
- Ingress:从七层路由到 TLS 终结
- ConfigMap & Secret:从配置注入到安全加密
- Volume:EmptyDir、HostPath、PV、PVC、StorageClass 一次讲清
- HPA:从自动扩缩容到企业级弹性伸缩
- Helm:从手动部署到企业级包管理
- ArgoCD 与 GitOps:现代运维方式
- K8s 集群安装部署实战(3 台 ECS + Prometheus + Grafana)
- 配套实战练习文档
1.1 Kubernetes 是什么
Kubernetes(简称 K8s)是 Google 开源的容器编排系统,它负责自动化地部署、扩展和管理容器化应用。
用一句话概括它和 Docker 的关系:
Docker 解决了"单个容器怎么跑"的问题;K8s 解决了"成百上千个容器怎么协同跑"的问题。
1.1.1 为什么需要编排
假设你用 Docker 部署了一个电商系统:
arduino
┌─────────────────┐ ┌─────────────────┐
│ 服务器 A │ │ 服务器 B │
│ docker run 商品服务 │ │ docker run 订单服务 │
│ docker run 用户服务 │ │ docker run MySQL │
│ docker run Redis │ │ │
└─────────────────┘ └─────────────────┘
当流量突然翻倍时,你需要:
- 登录每台机器,手动执行
docker run启动更多实例 - 上游 Nginx 手动改配置,把新实例加进 upstream
- 某台机器挂了,上面的容器全部停止,业务中断
- 发布新版本时,逐台停旧容器、起新容器,期间服务不可用
K8s 就是为解决这类问题而生的。它把上面这些重复、容易出错的操作自动化了。

1.1.2 声明式与命令式的区别
命令式是你告诉系统"怎么做":
bash
ssh serverA
systemctl stop nginx
docker pull myapp:v2
docker run -d -p 8080:8080 myapp:v2
# 漏掉一步,系统就停在不一致的状态
声明式是你告诉系统"要什么":
yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
template:
spec:
containers:
- name: myapp
image: myapp:v2
然后执行 kubectl apply -f deployment.yaml。K8s 会自己算出"当前状态"和"期望状态"的差异,并完成滚动替换。

这就是 K8s 的灵魂。
1.2 三大核心资源:Pod、Deployment、Service
这三个对象是你学习 K8s 的入口。本章先建立整体印象,后面几章会逐个拆碎。
1.2.1 Pod:最小调度单元
Pod 是 K8s 调度和管理的最小单位,一个 Pod 里可以运行一个或多个容器。这些容器共享同一个 IP、端口空间和存储卷。
为什么 K8s 不直接调度容器,而要引入 Pod?
因为实际场景中,容器之间经常需要紧密协作:
c
┌────────────────── Pod ──────────────────┐
│ IP: 10.244.36.71(共享) │
│ │
│ ┌────────────┐ ┌──────────────┐ │
│ │ 主业务容器 │ │ 日志收集 sidecar│ │
│ │ Nginx:80 │ │ fluent-bit │ │
│ └────────────┘ └──────────────┘ │
│ 共享卷 /var/log/nginx/access.log │
└─────────────────────────────────────────┘
主容器写日志,sidecar 读同一个卷并上传到日志中心。它们必须共享网络/存储,因此必须放在同一个 Pod 里。
初学者最常见误区:以为 Pod 就是容器。实际上 Pod 是"一组共享运行环境的容器",日常 99% 是一个容器,但概念上必须理解成"豆荚"。
1.2.2 Deployment:管理 Pod 的"班长"
直接创建 Pod 有两个问题:
- Pod 挂了没人管
- 想扩容、升级要手动操作一堆 Pod
Deployment 就是来解决这两个问题的。它通过 ReplicaSet 作为中间层,替你盯着 Pod:
markdown
Deployment(管版本、管发布)
└── ReplicaSet(管副本数)
└── Pod(跑容器)
bash
# 创建 3 个副本的 Nginx
kubectl create deployment web --image=nginx:alpine --replicas=3
# 扩成 5 个
kubectl scale deployment web --replicas=5
# 升级到新版
kubectl set image deployment/web nginx=nginx:1.27
# 新版有问题,回滚
kubectl rollout undo deployment/web
1.2.3 Service:稳定的访问入口
Pod 的 IP 是临时的。重建一次 IP 就变一次,调用方没法直接写死 Pod IP。
Service 给一组 Pod 提供一个固定虚拟 IP 和负载均衡,并通过标签选择器(label selector)关联后端 Pod:
yaml
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # 所有带 app=web 标签的 Pod 都是后端
ports:
- port: 80
targetPort: 80
后端 Pod 怎么变,访问方始终通过 http://web:80 调用,不需要关心 IP。
1.3 K8s 架构速览
一个 K8s 集群由 控制平面(Master) 和 工作节点(Node) 组成:

控制平面四大件:
- apiserver:唯一入口,认证、鉴权、准入、事件通知
- etcd:集群状态的唯一存储
- scheduler:为新 Pod 选择节点
- controller-manager:持续对比期望与实际状态,自动纠偏
工作节点三件半:
- kubelet:节点管家,执行 apiserver 指令,管理 Pod 生命周期
- containerd:容器运行时,拉镜像、起容器
- kube-proxy:维护 Service 负载均衡规则
- CNI 插件(Calico/Flannel/Cilium):给 Pod 分配 IP、打通跨节点网络
1.4 贯穿全专栏的实战集群
从第 12 章开始,我们会亲手搭出这样一个集群:
| 节点 | 内网 IP | 公网 IP | 角色 | 配置 |
|---|---|---|---|---|
| k8s-master | 192.168.0.201 | 121.40.218.245 | 控制平面 | 4C8G |
| k8s-node1 | 192.168.0.202 | 47.98.108.127 | 工作节点 | 4C8G |
| k8s-node2 | 192.168.0.203 | 118.178.120.248 | 工作节点 | 4C8G |
bash
# 搭建完成后的最终状态
$ kubectl get nodes -o wide
NAME STATUS ROLES VERSION INTERNAL-IP CONTAINER-RUNTIME
k8s-master Ready control-plane v1.31.14 192.168.0.201 containerd://1.7.29
k8s-node1 Ready <none> v1.31.14 192.168.0.202 containerd://1.7.29
k8s-node2 Ready <none> v1.31.14 192.168.0.203 containerd://1.7.29
后续每一章的命令和案例,都会基于这个真实集群输出,可以直接复制练习。
1.5 本章小结
- K8s 是容器编排系统,核心能力:自愈、扩容、滚动升级、服务发现
- 三大核心对象:
- Pod:最小调度单元,一个或多个容器共享网络和存储
- Deployment:通过 ReplicaSet 管理 Pod,负责副本数、版本、滚动更新
- Service:为 Pod 提供稳定虚拟 IP 和负载均衡
- 架构分两大阵营:控制平面(Master)做决策,工作节点(Node)执行
- 学习 K8s 的关键心态:从命令式转向声明式,关心"期望状态",让系统去收敛
1.6 课后思考
- 为什么 K8s 的最小单位是 Pod,而不是容器?一个 Pod 里放两个容器的典型场景是什么?
- 如果你直接
kubectl run创建一个裸 Pod,然后删掉它,会发生什么?如果换成 Deployment 创建后再删一个 Pod,又会发生什么? - Service 的 selector 如果写错了,会导致什么问题?怎么去验证 Service 是否关联到了正确的 Pod?