目录
一、引言:为什么需要Kubernetes
1.1 容器化时代的挑战
在微服务架构盛行的今天,一个中型应用可能包含数十个甚至上百个微服务。每个服务都需要独立部署、扩缩容、监控和管理。传统的运维方式面临着巨大挑战:
手动部署的困境:
- 在10台服务器上部署一个应用,需要逐台登录、上传代码、启动服务
- 服务挂了需要手动重启,半夜被叫醒处理故障是常态
- 流量突增时,临时加机器、配置负载均衡,往往来不及响应
Docker的局限性 :
虽然Docker解决了"在我机器上能跑"的问题,但在生产环境中,我们还需要:
- 服务编排:如何管理成百上千个容器?
- 自动恢复:容器挂了谁来重启?
- 负载均衡:流量如何分发到多个容器?
- 滚动更新:如何实现零停机部署?
- 资源调度:如何合理分配CPU和内存?
1.2 Kubernetes的价值定位
Kubernetes(简称K8s)是Google开源的容器编排平台,它的核心价值在于:
声明式管理:
yaml
# 你只需要告诉K8s"我要3个Nginx实例"
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3 # 期望状态:3个副本
template:
spec:
containers:
- name: nginx
image: nginx:1.21
K8s会自动确保始终有3个Nginx容器在运行。如果某个容器挂了,K8s会自动重启;如果节点宕机,K8s会在其他节点上重新创建容器。
自动化运维:
- 自愈能力:容器崩溃自动重启,节点故障自动迁移
- 弹性伸缩:根据CPU使用率自动增减Pod数量
- 服务发现:容器IP变化后,自动更新负载均衡配置
- 滚动更新:新版本逐步替换旧版本,出问题自动回滚
资源抽象 :
K8s将底层基础设施(物理机、虚拟机、云主机)抽象为统一的计算资源池,开发者无需关心应用运行在哪台机器上。
1.3 真实场景:从混乱到有序
让我分享一个真实案例。某电商平台在使用K8s之前:
- 部署耗时:发布一次需要2小时,涉及20台服务器
- 故障恢复:平均故障恢复时间15分钟
- 资源利用率:服务器CPU利用率不到30%
引入K8s后:
- 部署耗时:5分钟完成滚动更新,零停机
- 故障恢复:容器级故障秒级自愈,节点故障1分钟内迁移
- 资源利用率:通过合理调度,CPU利用率提升到70%
这就是Kubernetes的魅力------让运维从"救火队员"变成"架构师"。
二、Kubernetes核心架构
2.1 整体架构概览
Kubernetes采用典型的Master-Worker架构,分为控制平面 (Control Plane)和工作节点(Worker Node)两部分。
工作节点 Worker Node 2
工作节点 Worker Node 1
控制平面 Master Node
API Server
集群网关
etcd
分布式数据库
Scheduler
调度器
Controller Manager
控制器管理器
Kubelet
节点代理
kube-proxy
网络代理
Container Runtime
容器运行时
Pod 1
Pod 2
Kubelet
kube-proxy
Container Runtime
Pod 3
Pod 4
架构特点:
- 控制平面:大脑,负责决策和管理
- 工作节点:手脚,负责运行容器
- API Server:所有组件通信的中心枢纽
- etcd:集群状态的唯一真实来源
2.2 控制平面组件详解
2.2.1 API Server:集群的前台接待
作用:Kubernetes的前端接口,所有操作都要经过它。
核心职责:
- 认证授权:验证用户身份,检查操作权限
- 数据验证:确保提交的配置符合规范
- 数据持久化:将数据写入etcd
- 通知机制:通过Watch机制实时通知其他组件
工作流程:
etcd 准入控制 认证/授权 API Server 用户/kubectl etcd 准入控制 认证/授权 API Server 用户/kubectl 创建Deployment 验证身份和权限 通过 准入控制检查 通过 持久化数据 写入成功 返回结果
为什么重要 :
API Server是唯一直接与etcd通信的组件,这种设计保证了数据一致性和安全性。所有组件都通过API Server间接访问etcd,避免了并发冲突。
2.2.2 etcd:集群的记忆中枢
作用:分布式键值存储,保存集群的所有状态数据。
存储内容:
- 集群配置信息
- 所有资源对象(Pod、Service、ConfigMap等)
- 网络配置和密钥
核心特性:
- 强一致性:基于Raft协议,保证数据一致
- Watch机制:支持实时监听数据变化
- 高可用:支持集群部署,通常3或5个节点
类比理解 :
如果把Kubernetes比作一家公司,etcd就是公司的档案室,记录着所有重要文件。API Server是档案管理员,所有人都要通过他来查阅或修改档案。
2.2.3 Scheduler:智能的任务分配者
作用:为新创建的Pod选择最合适的节点。
调度流程:
新Pod创建
过滤阶段
Filtering
打分阶段
Scoring
绑定阶段
Binding
资源充足?
满足亲和性?
满足污点容忍?
资源均衡性
数据本地性
亲和性权重
调度策略:
-
过滤(Filtering):筛选满足条件的节点
- CPU和内存是否充足
- 是否满足nodeSelector标签
- 是否容忍节点的污点(Taint)
-
打分(Scoring):对候选节点评分
- 资源均衡性:优先选择资源使用率低的节点
- 亲和性规则:尽量将相关Pod调度到同一节点
- 数据本地性:优先选择已有镜像的节点
-
绑定(Binding):将Pod绑定到得分最高的节点
实际案例 :
假设有3个节点,要调度一个需要2核CPU的Pod:
- 节点A:剩余1核 → 过滤阶段被淘汰
- 节点B:剩余4核,CPU使用率60% → 得分70
- 节点C:剩余3核,CPU使用率40% → 得分85
最终Pod被调度到节点C。
2.2.4 Controller Manager:集群的自动驾驶系统
作用:运行各种控制器,持续监控集群状态,确保实际状态与期望状态一致。
核心控制器:
| 控制器 | 职责 | 工作原理 |
|---|---|---|
| Deployment Controller | 管理应用部署 | 确保指定数量的Pod运行 |
| ReplicaSet Controller | 维护Pod副本数 | Pod数量不足时创建,过多时删除 |
| Node Controller | 监控节点健康 | 节点失联后迁移Pod |
| Service Controller | 管理负载均衡 | 创建云厂商的LoadBalancer |
| Endpoints Controller | 维护服务端点 | 更新Service到Pod的映射 |
控制循环(Reconciliation Loop):
否
是
Watch资源变化
读取当前状态
对比期望状态
是否一致?
执行调谐操作
举例说明:
yaml
# 期望状态:3个Nginx Pod
spec:
replicas: 3
- 场景1:当前只有2个Pod → Controller创建1个新Pod
- 场景2:当前有4个Pod → Controller删除1个多余Pod
- 场景3:某个Pod崩溃 → Controller立即创建新Pod替换
这就是Kubernetes的"自愈"能力的核心机制。
2.3 工作节点组件详解
2.3.1 Kubelet:节点的管家
作用:运行在每个工作节点上的代理,负责管理Pod的生命周期。
核心职责:
- 接收API Server分配的Pod任务
- 通过容器运行时(containerd)创建和管理容器
- 监控Pod和容器的健康状态
- 定期向API Server上报节点和Pod状态
工作流程:
容器 Container Runtime Kubelet API Server 容器 Container Runtime Kubelet API Server 分配Pod到节点 拉取镜像 镜像就绪 创建容器 启动容器 运行中 容器状态 上报Pod状态
健康检查机制:
- Liveness Probe:存活探针,容器是否还活着
- Readiness Probe:就绪探针,容器是否准备好接收流量
- Startup Probe:启动探针,容器是否已启动完成
2.3.2 kube-proxy:网络流量的指挥官
作用:实现Service的负载均衡功能,将流量转发到后端Pod。
工作模式 :
当前主流使用IPVS模式(IP Virtual Server),性能优于传统的iptables模式。
流量转发过程:
客户端请求
Service IP
kube-proxy
IPVS规则
Pod 1
192.168.1.10
Pod 2
192.168.1.11
Pod 3
192.168.1.12
负载均衡算法:
- rr(Round Robin):轮询,默认算法
- lc(Least Connection):最少连接
- wrr(Weighted Round Robin):加权轮询
2.3.3 Container Runtime:容器的执行者
作用:负责容器的实际运行,当前主流使用containerd。
核心功能:
- 镜像管理:拉取、存储、删除镜像
- 容器生命周期:创建、启动、停止、删除容器
- 网络命名空间管理
- 存储卷挂载
从Docker到containerd的演进:
- Kubernetes v1.20之前:Docker作为容器运行时
- Kubernetes v1.20+:弃用Docker,推荐containerd
- 原因:containerd更轻量,直接实现CRI接口,减少调用链路
2.4 组件协作:创建Pod的完整流程
让我们通过一个实际例子,看看各组件如何协作:
containerd Kubelet Controller Scheduler etcd API Server kubectl containerd Kubelet Controller Scheduler etcd API Server kubectl kubectl create deployment 保存Deployment Watch到新Deployment 创建ReplicaSet 创建Pod Watch到Pending Pod 绑定Pod到节点 Watch到分配的Pod 创建容器 容器运行中 上报Pod状态为Running
时间线:
- 0秒 :用户执行
kubectl create deployment nginx --image=nginx --replicas=3 - 0.1秒:API Server验证并保存到etcd
- 0.2秒:Deployment Controller创建ReplicaSet
- 0.3秒:ReplicaSet Controller创建3个Pod
- 0.5秒:Scheduler为Pod选择节点
- 1秒:Kubelet拉取镜像(如果本地没有)
- 5秒:容器启动完成,Pod状态变为Running
整个过程自动化完成,无需人工干预。
三、网络模型深度解析
3.1 Kubernetes网络三大原则
Kubernetes的网络模型基于三个基本要求:
- 所有Pod可以直接通信:Pod之间无需NAT即可互相访问
- 节点与Pod可以直接通信:节点可以直接访问任何Pod
- Pod看到的IP就是其他Pod看到的IP:没有地址转换
这种"扁平化"网络模型大大简化了应用开发,开发者无需关心网络细节。
3.2 Pod网络:容器间的高速公路
3.2.1 Pod网络架构
每个Pod都有自己的IP地址,Pod内的容器共享网络命名空间。
节点 192.168.1.11
节点 192.168.1.10
VXLAN隧道
Pod 3 (10.244.2.7)
容器D
Pod 2 (10.244.1.6)
容器C
localhost:8080
Pod 1 (10.244.1.5)
共享网络
容器A
localhost:8080
容器B
localhost:9090
网桥 cni0
Pod1
Pod2
网桥 cni0
Pod3
关键特性:
- 同Pod内容器:通过localhost通信,性能最高
- 同节点Pod:通过网桥直接通信
- 跨节点Pod:通过CNI插件(如Calico、Flannel)实现
3.2.2 CNI插件:网络的魔法师
常见CNI插件对比:
| 插件 | 网络模式 | 性能 | 适用场景 |
|---|---|---|---|
| Calico | BGP/VXLAN | 高 | 生产环境,支持网络策略 |
| Flannel | VXLAN/Host-GW | 中 | 简单场景,易于部署 |
| Cilium | eBPF | 极高 | 高性能要求,需要新内核 |
| Weave | VXLAN | 中 | 快速部署,自动加密 |
VXLAN封装原理(以Calico为例):
原始数据包
Src: 10.244.1.5
Dst: 10.244.2.7
VXLAN封装
外层IP头
Src: 192.168.1.10
Dst: 192.168.1.11
物理网络传输
VXLAN解封装
目标Pod接收
为什么使用VXLAN:
- 云环境(阿里云、腾讯云)不支持IPIP协议
- VXLAN使用UDP封装,所有云厂商都支持
- 性能损耗小于5%,兼容性好
3.3 Service:稳定的服务入口
3.3.1 为什么需要Service
Pod的IP地址是不稳定的:
- Pod重启后IP会变化
- 扩缩容时Pod数量变化
- 节点故障时Pod会迁移
Service提供了一个稳定的虚拟IP(ClusterIP),作为一组Pod的统一入口。
客户端
Service
ClusterIP: 10.96.100.50
Pod 1
10.244.1.5
Pod 2
10.244.1.6
Pod 3
10.244.2.7
3.3.2 Service类型详解
1. ClusterIP(默认类型)
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80 # Service端口
targetPort: 80 # Pod端口
特点:只能在集群内部访问,适合内部服务通信。
2. NodePort
yaml
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 节点端口(30000-32767)
特点:在所有节点上开放相同端口,可以通过<节点IP>:30080从外部访问。
3. LoadBalancer
yaml
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
特点:云厂商提供的外部负载均衡器,自动分配公网IP。
3.3.3 kube-proxy的IPVS魔法
kube-proxy通过IPVS实现Service的负载均衡:
bash
# 查看IPVS规则
ipvsadm -Ln
# 输出示例:
TCP 10.96.100.50:80 rr
-> 10.244.1.5:80 Masq 1 0 0
-> 10.244.1.6:80 Masq 1 0 0
-> 10.244.2.7:80 Masq 1 0 0
流量转发过程:
- 客户端请求Service IP(10.96.100.50:80)
- IPVS根据负载均衡算法选择一个Pod
- 进行DNAT转换,将目标IP改为Pod IP
- 数据包通过Pod网络到达目标容器
3.4 Ingress:集群的统一入口
3.4.1 Ingress vs Service
Service的局限性:
- NodePort需要记忆非标准端口(30000-32767)
- 每个服务占用一个端口,端口资源有限
- 无法实现基于域名和路径的路由
Ingress的优势:
- 使用标准HTTP/HTTPS端口(80/443)
- 支持域名和路径路由
- 统一的TLS证书管理
- 一个Ingress可以管理多个服务
3.4.2 Ingress工作原理
example.com/api
example.com/web
admin.example.com
互联网
Ingress Controller
Nginx
API Service
Web Service
Admin Service
API Pods
Web Pods
Admin Pods
Ingress配置示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
tls:
- hosts:
- example.com
secretName: example-tls
流量路径:
用户请求 https://example.com/api/users
↓
Ingress Controller(Nginx)
↓ 域名匹配:example.com
↓ 路径匹配:/api
↓
转发到 api-service:8080
↓
kube-proxy负载均衡
↓
选择一个API Pod
四、存储与数据持久化
4.1 存储类型概览
Kubernetes提供了多种存储类型,适用于不同场景:
| 存储类型 | 生命周期 | 数据持久化 | 使用场景 |
|---|---|---|---|
| emptyDir | 与Pod相同 | ❌ Pod删除即清空 | 临时数据、缓存 |
| hostPath | 与节点相同 | ✅ 节点级持久化 | 日志收集、监控数据 |
| PV/PVC | 独立于Pod | ✅ 持久化存储 | 数据库、文件存储 |
| ConfigMap | 独立于Pod | ✅ 配置数据 | 应用配置文件 |
| Secret | 独立于Pod | ✅ 敏感数据 | 密码、证书、密钥 |
4.2 PV和PVC:存储的供需关系
4.2.1 核心概念
PersistentVolume (PV) :集群中的存储资源,由管理员创建或动态供应。
PersistentVolumeClaim (PVC):用户的存储请求,类似于Pod请求计算资源。
有
无
用户创建PVC
需要10GB存储
PVC Controller
是否有匹配的PV?
绑定现有PV
动态创建PV
Provisioner
PVC绑定到新PV
Pod挂载PVC
4.2.2 实际案例:MySQL数据持久化
步骤1:创建PVC
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
storageClassName: nfs-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
步骤2:Pod使用PVC
yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
数据流转:
MySQL容器写入数据
↓
/var/lib/mysql (容器内路径)
↓
PVC (mysql-pvc)
↓
PV (动态创建)
↓
NFS服务器 (192.168.1.100:/data/mysql)
4.3 存储选型建议
数据库应用:
- 推荐:云盘(高性能)或Ceph RBD
- 访问模式:ReadWriteOnce(单节点读写)
- 原因:数据库需要高IOPS,独占访问避免数据冲突
文件共享:
- 推荐:NFS或CephFS
- 访问模式:ReadWriteMany(多节点读写)
- 原因:多个Pod需要同时访问相同文件
日志收集:
- 推荐:hostPath + DaemonSet采集器
- 原因:日志写入本地性能最好,通过采集器统一收集
五、生产环境最佳实践
5.1 监控体系:集群的健康管家
5.1.1 Prometheus + Grafana架构
可视化层
存储查询层
数据采集层
Node Exporter
节点指标
kube-state-metrics
K8s资源状态
cAdvisor
容器指标
Prometheus
时序数据库
Grafana
仪表盘
核心监控指标:
| 指标类型 | 关键指标 | 告警阈值 |
|---|---|---|
| 节点 | CPU使用率、内存使用率、磁盘使用率 | >80% |
| Pod | 重启次数、状态异常、资源使用 | 重启>3次/15分钟 |
| 容器 | CPU限流、内存OOM | 持续限流>5分钟 |
| API Server | 请求延迟、错误率 | P99延迟>1秒 |
5.1.2 告警规则示例
yaml
# 节点CPU使用率过高
- alert: NodeCPUHigh
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
annotations:
summary: "节点CPU使用率过高"
description: "节点 {{ $labels.instance }} CPU使用率为 {{ $value }}%"
# Pod频繁重启
- alert: PodRestartFrequent
expr: rate(kube_pod_container_status_restarts_total[15m]) > 0.1
for: 5m
annotations:
summary: "Pod重启频繁"
description: "Pod {{ $labels.namespace }}/{{ $labels.pod }} 在15分钟内重启了多次"
5.2 高可用部署策略
5.2.1 应用层高可用
多副本部署:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3 # 至少3个副本
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多多1个Pod
maxUnavailable: 0 # 最多0个Pod不可用(零停机)
Pod反亲和性:确保Pod分散在不同节点
yaml
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web-app
topologyKey: kubernetes.io/hostname
健康检查:
yaml
spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5.2.2 资源配额管理
设置资源请求和限制:
yaml
resources:
requests:
cpu: 100m # 最少需要0.1核
memory: 128Mi # 最少需要128MB
limits:
cpu: 500m # 最多使用0.5核
memory: 512Mi # 最多使用512MB
为什么重要:
- requests:调度器根据此值选择节点,保证资源可用
- limits:防止单个容器占用过多资源,影响其他容器
5.3 常见问题排查
5.3.1 Pod一直处于Pending状态
可能原因:
-
资源不足:节点CPU/内存不够
bashkubectl describe pod <pod-name> # 查看Events: FailedScheduling: Insufficient cpu -
PVC未绑定:存储卷未就绪
bashkubectl get pvc # 查看STATUS是否为Bound -
镜像拉取失败:镜像不存在或无权限
bashkubectl describe pod <pod-name> # 查看Events: Failed to pull image
5.3.2 Pod频繁重启
排查步骤:
bash
# 1. 查看Pod日志
kubectl logs <pod-name> --previous
# 2. 查看Pod事件
kubectl describe pod <pod-name>
# 3. 检查资源限制
kubectl top pod <pod-name>
常见原因:
- 应用崩溃(查看日志)
- 内存OOM(超过limits)
- 健康检查失败(调整探针参数)
5.3.3 Service无法访问
排查清单:
bash
# 1. 检查Service是否存在
kubectl get svc <service-name>
# 2. 检查Endpoints是否正常
kubectl get endpoints <service-name>
# 3. 检查Pod标签是否匹配
kubectl get pods --show-labels
# 4. 测试Pod直接访问
kubectl run test --image=busybox --rm -it -- wget -O- http://<pod-ip>
# 5. 测试Service访问
kubectl run test --image=busybox --rm -it -- wget -O- http://<service-name>
六、总结
6.1 核心要点回顾
通过本文,我们深入探讨了Kubernetes的核心架构和生产实践:
架构层面:
- 控制平面:API Server是中心枢纽,etcd是数据库,Scheduler负责调度,Controller Manager维护期望状态
- 工作节点:Kubelet管理Pod生命周期,kube-proxy实现服务负载均衡,Container Runtime运行容器
网络层面:
- Pod网络:通过CNI插件(如Calico)实现跨节点通信,VXLAN封装解决云环境兼容性
- Service抽象:提供稳定的虚拟IP,通过IPVS实现高性能负载均衡
- Ingress入口:统一的HTTP/HTTPS入口,支持域名和路径路由
存储层面:
- PV/PVC机制:存储资源的供需关系,支持动态供应
- 存储选型:根据应用特性选择合适的存储类型(云盘、NFS、Ceph等)
运维层面:
- 监控体系:Prometheus采集指标,Grafana可视化展示
- 高可用部署:多副本、反亲和性、健康检查、资源配额
- 问题排查:系统化的排查思路和工具使用
6.2 Kubernetes的价值
Kubernetes不仅仅是一个容器编排工具,更是一种声明式基础设施的理念:
从命令式到声明式:
- 传统运维:告诉系统"怎么做"(执行一系列命令)
- Kubernetes:告诉系统"要什么"(声明期望状态)
从手动到自动:
- 自动调度、自动扩缩容、自动故障恢复
- 运维人员从"救火队员"变成"架构师"
从单体到微服务:
- 支持大规模微服务部署和管理
- 服务发现、负载均衡、配置管理一应俱全
6.3 技术演进趋势
1. Service Mesh(服务网格)
- 代表:Istio、Linkerd
- 价值:流量管理、安全通信、可观测性
- 适用:大规模微服务架构
2. Serverless on Kubernetes
- 代表:Knative、OpenFaaS
- 价值:按需计算、自动扩缩容到零
- 适用:事件驱动应用
3. GitOps
- 代表:ArgoCD、Flux
- 价值:基础设施即代码,Git作为唯一真实来源
- 适用:持续部署、多环境管理
4. eBPF网络
- 代表:Cilium
- 价值:极致性能、内核级可观测性
- 适用:高性能要求场景
6.4 学习建议
入门阶段:
- 搭建本地集群(Minikube或Kind)
- 掌握基本概念(Pod、Service、Deployment)
- 熟悉kubectl命令