开篇:生产实践、可观测性与扩展能做什么
前两个文档解决的是"应用如何跑起来、如何访问、如何配置、如何保存数据"。
这个文档要解决的是更接近真实生产环境的问题:
text
应用跑起来之后,如何稳定、安全、可观察、可发布、可回滚、可治理、可扩展。
Kubernetes 不只是一个应用运行工具。在生产环境中,它更像一个应用管理平台。
1. 防止应用互相影响
在一个 Kubernetes 集群里,通常会同时运行很多应用。
如果不做资源限制,一个异常应用可能会占满 CPU 或内存,影响同一节点上的其他应用。
例如:
text
某个服务内存泄漏。
它不断占用内存。
节点内存变得紧张。
其他正常 Pod 也可能被驱逐。
Kubernetes 通过这些能力做资源治理:
- requests:声明应用至少需要多少资源
- limits:限制应用最多能使用多少资源
- ResourceQuota:限制一个 Namespace 的资源总量
- LimitRange:给容器设置默认资源范围
2. 控制谁能操作哪些资源
生产集群不能让所有人都有管理员权限。
否则可能出现:
- 误删生产 Pod
- 误删 Namespace
- 查看不该看的 Secret
- 修改系统组件
- CI/CD 系统权限过大
Kubernetes 通过 RBAC 管理权限。
常见控制方式:
- 开发人员只能查看自己的 Namespace
- 运维人员可以管理节点和系统组件
- 应用 ServiceAccount 只能读取自己需要的资源
- CI/CD 账号只能发布指定应用
3. 控制 Pod 应该运行在哪里
默认情况下,Kubernetes 会自动选择节点运行 Pod。
但生产环境经常需要更精细的调度控制。
例如:
- GPU 任务只能运行在 GPU 节点
- 核心服务副本不要都放在同一台机器
- 日志采集 Agent 每台节点都要运行
- 系统组件和业务组件分开部署
Kubernetes 提供:
- nodeSelector
- Node Affinity
- Pod Affinity
- Pod Anti-Affinity
- Taints 和 Tolerations
- PodDisruptionBudget
这些能力用于提高稳定性、隔离性和资源利用率。
4. 发现问题并定位原因
生产环境最怕"服务挂了但不知道为什么"。
Kubernetes 可观测性主要解决:
- 资源是否不足
- Pod 是否频繁重启
- 应用是否异常退出
- Service 是否没有后端
- Ingress 是否转发失败
- DNS 是否解析异常
- 发布是否卡住
常用手段:
kubectl get查看状态kubectl describe查看详情和事件kubectl logs查看应用日志kubectl top查看资源使用- Prometheus 采集指标
- Grafana 展示监控
- Loki 或 ELK 收集日志
5. 降低发布风险
生产发布不是简单地"把新镜像跑起来"。
还需要考虑:
- 新版本是否能正常启动
- 新 Pod 是否 Ready
- 是否影响旧版本流量
- 发布失败后能否快速回滚
- 多环境配置是否一致
- 谁修改了发布配置
Kubernetes 和周边工具可以支持:
- Deployment 滚动发布
- rollout 状态观察
- rollout undo 回滚
- Helm 参数化发布
- Kustomize 管理多环境差异
- Argo CD / Flux 实现 GitOps
6. 支撑平台化扩展
Kubernetes 的强大之处在于可以扩展。
当内置资源不够用时,可以通过 CRD 定义新的资源类型,通过 Controller 或 Operator 自动管理复杂系统。
例如:
- Prometheus Operator 管理监控系统
- Cert Manager 自动申请和续期证书
- Argo CD 管理 GitOps 应用发布
- Istio 管理服务治理和流量控制
初学者不需要一开始就深入源码,但要知道这些扩展能力是 Kubernetes 生态的重要基础。
7. 本文档要解决的主线问题
这一章的学习主线可以概括为:
text
资源治理 -> 调度控制 -> 权限管理 -> 监控日志 -> 发布回滚 -> 故障排查 -> 平台扩展
学完后,你应该能理解一个 Kubernetes 应用从"能跑"走向"能稳定运行"的关键能力。
补充:本章核心能力详细说明
1. 从"能跑"到"能稳定运行"
初学 Kubernetes 时,能把应用部署成功通常只是第一步。
生产环境更关注这些问题:
- 应用会不会占用过多资源
- 应用异常时能不能快速发现
- 发布失败能不能回滚
- 权限是否过大
- 多个副本是否真的高可用
- 配置变更是否可追踪
- 故障发生后能不能定位原因
所以生产实践不是一组高级概念,而是为了降低真实故障风险。
可以这样理解:
text
基础部署解决"能不能跑"。
生产实践解决"能不能长期稳定地跑"。
2. 资源治理为什么重要
Kubernetes 集群通常是多应用共享的。
如果没有资源治理,一个应用可能影响整个节点,甚至影响同一个 Namespace 下的其他应用。
例如:
text
某个应用没有设置 memory limit。
代码出现内存泄漏。
它持续占用节点内存。
节点触发内存压力。
其他 Pod 被驱逐。
多个服务同时异常。
资源治理要解决的问题包括:
- 调度时知道 Pod 至少需要多少资源
- 运行时限制 Pod 最多能用多少资源
- 限制一个 Namespace 的总资源消耗
- 避免没有资源配置的 Pod 随意创建
建议初学者先掌握四个对象:
- requests:调度依据
- limits:运行上限
- ResourceQuota:Namespace 总量限制
- LimitRange:默认资源和单容器范围限制
实践时要重点观察:
bash
kubectl describe pod <pod-name>
kubectl describe quota <quota-name> -n <namespace>
kubectl top pods
kubectl top nodes
3. 调度策略为什么重要
默认调度可以满足大多数简单应用,但生产中经常要控制 Pod 分布。
典型问题:
text
一个服务有 3 个副本。
如果 3 个副本都调度到同一个节点。
这个节点宕机时,服务会整体不可用。
这时就需要 Pod Anti-Affinity 或拓扑分布约束,让副本尽量分散。
再比如:
text
GPU 任务必须运行在 GPU 节点。
普通 Web 服务不应该占用 GPU 节点。
这时可以使用 nodeSelector、Node Affinity、Taints 和 Tolerations。
初学者可以按这个顺序理解:
- nodeSelector:最简单,指定节点标签
- Node Affinity:更灵活的节点选择
- Pod Anti-Affinity:让副本分散
- Taints:节点拒绝普通 Pod
- Tolerations:Pod 声明自己可以接受某种污点
- PDB:节点维护时保护最小可用副本数
验证调度结果时常用:
bash
kubectl get pods -o wide
kubectl describe pod <pod-name>
kubectl describe node <node-name>
4. 权限治理为什么重要
Kubernetes API 能操作的东西很多,包括:
- 创建和删除 Pod
- 查看 Secret
- 修改 Deployment
- 删除 Namespace
- 修改 RBAC
- 操作节点
如果权限没有控制好,误操作和安全风险会很大。
RBAC 的理解顺序:
text
先定义权限,再把权限绑定给某个身份。
对应到资源:
- Role:定义某个 Namespace 内能做什么
- ClusterRole:定义集群级能做什么
- RoleBinding:把 Role 或 ClusterRole 绑定给某个身份
- ClusterRoleBinding:把 ClusterRole 绑定到集群范围
- ServiceAccount:Pod 在集群内访问 API Server 的身份
初学者实践 RBAC 时,不要一开始就写复杂权限。
可以从这个场景开始:
text
创建一个 ServiceAccount。
只允许它查看 Pod 和日志。
不允许它删除 Pod。
验证权限最重要的命令是:
bash
kubectl auth can-i <verb> <resource> --as=<identity> -n <namespace>
5. 可观测性为什么重要
没有可观测性时,故障排查通常只能靠猜。
例如用户反馈服务无法访问,你需要判断:
- Pod 是否还在
- Pod 是否 Ready
- Service 是否有 endpoints
- Ingress 是否转发正确
- 应用日志是否报错
- 节点资源是否不足
- DNS 是否正常
Kubernetes 排查建议从四层开始:
text
状态 -> 事件 -> 日志 -> 指标
对应命令:
bash
kubectl get pods
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl top pod <pod-name>
如果是访问问题,再补充:
bash
kubectl get svc
kubectl get endpoints <service-name>
kubectl get ingress
kubectl describe ingress <ingress-name>
生产中还需要长期工具:
- Prometheus:采集指标
- Grafana:展示图表
- Alertmanager:发送告警
- Loki 或 ELK:集中日志
- OpenTelemetry:链路追踪
6. 发布治理为什么重要
发布是生产环境最常见的风险来源之一。
发布失败可能来自:
- 镜像不存在
- 新版本启动失败
- 配置缺失
- readinessProbe 一直失败
- 资源不足导致 Pod 无法调度
- 新版本接口不兼容
Deployment 提供基础发布能力:
- 滚动发布
- 发布状态观察
- 历史版本记录
- 回滚
常用命令:
bash
kubectl rollout status deployment/<name>
kubectl rollout history deployment/<name>
kubectl rollout undo deployment/<name>
生产发布时建议形成固定流程:
text
发布前检查 -> 发布中观察 -> 发布后验证 -> 异常回滚 -> 复盘原因
不要只看 kubectl apply 是否成功。
apply 成功只表示 Kubernetes 接收了配置,不代表应用成功运行。
7. 扩展能力为什么重要
Kubernetes 内置资源不能覆盖所有场景。
例如 Kubernetes 原生并不知道如何完整管理一个 Prometheus 集群,也不知道如何自动申请 TLS 证书。
这时可以通过 CRD 和 Operator 扩展 Kubernetes。
可以这样理解:
text
CRD 定义一种新的资源。
Controller 监听这种资源。
Operator 把复杂系统的运维经验自动化。
例如:
- 创建 Prometheus 资源,Prometheus Operator 自动部署监控系统
- 创建 Certificate 资源,Cert Manager 自动申请证书
- 创建 Application 资源,Argo CD 自动同步 Git 仓库里的应用配置
初学者不需要马上开发 Operator,但要理解它们为什么存在。
8. 学习本章时的验证习惯
生产实践类知识不能只看 YAML。
每学一个能力,都应该问:
text
它解决什么风险?
如何验证它真的生效?
如果不生效,应该看哪里?
建议固定使用这些验证命令:
bash
kubectl get pods -o wide
kubectl describe pod <pod-name>
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl logs <pod-name>
kubectl auth can-i ...
kubectl rollout status deployment/<name>
kubectl describe quota <quota-name> -n <namespace>
这套命令能覆盖大多数初学阶段的生产问题排查。
1. 本章学习目标
这一章面向已经会部署基础应用的初学者,重点学习 Kubernetes 在真实环境中为什么还需要资源限制、权限控制、调度策略、监控日志和发布治理。
学完本章后,你应该能理解:
- 为什么每个应用都应该配置 requests 和 limits
- Namespace 如何做资源治理
- RBAC 如何控制权限
- Pod 为什么会被调度到不同节点
- 如何观察应用是否健康
- 发布失败后如何定位和回滚
- CRD、Operator、Webhook 大概解决什么问题
2. 资源管理:避免一个应用拖垮整个集群
2.1 为什么要做资源限制
如果不限制资源,一个异常应用可能会占满节点 CPU 或内存,影响同一节点上的其他应用。
例如:
text
某个服务出现内存泄漏。
它不断占用内存。
最终节点内存不足。
其他正常 Pod 也可能被驱逐。
所以生产环境中,每个容器都应该设置资源请求和资源上限。
2.2 Requests 是什么
Requests 表示应用正常运行至少需要多少资源。
Scheduler 会根据 requests 判断哪个节点能放下这个 Pod。
例如:
yaml
requests:
cpu: "100m"
memory: "128Mi"
含义:
- 这个容器希望至少有 0.1 核 CPU
- 这个容器希望至少有 128Mi 内存
2.3 Limits 是什么
Limits 表示容器最多能使用多少资源。
例如:
yaml
limits:
cpu: "500m"
memory: "512Mi"
含义:
- CPU 使用超过 0.5 核会被限制
- 内存超过 512Mi 可能被 OOMKilled
2.4 初学者如何设置 requests 和 limits
刚开始没有历史监控数据时,可以先保守设置:
yaml
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
上线后根据监控调整。
注意:
- requests 太大,会导致 Pod 调度不上
- limits 太小,应用容易被限流或 OOMKilled
- 内存 limit 要尤其谨慎
2.5 ResourceQuota
ResourceQuota 用于限制一个 Namespace 的总资源。
适合:
- 防止某个团队占满集群
- 给 dev、test、prod 分配不同资源池
- 限制 Pod、Service、PVC 数量
示例:
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: prod-quota
namespace: prod
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "50"
2.6 LimitRange
LimitRange 用于给 Namespace 中的容器设置默认资源值。
如果开发人员忘记写 requests 和 limits,LimitRange 可以补默认值。
示例:
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: prod-limit-range
namespace: prod
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
2.7 QoS Class
Kubernetes 会根据资源配置给 Pod 分 QoS 等级。
- Guaranteed:requests 和 limits 都设置,并且相等
- Burstable:设置了部分 requests 或 limits
- BestEffort:完全没设置 requests 和 limits
节点资源紧张时,BestEffort 最容易被驱逐。
3. 调度策略:Pod 为什么跑到这台机器
3.1 默认调度
默认情况下,Scheduler 会根据资源、节点状态和规则选择合适节点。
你不指定调度规则时,Kubernetes 会自动决定 Pod 跑在哪里。
3.2 nodeSelector
nodeSelector 是最简单的节点选择方式。
先给节点打标签:
bash
kubectl label node <node-name> disk=ssd
再让 Pod 选择这个标签:
yaml
nodeSelector:
disk: ssd
适合:
- 指定 SSD 节点
- 指定 GPU 节点
- 指定某类专用节点
3.3 Node Affinity
Node Affinity 比 nodeSelector 更灵活。
它支持:
- 必须满足
- 尽量满足
- 多条件匹配
初学阶段可以先知道:
text
nodeSelector 简单直接,Node Affinity 更灵活。
3.4 Pod Anti-Affinity
Pod Anti-Affinity 用来让多个副本尽量分散。
例如一个 Web 服务有 3 个副本,你不希望它们都跑在同一台机器上。否则这台机器宕机,3 个副本都会消失。
适合:
- 高可用服务
- 多副本应用
- 避免单点故障
3.5 Taints 与 Tolerations
Taint 是节点上的"排斥规则",Toleration 是 Pod 的"容忍声明"。
简单理解:
text
节点说:我有特殊要求,普通 Pod 不要来。
Pod 说:我能接受这个特殊要求。
适合:
- GPU 节点只跑 GPU 任务
- 系统节点只跑系统组件
- 专用节点只跑某类业务
3.6 PodDisruptionBudget
PodDisruptionBudget 简称 PDB,用于限制主动维护时最多能中断多少 Pod。
例如一个服务有 3 个副本,要求至少 2 个可用:
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
这样在节点维护或集群升级时,Kubernetes 会尽量保证至少 2 个副本可用。
4. 安全体系:谁能做什么
4.1 为什么需要 RBAC
在 Kubernetes 中,权限非常重要。
如果每个人都有集群管理员权限,可能出现:
- 误删生产 Pod
- 查看不该看的 Secret
- 修改系统组件
- 删除 Namespace
RBAC 用来控制谁能访问哪些资源、能执行哪些操作。
4.2 ServiceAccount
ServiceAccount 是 Pod 在集群内访问 API Server 时使用的身份。
例如一个控制器 Pod 需要读取 Pod 列表,就需要给它对应权限。
4.3 Role 与 ClusterRole
Role 是 Namespace 级别权限。
例如:只允许读取 prod Namespace 中的 Pod。
ClusterRole 是集群级别权限。
例如:允许查看所有节点。
4.4 RoleBinding 与 ClusterRoleBinding
RoleBinding 把权限绑定给用户、组或 ServiceAccount。
可以理解为:
text
Role 定义权限。
RoleBinding 把权限给某个身份。
4.5 最小权限原则
生产环境建议遵循最小权限原则。
例如应用只需要读取 Pod 日志,就不要给它删除 Pod 的权限。
5. 可观测性:系统出问题时怎么看
5.1 为什么需要可观测性
应用部署成功不代表长期稳定。
你还需要知道:
- CPU 是否过高
- 内存是否增长异常
- Pod 是否频繁重启
- 接口是否变慢
- 错误率是否升高
- 节点磁盘是否快满
这些都属于可观测性。
5.2 监控
常见组件:
- Metrics Server:提供基础资源指标
- Prometheus:采集和存储指标
- Grafana:展示图表
- Alertmanager:发送告警
常见指标:
- Pod CPU 使用率
- Pod 内存使用率
- Pod 重启次数
- HTTP 请求量
- HTTP 错误率
- 请求延迟
- 节点资源使用率
常用命令:
bash
kubectl top nodes
kubectl top pods
5.3 日志
Kubernetes 推荐应用把日志输出到 stdout 和 stderr。
查看日志:
bash
kubectl logs <pod-name>
kubectl logs <pod-name> --previous
kubectl logs deployment/<deployment-name>
生产常见日志方案:
- Fluent Bit + Elasticsearch + Kibana
- Fluent Bit + Loki + Grafana
5.4 Event
Event 是 Kubernetes 给出的资源变化记录。
很多问题第一时间应该看 Event。
bash
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl describe pod <pod-name>
Event 里常见信息:
- 调度失败原因
- 镜像拉取失败原因
- 健康检查失败原因
- PVC 绑定失败原因
5.5 链路追踪
链路追踪用于分析一次请求经过了哪些服务。
常见工具:
- OpenTelemetry
- Jaeger
- Tempo
适合微服务场景,用于排查慢请求和跨服务调用问题。
6. 发布与交付
6.1 滚动发布
Deployment 默认支持滚动发布。
发布新版本时,Kubernetes 会逐步创建新 Pod,并逐步删除旧 Pod。
命令:
bash
kubectl set image deployment/web web=example/web:v2
kubectl rollout status deployment/web
6.2 回滚
如果新版本有问题,可以回滚。
bash
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
kubectl rollout status deployment/web
6.3 Helm
Helm 是 Kubernetes 的包管理工具。
它适合管理复杂应用,例如:
- MySQL
- Redis
- Prometheus
- NGINX Ingress
- Argo CD
常用命令:
bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-nginx bitnami/nginx
helm upgrade my-nginx bitnami/nginx
helm rollback my-nginx 1
初学者可以这样理解:
text
YAML 多了以后很难维护,Helm 用 Chart 把一组 YAML 打包,并支持参数化。
6.4 Kustomize
Kustomize 用于管理多环境差异。
例如:
text
dev 环境 replicas=1
prod 环境 replicas=5
它不需要模板语法,而是通过 patch 修改基础 YAML。
6.5 GitOps
GitOps 是用 Git 管理集群期望状态。
典型流程:
- Kubernetes YAML 存放在 Git 仓库
- 修改配置通过 Pull Request
- Argo CD 或 Flux 自动同步到集群
- 集群状态和 Git 保持一致
适合:
- 多环境发布
- 审计变更
- 回滚配置
- 团队协作
7. 运用实例:生产级 Namespace 资源限制与 RBAC
7.1 创建 Namespace
yaml
apiVersion: v1
kind: Namespace
metadata:
name: prod
7.2 设置 ResourceQuota
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: prod-quota
namespace: prod
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "50"
services: "20"
persistentvolumeclaims: "10"
7.3 设置 LimitRange
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: prod-limit-range
namespace: prod
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "50m"
memory: "64Mi"
7.4 创建只读 ServiceAccount
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-reader
namespace: prod
7.5 创建 Role
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: prod
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
7.6 创建 RoleBinding
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-reader-binding
namespace: prod
subjects:
- kind: ServiceAccount
name: app-reader
namespace: prod
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
7.7 验证权限
bash
kubectl auth can-i list pods \
--as=system:serviceaccount:prod:app-reader \
-n prod
kubectl auth can-i delete pods \
--as=system:serviceaccount:prod:app-reader \
-n prod
预期结果:
text
yes
no
8. 生产发布排查流程
8.1 发布前检查
bash
kubectl get nodes
kubectl get pods -A
kubectl get events --sort-by=.metadata.creationTimestamp
检查内容:
- 节点是否 Ready
- 系统组件是否正常
- 目标 Namespace 是否存在
- 资源配额是否足够
- 镜像是否能拉取
8.2 发布中观察
bash
kubectl rollout status deployment/<deployment-name> -n <namespace>
kubectl get pods -n <namespace> -w
关注:
- 新 Pod 是否 Running
- 新 Pod 是否 Ready
- 是否出现 CrashLoopBackOff
- 是否出现 ImagePullBackOff
- 旧 Pod 是否正常退出
8.3 发布后验证
bash
kubectl get deployment <deployment-name> -n <namespace>
kubectl get svc -n <namespace>
kubectl get ingress -n <namespace>
kubectl logs deployment/<deployment-name> -n <namespace>
验证:
- 副本数是否正确
- Service endpoints 是否存在
- Ingress 是否生效
- 应用日志是否正常
- 监控指标是否异常
8.4 异常回滚
bash
kubectl rollout history deployment/<deployment-name> -n <namespace>
kubectl rollout undo deployment/<deployment-name> -n <namespace>
kubectl rollout status deployment/<deployment-name> -n <namespace>
9. Kubernetes 扩展能力
9.1 CRD
CRD 用于扩展 Kubernetes API,让 Kubernetes 支持新的资源类型。
例如安装 Prometheus Operator 后,集群中可能出现:
text
Prometheus
ServiceMonitor
Alertmanager
这些不是 Kubernetes 原生资源,而是通过 CRD 扩展出来的。
9.2 Controller
Controller 负责监听资源变化,并把实际状态调整成期望状态。
Kubernetes 自带很多 Controller,例如 Deployment Controller。
自定义 Controller 可以管理你自己的业务资源。
9.3 Operator
Operator 是一种更高级的控制器,通常用于自动化运维复杂应用。
适合:
- 数据库集群
- 中间件集群
- 自动备份
- 自动扩容
- 自动升级
可以简单理解:
text
Operator 把人工运维经验写进 Kubernetes 控制器里。
9.4 Admission Webhook
Admission Webhook 会在资源真正创建或更新前介入。
常见用途:
- 自动给 Pod 注入 sidecar
- 校验镜像来源
- 强制要求设置资源限制
- 自动添加标签
10. 常见生产故障排查
10.1 节点 NotReady
排查:
bash
kubectl describe node <node-name>
kubectl get pods -A -o wide
常见原因:
- kubelet 异常
- 容器运行时异常
- 节点磁盘压力
- 节点内存压力
- 网络插件异常
10.2 应用频繁重启
排查:
bash
kubectl get pods
kubectl describe pod <pod-name>
kubectl logs <pod-name> --previous
常见原因:
- 应用配置错误
- 依赖服务不可用
- 内存限制太小
- 健康检查配置不合理
10.3 Service 无法访问
排查:
bash
kubectl get svc
kubectl get endpoints <service-name>
kubectl get pods --show-labels
常见原因:
- Service selector 写错
- Pod label 不匹配
- Pod 没有 Ready
- targetPort 配置错误
10.4 DNS 异常
排查:
bash
kubectl get pods -n kube-system | grep coredns
kubectl logs -n kube-system deployment/coredns
kubectl exec -it <pod-name> -- nslookup kubernetes.default
常见原因:
- CoreDNS 异常
- CNI 网络异常
- DNS 配置错误
- 节点网络异常
11. 本章小结
生产实践的主线是:
text
资源限制保证稳定 -> RBAC 控制权限 -> 调度策略提高可用性 -> 监控日志帮助发现问题 -> 发布治理降低变更风险 -> 扩展能力支撑平台化
初学者可以按这个顺序逐步深入:
- 先学 requests 和 limits
- 再学 Namespace、ResourceQuota、LimitRange
- 再学 RBAC
- 再学监控、日志、Event
- 最后学 Helm、GitOps、CRD 和 Operator
12. 初学者实践与验证
这一节重点练习生产环境最常见的三个能力:资源治理、权限控制、发布回滚。建议在测试 Namespace 中操作。
12.1 实践一:给 Namespace 设置默认资源限制
实践目的:
- 理解 LimitRange 的作用
- 验证未设置 resources 的 Pod 是否会被自动补默认值
操作步骤:
bash
kubectl create namespace beginner-prod
创建 beginner-limitrange.yaml:
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: beginner-limitrange
namespace: beginner-prod
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
应用配置:
bash
kubectl apply -f beginner-limitrange.yaml
创建一个没有写 resources 的 Pod:
bash
kubectl run no-resource-demo \
--image=nginx:1.25 \
-n beginner-prod
验证方法:
bash
kubectl get pod no-resource-demo -n beginner-prod -o yaml
预期结果:
在容器配置中能看到 Kubernetes 自动补上的:
yaml
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
清理:
bash
kubectl delete pod no-resource-demo -n beginner-prod
12.2 实践二:设置 ResourceQuota 并验证限制效果
实践目的:
- 理解 Namespace 总资源配额
- 验证超过配额时 Kubernetes 会拒绝创建资源
创建 beginner-quota.yaml:
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: beginner-quota
namespace: beginner-prod
spec:
hard:
requests.cpu: "500m"
requests.memory: 512Mi
limits.cpu: "1"
limits.memory: 1Gi
pods: "2"
应用配置:
bash
kubectl apply -f beginner-quota.yaml
kubectl describe quota beginner-quota -n beginner-prod
创建 Deployment:
bash
kubectl create deployment quota-demo \
--image=nginx:1.25 \
--replicas=3 \
-n beginner-prod
验证方法:
bash
kubectl get pods -n beginner-prod
kubectl describe quota beginner-quota -n beginner-prod
kubectl describe deployment quota-demo -n beginner-prod
预期结果:
- 因为 pods 配额是 2,Deployment 想创建 3 个副本时可能无法全部创建
- Events 中可以看到超过配额的提示
修复方法:
bash
kubectl scale deployment quota-demo --replicas=2 -n beginner-prod
kubectl get pods -n beginner-prod
清理:
bash
kubectl delete deployment quota-demo -n beginner-prod
12.3 实践三:创建只读权限并验证 RBAC
实践目的:
- 理解 Role 和 RoleBinding 的关系
- 验证 ServiceAccount 只能做被授权的操作
创建 beginner-rbac.yaml:
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: beginner-prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader-role
namespace: beginner-prod
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: beginner-prod
subjects:
- kind: ServiceAccount
name: pod-reader
namespace: beginner-prod
roleRef:
kind: Role
name: pod-reader-role
apiGroup: rbac.authorization.k8s.io
应用配置:
bash
kubectl apply -f beginner-rbac.yaml
验证方法:
bash
kubectl auth can-i list pods \
--as=system:serviceaccount:beginner-prod:pod-reader \
-n beginner-prod
kubectl auth can-i delete pods \
--as=system:serviceaccount:beginner-prod:pod-reader \
-n beginner-prod
预期结果:
text
yes
no
理解重点:
text
Role 定义能做什么。
RoleBinding 定义把这些权限给谁。
12.4 实践四:发布新版本并回滚
实践目的:
- 理解 Deployment 滚动发布
- 学会观察发布状态
- 学会回滚到上一个版本
创建应用:
bash
kubectl create deployment rollout-demo \
--image=nginx:1.25 \
-n beginner-prod
查看初始版本:
bash
kubectl get deployment rollout-demo -n beginner-prod
kubectl rollout history deployment/rollout-demo -n beginner-prod
发布新版本:
bash
kubectl set image deployment/rollout-demo nginx=nginx:1.26 -n beginner-prod
kubectl rollout status deployment/rollout-demo -n beginner-prod
验证方法:
bash
kubectl describe deployment rollout-demo -n beginner-prod
kubectl rollout history deployment/rollout-demo -n beginner-prod
回滚:
bash
kubectl rollout undo deployment/rollout-demo -n beginner-prod
kubectl rollout status deployment/rollout-demo -n beginner-prod
再次验证:
bash
kubectl describe deployment rollout-demo -n beginner-prod
清理:
bash
kubectl delete deployment rollout-demo -n beginner-prod
12.5 实践五:使用 Event 和 logs 排查异常发布
实践目的:
- 建立生产排查顺序
- 学会从状态、事件、日志三层定位问题
制造错误镜像:
bash
kubectl create deployment broken-release \
--image=nginx:not-exist-tag \
-n beginner-prod
排查顺序:
bash
kubectl get pods -n beginner-prod
kubectl describe pod <pod-name> -n beginner-prod
kubectl get events -n beginner-prod --sort-by=.metadata.creationTimestamp
预期结果:
- Pod 出现 ImagePullBackOff
- describe 和 events 中能看到镜像拉取失败原因
修复:
bash
kubectl set image deployment/broken-release nginx=nginx:1.25 -n beginner-prod
kubectl rollout status deployment/broken-release -n beginner-prod
清理:
bash
kubectl delete deployment broken-release -n beginner-prod
12.6 实践六:清理实验环境
完成所有实验后,删除测试 Namespace:
bash
kubectl delete namespace beginner-prod
验证:
bash
kubectl get namespace beginner-prod
预期结果:
- 查不到该 Namespace
- 或显示正在 Terminating,稍等后消失
12.7 本章练习验收标准
完成本章后,你应该能独立完成:
- 给 Namespace 配置 LimitRange
- 用 ResourceQuota 限制资源总量
- 创建只读 ServiceAccount
- 用
kubectl auth can-i验证权限 - 发布 Deployment 新版本
- 回滚 Deployment
- 用 get、describe、logs、events 建立基础排查流程