1. Kubernetes 都能做什么
初学 Kubernetes 时,最先要理解的不是各种资源名,而是 Kubernetes 能帮我们解决哪些实际问题。
一句话概括:
text
Kubernetes 可以把一组服务器变成一个统一的应用运行平台,自动完成应用部署、调度、恢复、扩缩容、发布、访问、配置和资源治理。
1.1 自动部署应用
你只需要告诉 Kubernetes:
- 使用哪个镜像
- 启动几个副本
- 暴露哪个端口
- 需要哪些配置
Kubernetes 会自动选择合适的节点,把应用运行起来。
例如:
text
我要运行 3 个 nginx:1.25 副本。
Kubernetes 会负责创建 3 个 Pod,并让它们分布在集群节点上。
1.2 自动恢复故障
如果某个应用容器崩溃,Kubernetes 可以自动重启它。
如果某个 Pod 被删除,Deployment 可以自动创建新的 Pod。
如果某台节点宕机,Kubernetes 可以把受影响的 Pod 调度到其他可用节点。
这就是常说的自愈能力。
1.3 管理多个应用副本
生产环境中,一个服务通常不会只运行一个实例。
Kubernetes 可以帮你管理多个副本,例如:
text
前端服务运行 3 个副本。
订单服务运行 5 个副本。
支付服务运行 2 个副本。
当副本数量不符合预期时,Kubernetes 会自动调整。
1.4 应用扩容和缩容
当访问量变大时,可以增加副本数。当访问量变小时,可以减少副本数。
手动扩容示例:
bash
kubectl scale deployment web --replicas=5
Kubernetes 也支持基于 CPU、内存或自定义指标的自动扩缩容。
1.5 服务发现和负载均衡
Pod 的 IP 会变化,不能直接依赖 Pod IP 访问应用。
Kubernetes 通过 Service 给一组 Pod 提供稳定访问入口。
例如:
text
订单服务不需要知道用户服务后面有几个 Pod。
订单服务只需要访问 user-service。
Service 会把请求转发给后端健康的 Pod。
1.6 滚动发布和版本回滚
Kubernetes 可以在不中断服务的情况下逐步发布新版本。
例如从:
text
web:v1
升级到:
text
web:v2
Kubernetes 会逐步创建新版本 Pod,同时逐步减少旧版本 Pod。
如果新版本有问题,可以执行回滚:
bash
kubectl rollout undo deployment/web
1.7 配置和密钥管理
不同环境通常有不同配置:
text
dev 使用开发数据库。
test 使用测试数据库。
prod 使用生产数据库。
Kubernetes 可以通过 ConfigMap 管理普通配置,通过 Secret 管理敏感信息。
这样镜像可以保持一致,环境差异通过配置注入。
1.8 挂载存储
有些应用需要保存数据,例如:
- 数据库
- 文件上传服务
- 日志归档服务
Kubernetes 可以通过 Volume、PVC、PV、StorageClass 管理存储。
这样 Pod 重建后,数据仍然可以保留下来。
1.9 资源限制和调度
Kubernetes 可以限制每个应用使用多少 CPU 和内存。
它还能根据节点资源情况,把 Pod 调度到合适的机器上。
例如:
- 普通 Web 服务调度到普通节点
- GPU 任务调度到 GPU 节点
- 高优先级服务优先获得资源
1.10 权限控制和安全治理
Kubernetes 支持 RBAC 权限控制。
可以做到:
- 开发人员只能查看自己的 Namespace
- CI/CD 系统只能发布指定应用
- 应用只能读取自己需要的 Secret
- 普通用户不能删除集群节点
这对生产环境非常重要。
1.11 监控、日志和故障排查
Kubernetes 本身会记录资源状态和事件。
配合 Prometheus、Grafana、Loki、ELK 等工具,可以实现:
- 查看 CPU 和内存使用率
- 查看 Pod 重启次数
- 查看应用日志
- 配置告警
- 排查发布失败、镜像拉取失败、服务不可访问等问题
1.12 扩展 Kubernetes 能力
Kubernetes 不只可以管理内置资源,也可以通过 CRD 和 Operator 扩展。
例如:
- Prometheus Operator 管理监控系统
- Argo CD 管理 GitOps 发布
- Istio 管理服务网格
- Cert Manager 管理证书
这也是 Kubernetes 成为云原生基础平台的重要原因。
1.13 Kubernetes 不适合做什么
Kubernetes 能力很强,但不是所有场景都适合使用。
不太适合:
- 只有一个很小的应用,没有多副本和自动化需求
- 团队还没有容器化基础
- 没有人维护集群
- 应用强依赖单机本地状态
- 为了学习而直接把复杂生产系统迁入 Kubernetes
初学者应先从简单应用开始:
text
容器镜像 -> Deployment -> Service -> ConfigMap -> Probe -> Ingress -> PVC -> RBAC -> 监控发布
2. 本章学习目标
这一章面向 Kubernetes 初学者,目标不是一次性记住所有术语,而是先建立一套清晰的理解框架。
学完本章后,你应该能回答这些问题:
- Kubernetes 到底是做什么的
- 为什么有了 Docker 还需要 Kubernetes
- 一个应用从提交 YAML 到运行起来,中间发生了什么
- Pod、Deployment、Service 分别解决什么问题
- kubectl 常用命令应该怎么看、怎么用
- 如何部署一个最简单的 Nginx 应用
3. 先理解容器与 Kubernetes 的关系
3.1 Docker 解决了什么问题
在没有容器之前,部署应用经常遇到这些问题:
- 开发环境能跑,测试环境不能跑
- Java、Node、Python、Nginx 等依赖版本不一致
- 部署步骤靠人工记录,容易漏步骤
- 一台机器上部署多个应用,依赖互相影响
Docker 的核心价值是把应用和依赖打包成镜像,然后用容器运行。
可以把镜像理解成一个应用的安装包,把容器理解成这个安装包启动后的运行进程。
例如:
bash
docker run -d -p 8080:80 nginx
这条命令的意思是:启动一个 Nginx 容器,并把本机 8080 端口转发到容器的 80 端口。
3.2 Docker 没有完整解决的问题
如果只有一台机器、几个容器,Docker 已经够用。但生产环境通常不是这样。
生产环境会遇到:
- 有很多台服务器
- 有很多个应用
- 每个应用有多个副本
- 某些容器会异常退出
- 某些机器会宕机
- 发布应用时不能停机
- 流量需要自动分发到多个副本
- 配置、密钥、存储、权限都需要统一管理
这些问题靠人工维护会非常复杂。
Kubernetes 就是为了解决这些多机器、多应用、多副本的自动化管理问题。
3.3 Kubernetes 的核心作用
Kubernetes 是一个容器编排平台。
"编排"可以理解为:你告诉 Kubernetes 你想要什么结果,Kubernetes 负责把集群调整到这个结果。
例如你告诉 Kubernetes:
text
我要运行 3 个 Nginx 副本。
Kubernetes 会负责:
- 找合适的机器运行它们
- 拉取镜像
- 启动容器
- 检查容器是否健康
- 某个副本挂了就重新创建
- 某台机器挂了就迁移到其他机器
这就是 Kubernetes 最重要的思想:声明式管理。
4. 声明式管理:初学者必须理解的核心思想
4.1 命令式与声明式
命令式是告诉系统"怎么做"。
例如:
text
先登录服务器 A。
再下载镜像。
再启动容器。
再检查端口。
如果失败再重启。
声明式是告诉系统"我要什么结果"。
例如:
yaml
replicas: 3
image: nginx:1.25
意思是:我要 3 个 nginx:1.25 副本。
Kubernetes 会不断检查实际状态和期望状态是否一致。如果不一致,就自动修正。
4.2 期望状态与实际状态
Kubernetes 中经常出现两个概念:
- 期望状态:你写在 YAML 里的状态
- 实际状态:集群当前真实运行的状态
举例:
text
期望状态:Deployment 需要 3 个 Pod
实际状态:当前只有 2 个 Pod 正常运行
Kubernetes 发现少了一个,就会自动创建新的 Pod。
这就是 Kubernetes 的自愈能力。
5. Kubernetes 集群架构
5.1 集群是什么
Kubernetes 集群可以理解为一组服务器,这些服务器共同运行应用。
集群中通常有两类节点:
- Control Plane:控制平面,负责管理和决策
- Worker Node:工作节点,负责运行真正的业务应用
可以用一个简单类比理解:
text
Control Plane 像调度中心。
Worker Node 像真正干活的服务器。
你通过 kubectl 提交命令,先到控制平面,然后控制平面安排工作节点运行 Pod。
5.2 Control Plane 组件
API Server
API Server 是 Kubernetes 的入口。
你执行的每条 kubectl 命令,基本都会先请求 API Server。
例如:
bash
kubectl get pods
这条命令不是直接去每台机器上查 Pod,而是向 API Server 查询集群状态。
API Server 负责:
- 接收请求
- 校验 YAML 是否合法
- 做认证和授权
- 把数据保存到 etcd
- 把结果返回给客户端
etcd
etcd 是 Kubernetes 的数据库。
它保存集群里所有重要信息:
- 有哪些节点
- 有哪些 Pod
- 有哪些 Service
- Deployment 期望几个副本
- ConfigMap 和 Secret 内容
- RBAC 权限配置
初学者可以先记住一句话:
text
etcd 保存 Kubernetes 集群状态,不能随便删除或修改。
Scheduler
Scheduler 是调度器,负责决定 Pod 放在哪个节点运行。
它会考虑:
- 哪个节点 CPU 和内存够
- Pod 有没有指定节点
- 节点有没有污点
- Pod 是否能容忍污点
- 是否有亲和性规则
初学阶段可以简单理解为:
text
Scheduler 负责给新 Pod 选机器。
Controller Manager
Controller Manager 是控制器管理器,负责不断检查实际状态是否符合期望状态。
例如:
- Deployment 要 3 个副本,但只剩 2 个,它会补 1 个
- Job 没执行完,它会继续创建任务 Pod
- 节点异常,它会触发相关处理
初学阶段可以记住:
text
Controller Manager 负责自动纠偏。
5.3 Worker Node 组件
Kubelet
Kubelet 运行在每个工作节点上,负责管理本机 Pod。
它的工作包括:
- 接收控制平面下发的 Pod 信息
- 调用容器运行时启动容器
- 上报 Pod 状态
- 执行健康检查
- 挂载存储卷
初学阶段可以理解为:
text
Kubelet 是每台机器上的 Kubernetes 管家。
Container Runtime
Container Runtime 是真正运行容器的组件。
常见运行时:
- containerd
- CRI-O
Kubernetes 不直接运行容器,而是通过容器运行时来运行容器。
Kube Proxy
Kube Proxy 负责 Service 的网络转发。
当你访问一个 Service 时,请求最终要转发到某个 Pod。Kube Proxy 会维护这些转发规则。
初学阶段可以理解为:
text
Kube Proxy 帮 Service 把流量转给后端 Pod。
6. Kubernetes 最核心的资源对象
6.1 Namespace:资源分组
Namespace 用来把资源分组。
例如:
text
dev 开发环境
test 测试环境
prod 生产环境
这样不同环境的 Pod、Service、ConfigMap 可以分开管理。
常用命令:
bash
kubectl get namespaces
kubectl create namespace dev
kubectl get pods -n dev
初学者常见误区:
- Namespace 不是虚拟机
- Namespace 不是强安全边界
- 不同 Namespace 里的服务仍然可能通过网络访问,是否能访问取决于网络策略
6.2 Pod:Kubernetes 最小运行单位
Pod 是 Kubernetes 中最小的调度单位。
一个 Pod 里可以有一个或多个容器。大多数业务场景中,一个 Pod 通常只有一个主容器。
Pod 的特点:
- 有自己的 IP
- 可以挂载 Volume
- 可以配置环境变量
- 可以设置资源限制
- 可以配置健康检查
为什么 Kubernetes 不直接调度容器,而是调度 Pod?
因为有些容器必须紧密协作,例如:
- 主应用容器
- 日志收集 sidecar 容器
- 代理 sidecar 容器
这些容器需要共享网络和存储,所以 Kubernetes 用 Pod 把它们放在一起管理。
常用命令:
bash
kubectl get pods
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl exec -it <pod-name> -- sh
6.3 Deployment:管理无状态应用
实际工作中,一般不会直接创建 Pod,而是创建 Deployment。
原因是 Pod 如果被删除,不会自己恢复。而 Deployment 会保证副本数量始终符合预期。
Deployment 适合:
- Web 服务
- API 服务
- 前端服务
- 无状态微服务
Deployment 能做:
- 创建 Pod
- 维持副本数
- 滚动更新
- 版本回滚
- 故障自愈
例子:
text
你创建一个 replicas=3 的 Deployment。
Kubernetes 会创建 3 个 Pod。
如果某个 Pod 挂了,Deployment 会让控制器再创建一个新的。
6.4 Service:给 Pod 一个稳定入口
Pod 的 IP 不是固定的。
当 Pod 重建后,它的 IP 可能会变化。如果其他服务直接访问 Pod IP,就会很不稳定。
Service 的作用是给一组 Pod 提供稳定访问入口。
Service 通过 label selector 找到后端 Pod。
例如:
yaml
selector:
app: nginx-demo
表示这个 Service 会把流量转发给带有 app=nginx-demo 标签的 Pod。
常见 Service 类型:
- ClusterIP:集群内部访问,默认类型
- NodePort:通过节点端口访问
- LoadBalancer:通过云厂商负载均衡访问
6.5 ConfigMap:保存普通配置
ConfigMap 用来保存非敏感配置。
例如:
- 应用环境:production
- 日志级别:info
- 配置文件内容
- 功能开关
不要把密码放进 ConfigMap。密码应该放到 Secret。
6.6 Secret:保存敏感配置
Secret 用于保存敏感数据。
例如:
- 数据库密码
- Token
- TLS 证书
- 镜像仓库登录信息
注意:Secret 不是绝对安全。它只是比 ConfigMap 更适合保存敏感信息,生产环境还需要配合 RBAC、etcd 加密和外部密钥系统。
7. kubectl 入门命令
7.1 查看资源
bash
kubectl get nodes
kubectl get pods
kubectl get pods -A
kubectl get deployments
kubectl get svc
7.2 查看详细信息
bash
kubectl describe pod <pod-name>
kubectl describe deployment <deployment-name>
kubectl describe svc <service-name>
describe 很适合排查问题,因为它会显示事件、状态、镜像、调度信息和错误原因。
7.3 查看日志
bash
kubectl logs <pod-name>
kubectl logs <pod-name> --previous
--previous 用于查看上一个已经崩溃的容器日志,排查 CrashLoopBackOff 时很常用。
7.4 进入容器
bash
kubectl exec -it <pod-name> -- sh
如果镜像里有 bash,也可以用:
bash
kubectl exec -it <pod-name> -- bash
7.5 应用和删除 YAML
bash
kubectl apply -f app.yaml
kubectl delete -f app.yaml
apply 的意思是把 YAML 中描述的期望状态提交给 Kubernetes。
8. 运用实例:部署第一个 Nginx 应用
8.1 创建 Deployment
文件名:nginx-deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
重点解释:
apiVersion:资源使用的 API 版本kind:资源类型,这里是 Deploymentmetadata.name:资源名称replicas:期望运行 2 个副本selector.matchLabels:Deployment 用它找到自己管理的 Podtemplate:Pod 模板,Kubernetes 会根据它创建 Podimage:容器镜像containerPort:容器内部监听端口
执行:
bash
kubectl apply -f nginx-deployment.yaml
kubectl get pods
kubectl get deployment nginx-demo
8.2 创建 Service
文件名:nginx-service.yaml
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-demo-svc
spec:
selector:
app: nginx-demo
ports:
- port: 80
targetPort: 80
type: ClusterIP
重点解释:
selector.app=nginx-demo:找到带有这个标签的 Podport:Service 暴露的端口targetPort:Pod 容器里的端口ClusterIP:只能在集群内部访问
执行:
bash
kubectl apply -f nginx-service.yaml
kubectl get svc
8.3 本地访问验证
bash
kubectl port-forward svc/nginx-demo-svc 8080:80
然后访问:
text
http://localhost:8080
这条命令的意思是:把本机 8080 端口临时转发到集群里的 nginx-demo-svc:80。
8.4 扩容应用
bash
kubectl scale deployment nginx-demo --replicas=5
kubectl get pods
这表示把 Nginx 副本数从 2 个调整为 5 个。
8.5 更新镜像
bash
kubectl set image deployment/nginx-demo nginx=nginx:1.26
kubectl rollout status deployment/nginx-demo
Kubernetes 会逐步创建新版本 Pod,并删除旧版本 Pod。
8.6 回滚版本
bash
kubectl rollout history deployment/nginx-demo
kubectl rollout undo deployment/nginx-demo
如果新版本有问题,可以回滚到上一个版本。
9. 初学者常见问题
9.1 Pod 和容器是什么关系
容器运行在 Pod 里面,Pod 是 Kubernetes 调度和管理的单位。
可以简单理解:
text
Pod 是房间,容器是房间里运行的应用进程。
9.2 Deployment 和 Pod 是什么关系
Deployment 负责管理 Pod。
一般不要直接创建裸 Pod,因为裸 Pod 删除后不会自动恢复。
9.3 Service 为什么必须要有
因为 Pod IP 会变。Service 提供稳定的访问地址,并把流量转发给后端 Pod。
9.4 label 为什么重要
Kubernetes 很多资源都是通过 label 关联的。
例如 Service 找 Pod、Deployment 管 Pod,都是依赖 label。
如果 label 写错,Service 可能找不到 Pod。
9.5 YAML 改了以后为什么要 apply
YAML 只是本地文件。只有执行 kubectl apply -f xxx.yaml,Kubernetes 才会收到新的期望状态。
10. 本章小结
初学 Kubernetes 时,先记住这条主线:
text
写 YAML -> kubectl apply -> API Server 接收 -> 控制器调整状态 -> Scheduler 选择节点 -> Kubelet 启动 Pod -> Service 暴露访问
最核心的几个对象:
- Pod:运行容器
- Deployment:管理 Pod 副本和发布
- Service:提供稳定访问入口
- ConfigMap:保存普通配置
- Secret:保存敏感配置
- Namespace:资源分组
11. 初学者实践与验证
这一节建议在 Minikube、Kind、Docker Desktop Kubernetes 或测试集群中操作。不要直接在生产集群练习删除、扩容、回滚等命令。
11.1 实践一:确认集群是否可用
实践目的:
- 确认 kubectl 能连接 Kubernetes 集群
- 学会查看节点、命名空间和系统 Pod
操作步骤:
bash
kubectl cluster-info
kubectl get nodes
kubectl get namespaces
kubectl get pods -A
验证方法:
bash
kubectl get nodes
预期结果:
- 至少能看到 1 个 Node
- Node 状态应该是 Ready
如果失败,按下面顺序排查:
bash
kubectl config current-context
kubectl config get-contexts
kubectl cluster-info
常见原因:
- kubeconfig 没配置
- 当前 context 指向了错误集群
- 本地 Kubernetes 没启动
- 网络无法访问 API Server
11.2 实践二:创建 Namespace 并观察资源隔离
实践目的:
- 理解 Namespace 是资源分组
- 学会在指定 Namespace 中创建和查看资源
操作步骤:
bash
kubectl create namespace k8s-beginner
kubectl get namespaces
kubectl get pods -n k8s-beginner
验证方法:
bash
kubectl get namespace k8s-beginner
预期结果:
text
k8s-beginner Active
进一步理解:
bash
kubectl get pods
kubectl get pods -n k8s-beginner
kubectl get pods -A
这三个命令的区别:
kubectl get pods:查看当前默认 Namespace 的 Podkubectl get pods -n k8s-beginner:查看指定 Namespacekubectl get pods -A:查看所有 Namespace
清理命令:
bash
kubectl delete namespace k8s-beginner
11.3 实践三:用 Deployment 部署 Nginx
实践目的:
- 理解 Deployment 如何创建和管理 Pod
- 学会用 YAML 描述应用
- 学会验证 Pod 是否运行成功
操作步骤:
创建 nginx-deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
应用配置:
bash
kubectl apply -f nginx-deployment.yaml
验证方法:
bash
kubectl get deployment nginx-demo
kubectl get pods -l app=nginx-demo
kubectl describe deployment nginx-demo
预期结果:
- Deployment 的 READY 应该接近
2/2 - 应该看到 2 个 Pod
- Pod 状态应该是 Running
如果 Pod 没有 Running,排查:
bash
kubectl describe pod <pod-name>
kubectl logs <pod-name>
重点看:
- Events 中是否有镜像拉取失败
- Pod 是否因为资源不足无法调度
- 容器是否启动后立即退出
11.4 实践四:扩容和缩容 Deployment
实践目的:
- 理解 Kubernetes 如何维持期望副本数
- 观察 Deployment 自动创建和删除 Pod
操作步骤:
bash
kubectl scale deployment nginx-demo --replicas=4
kubectl get pods -l app=nginx-demo
验证方法:
bash
kubectl get deployment nginx-demo
预期结果:
- READY 最终变成
4/4 - Pod 数量变成 4 个
缩容:
bash
kubectl scale deployment nginx-demo --replicas=1
kubectl get pods -l app=nginx-demo
预期结果:
- READY 最终变成
1/1 - Kubernetes 自动删除多余 Pod
11.5 实践五:删除 Pod 并观察自愈
实践目的:
- 理解 Deployment 的自愈能力
- 理解为什么不要直接管理裸 Pod
操作步骤:
bash
kubectl get pods -l app=nginx-demo
kubectl delete pod <pod-name>
kubectl get pods -l app=nginx-demo -w
验证方法:
- 被删除的 Pod 会消失
- 新的 Pod 会自动创建
- Deployment 的副本数最终恢复到期望值
理解重点:
text
你删除的是 Pod。
Deployment 发现实际 Pod 数少了。
Controller 又创建了一个新的 Pod。
退出观察:
bash
Ctrl + C
11.6 实践六:创建 Service 并访问应用
实践目的:
- 理解 Service 为 Pod 提供稳定入口
- 学会通过 port-forward 访问集群内服务
创建 nginx-service.yaml:
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-demo-svc
spec:
selector:
app: nginx-demo
ports:
- port: 80
targetPort: 80
type: ClusterIP
应用配置:
bash
kubectl apply -f nginx-service.yaml
验证 Service:
bash
kubectl get svc nginx-demo-svc
kubectl get endpoints nginx-demo-svc
预期结果:
- Service 存在
- endpoints 中能看到 Pod IP
本地访问:
bash
kubectl port-forward svc/nginx-demo-svc 8080:80
浏览器访问:
text
http://localhost:8080
预期结果:
- 能看到 Nginx 欢迎页
如果访问失败,排查:
bash
kubectl get pods -l app=nginx-demo
kubectl get endpoints nginx-demo-svc
kubectl describe svc nginx-demo-svc
重点看:
- Pod 是否 Running
- Service selector 是否和 Pod label 一致
- targetPort 是否是容器真实监听端口
11.7 本章练习验收标准
完成本章后,你应该能独立完成:
- 查看当前集群和节点状态
- 创建和删除 Namespace
- 使用 YAML 创建 Deployment
- 扩容和缩容 Deployment
- 删除 Pod 并观察自动恢复
- 创建 Service 并通过 port-forward 访问应用
- 使用 describe 和 logs 做基础排查
12. 专家级补充:架构深度与核心机制
12.1 kube-proxy 的两种工作模式
kube-proxy 负责维护 Service 的网络转发规则,有两种主要模式:
iptables 模式(默认)
text
请求 -> iptables DNAT 规则 -> 随机选一个后端 Pod IP -> 转发
- 规则数量随 Service 数量线性增长
- 大规模集群(数千 Service)iptables 规则更新慢
- 每次更新需要全量刷新规则
IPVS 模式(推荐生产)
text
请求 -> IPVS 虚拟服务 -> 哈希表查找后端 -> 转发
- 基于哈希表,查找 O(1),适合大规模集群
- 支持多种负载均衡算法:rr(轮询)、lc(最少连接)、sh(源地址哈希)
- 规则更新增量化,性能更好
切换方式:修改 kube-proxy ConfigMap:
yaml
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
scheduler: "rr"
验证当前模式:
bash
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
12.2 Init Container:初始化容器
Init Container 在主容器启动前运行,必须执行成功主容器才会启动。
适用场景:
- 等待依赖服务就绪(数据库、消息队列)
- 下载配置文件或证书
- 数据库迁移
- 修改文件权限
yaml
spec:
initContainers:
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c', 'until nc -z mysql-svc 3306; do echo waiting; sleep 2; done']
- name: db-migrate
image: myapp:v2
command: ['sh', '-c', './migrate.sh']
containers:
- name: app
image: myapp:v2
关键特性:
- 多个 Init Container 按顺序执行
- 任一失败,Pod 重启,重新从头执行
- 与主容器共享 Volume,可传递数据
12.3 Deployment 滚动更新策略参数
滚动更新的核心参数控制发布速度和风险:
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多超出期望副本数的数量(可用百分比)
maxUnavailable: 0 # 最多不可用副本数(可用百分比)
参数含义:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| maxSurge: 1 | 发布时最多额外创建1个新Pod | 保证快速上线 |
| maxUnavailable: 0 | 不允许任何Pod不可用 | 保证服务不中断 |
典型场景:
- 追求零中断:
maxSurge=1, maxUnavailable=0(先起新Pod再删旧Pod) - 追求快速发布:
maxSurge=25%, maxUnavailable=25%(并行替换) - 资源紧张环境:
maxSurge=0, maxUnavailable=1(先删再建,节省资源)
12.4 API Server 认证与授权体系
请求进入 API Server 经过三个阶段:
text
Authentication(认证)-> Authorization(授权)-> Admission Control(准入控制)
认证方式
| 方式 | 适用对象 | 说明 |
|---|---|---|
| ServiceAccount Token | Pod 内应用 | 自动挂载,访问 API Server |
| kubeconfig / x509 证书 | kubectl 用户 | 集群管理员常用 |
| OIDC | 企业用户 | 对接 SSO/Dex/Keycloak |
| Bootstrap Token | 节点加入集群 | kubeadm join 使用 |
授权方式
生产集群通常使用 RBAC,也可组合:
text
--authorization-mode=Node,RBAC
Node:限制 kubelet 只能访问自己节点的资源RBAC:基于角色的访问控制
Admission Controller 准入控制
资源通过认证授权后,准入控制器可以修改或拒绝请求:
text
常用准入控制器:
- NamespaceLifecycle:防止在删除中的Namespace创建资源
- ResourceQuota:检查资源配额
- LimitRanger:注入默认资源限制
- MutatingAdmissionWebhook:调用外部Webhook修改资源(如注入sidecar)
- ValidatingAdmissionWebhook:调用外部Webhook校验资源
12.5 etcd 高可用与备份恢复
etcd 是整个集群的数据库,生产环境必须高可用和定期备份。
高可用部署
etcd 集群通常部署奇数节点(3或5个),使用 Raft 一致性协议:
text
3节点 etcd: 最多容忍 1 节点故障
5节点 etcd: 最多容忍 2 节点故障
备份 etcd 数据
bash
# 备份
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# 验证备份
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-xxx.db --write-out=table
恢复 etcd 数据
bash
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-xxx.db \
--data-dir=/var/lib/etcd-restore \
--initial-cluster=master=https://127.0.0.1:2380 \
--initial-advertise-peer-urls=https://127.0.0.1:2380 \
--name=master
生产建议:定时 CronJob 每天备份,并上传到对象存储(OSS/S3)。