Kubernetes 生产实践、可观测性与扩展入门

开篇:生产实践、可观测性与扩展能做什么

前两个文档解决的是"应用如何跑起来、如何访问、如何配置、如何保存数据"。

这个文档要解决的是更接近真实生产环境的问题:

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 建立基础排查流程
相关推荐
Devin~Y2 小时前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 与 Spring AI(RAG/Agent)三轮连环问
java·spring boot·redis·mysql·spring cloud·kafka·kubernetes
bLEd RING2 小时前
SpringBoot3.3.0集成Knife4j4.5.0实战
java
小松加哲2 小时前
Spring MVC 核心原理全解析
java·spring·mvc
Ulyanov2 小时前
《PySide6 GUI开发指南:QML核心与实践》 第二篇:QML语法精要——构建声明式UI的基础
java·开发语言·javascript·python·ui·gui·雷达电子对抗系统仿真
码界筑梦坊2 小时前
357-基于Java的大型商场应急预案管理系统
java·开发语言·毕业设计·知识分享
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【31】集成 Studio 模块实现可视化 Agent 调试
java·人工智能·spring
014-code3 小时前
Spring Data JPA 实战指南
java·spring
安小牛3 小时前
Android 开发汉字转带声调的拼音
android·java·学习·android studio
聚美智数3 小时前
企业实际控制人查询-公司实控人查询
android·java·javascript