Kubernetes Operator 开发指南

概述 Kubernetes Operator 是将人类运维知识编码为软件的范式。它通过 CRD(Custom Resource Definition)扩展 K8s API,通过 Controller 实现自动化运维逻辑。数据库集群管理、消息队列运维、证书轮转……这些原本需要 SRE 手动操作的工作,Operator 可以自动完成。 Operator 的核心思想是声明式 + 控制循环:用户声明期望状态(如"3 个 Redis 副本"),Controller 持续调整实际状态以趋近期望状态。理解这一模式,不仅能开发 Operator,更能深入理解 K8s 本身的设计哲学。 本文基于 Kubernetes v1.30、operator-sdk v1.37、kubebuilder v4.0。参考 Operator 模式文档 Operator 核心概念 CRD 与 Controller 的关系 用户创建 CR (Custom Resource) ──→ API Server 存储 ──→ Controller Watch ↓ Reconcile 循环 ↓ 比较期望状态 vs 实际状态 ↓ 创建/更新/删除资源 ↓ 更新 CR Status 声明式 vs 命令式 模式 示例 特点 命令式 “创建 3 个 Pod” 执行一次就结束,不关心后续状态 声明式 “保持 3 个 Pod 运行” 持续监控,自动修复偏差 Operator 是声明式的——用户声明 spec....

July 23, 2024 · 14 分钟 · 2770 字 · 徐保金

容量规划与弹性扩容实践

概述 容量规划是 SRE 的核心职责之一。Google SRE Book 将容量规划视为"前瞻性工作",强调基于数据预测而非凭经验猜测。一个没有容量规划的团队,要么在高峰期被流量打垮,要么在低谷期浪费大量资源成本。 从指标采集、数据建模、Kubernetes 弹性扩容配置、陷阱规避四个层面,详细梳理容量规划的工程实践。 关于容量规划的系统方法论,可参考 Google SRE Book - Capacity Planning 中关于容量规划与级联故障的讨论。 一、容量规划的核心思想:基于数据而非猜测 容量规划的三个层次 当前容量评估:系统现在能扛多少?水位是多少? 容量趋势预测:按当前增长趋势,什么时候需要扩容? 弹性伸缩策略:面对突发流量,如何自动应对? 容量规划的前提:可观测性 没有度量就没有管理。容量规划的基础是完善的监控体系,需要持续采集以下指标: 指标类别 具体指标 采集工具 CPU 使用率、负载(1m/5m/15m) node_exporter / cAdvisor 内存 使用量、可用量、OOM 次数 node_exporter / cAdvisor 网络 入站/出站带宽、连接数、丢包率 node_exporter 磁盘 I/O IOPS、读写延迟、队列深度 node_exporter 应用层 QPS、延迟分布、错误率 Prometheus / 自定义指标 中间件 连接池使用率、队列长度、缓存命中率 Exporter / 自定义指标 容量水位定义 不是所有指标都同等重要。需要定义关键资源的容量水位: # 容量水位定义示例 capacity_thresholds: cpu: warning: 60% # 60% 开始关注 critical: 80% # 80% 需要扩容 limit: 90% # 90% 紧急扩容 memory: warning: 70% critical: 85% limit: 95% disk_io: warning: 60% critical: 80% limit: 90% connection: warning: 60% # 连接池使用率 critical: 80% limit: 90% 关键原则:水位线不是拍脑袋定的,而是基于压测数据和历史故障分析得出的。如果你的应用在 CPU 85% 时开始出现延迟劣化,那么 warning 就应该设在 70% 以下。...

June 27, 2024 · 6 分钟 · 1180 字 · 徐保金

Kubernetes Pod故障排查速查

排查路径 kubectl get pods → 看状态 kubectl describe pod → 看 Events kubectl logs → 看日志 常见 Pod 状态 状态 含义 常见原因 Pending 未调度 资源不足、调度约束 CrashLoopBackOff 崩溃重启 应用异常、配置错误 ImagePullBackOff 镜像拉取失败 镜像不存在、认证失败 OOMKilled 内存溢出 内存限制过低 CrashLoopBackOff 排查 最常见故障,排查步骤: # 查看上次崩溃日志 kubectl logs <pod> --previous # 查看退出码 kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}' 退出码含义: 137:OOMKilled → 增加 resources.limits.memory 1:应用错误 → 查应用日志 126/127:命令不存在或权限问题 ImagePullBackOff 排查 kubectl describe pod <pod> | grep -A5 Events 常见原因:镜像名拼写错误、仓库需认证、网络不通。...

May 8, 2024 · 1 分钟 · 185 字 · 徐保金

Kubernetes RBAC 与安全上下文

概述 Kubernetes 默认配置的安全性可以用一个词概括:开放。默认 ServiceAccount 拥有集群内几乎所有 API 的访问权限(取决于版本和 PSP 配置),Pod 以 root 用户运行,容器可以挂载宿主机文件系统,网络全通。这种"默认开放"的设计降低了上手门槛,但在生产环境中是巨大的安全隐患。 从 RBAC 权限模型、ServiceAccount 管理、Pod 安全标准、SecurityContext、网络策略到审计日志,详细梳理 K8s 安全加固的实践方法。 本文基于 Kubernetes v1.30。参考 Kubernetes 安全文档 RBAC 权限模型 RBAC 四个核心对象 对象 作用域 功能 Role 命名空间 定义命名空间内的权限 ClusterRole 集群 定义集群范围或命名空间内的权限 RoleBinding 命名空间 将 Role/ClusterRole 绑定到用户/组/SA ClusterRoleBinding 集群 将 ClusterRole 绑定到用户/组/SA 核心关系: 用户/组/ServiceAccount ──Binding──→ Role/ClusterRole ──包含──→ 权限规则 Role 与 ClusterRole # Role:命名空间级别的权限,只影响指定 namespace apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: pod-reader rules: - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["configmaps"] verbs: ["get"] resourceNames: ["app-config"] # 限制只能访问特定 ConfigMap # ClusterRole:集群级别的权限 apiVersion: rbac....

May 2, 2024 · 8 分钟 · 1616 字 · 徐保金

Kubernetes 调度器原理与调优

概述 Kubernetes 调度器是控制平面中最核心的组件之一——它决定每个 Pod 运行在哪个节点上。调度质量直接影响集群的资源利用率、应用性能和可靠性。理解调度器的工作原理,是做好 K8s 生产运维的基本功。 从调度流程、过滤打分机制、亲和性、污点容忍、优先级抢占到自定义调度器,详细梳理调度器的原理与调优实践。 本文基于 Kubernetes v1.30。参考 Kubernetes 调度器文档 调度流程 整体流程 Pod 创建 → API Server → etcd → 调度器 Watch → 调度决策 → 绑定到节点 → kubelet 创建容器 调度器的核心工作分为两个阶段: 1. 过滤(Filter):排除不满足条件的节点 → 候选节点集 2. 打分(Score):对候选节点打分 → 选择最高分节点 详细调度流程 ┌──────────────┐ │ Pod 入队 │ └──────┬───────┘ ▼ ┌──────────────┐ │ 调度周期开始 │ └──────┬───────┘ ▼ ┌────────────────────────┐ │ 扩展点:PreFilter │ ← 预过滤(检查 Pod 是否可调度) └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:Filter │ ← 过滤不满足条件的节点 │ (排除不可行节点) │ └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:PostFilter │ ← 过滤后无节点?(触发抢占) └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:Score │ ← 对候选节点打分 │ (选择最优节点) │ └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:Reserve │ ← 预留资源 └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:Permit │ ← 允许/延迟/拒绝 └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:PreBind │ ← 绑定前处理 └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:Bind │ ← 绑定到节点 └────────────┬────────────┘ ▼ ┌────────────────────────┐ │ 扩展点:PostBind │ ← 绑定后处理 └────────────────────────┘ 调度队列 调度器内部维护三个队列:...

April 29, 2024 · 8 分钟 · 1655 字 · 徐保金

K8s 网络模型:CNI 与 Service 网络

Kubernetes 网络模型四大要求 Kubernetes 网络模型的设计基于四个核心要求,理解它们是掌握 K8s 网络的基础。根据 Kubernetes 官方网络模型文档,这四个要求构成了集群网络通信的基石。 1. Pod 间通信(Pod-to-Pod) K8s 要求所有 Pod 之间可以直接通过 IP 通信,无需 NAT(网络地址转换)。这意味着: 每个 Pod 拥有独立的 IP 地址 Pod 之间通信使用真实 Pod IP,不经过 NAT 转换 无论 Pod 调度到哪个 Node,Pod 间网络始终扁平可达 这是 K8s 网络模型最核心的设计决策。传统数据中心网络中,跨主机容器通信通常依赖端口映射或 NAT,而 K8s 选择了扁平网络模型,让每个 Pod 成为网络中平等的一等公民。 2. Node 与 Pod 通信(Node-to-Pod) Node 上的进程(包括 kubelet、kube-proxy)必须能直接与该 Node 上任何 Pod 通信,同样不经过 NAT。这个要求保证了: kubelet 可以执行健康检查(liveness/readiness probe) 节点上的监控 agent 能直接采集 Pod 指标 主机网络进程与 Pod 网络互通 3. Service 网络 Service 提供了一个稳定的虚拟 IP(ClusterIP),将流量负载均衡到后端 Pod。Service 网络是独立于 Pod 网络的虚拟地址段(默认 10....

April 12, 2024 · 4 分钟 · 722 字 · 徐保金

Kubernetes Ingress 控制器选型与配置

概述 Kubernetes Service 提供四层负载均衡,但在生产环境中,绝大多数 Web 应用需要七层路由能力:基于域名的虚拟主机、基于路径的路由、TLS 终止、灰度发布。Ingress 就是 K8s 对七层路由的抽象,而 Ingress Controller 则是这一抽象的具体实现。 选择 Ingress Controller 不是一个小决策——它处于所有外部流量的入口位置,一旦选错或配置不当,影响的是整个集群的服务可用性。本文对比主流 Ingress Controller 的优劣,并给出生产环境配置实践。 本文基于 Kubernetes v1.30。参考 Kubernetes Ingress 文档 Ingress 原理 数据流路径 客户端 → 负载均衡器(云LB/MetalLB) → Ingress Controller Pod → Service → Pod ↑ Ingress 资源 (路由规则) Ingress Controller 本质上是一个运行在集群中的 Pod(通常是 Deployment 或 DaemonSet),它: 监听 K8s API 中的 Ingress 资源变化 将 Ingress 规则翻译成自身配置(如 nginx.conf) 热加载配置,处理外部请求并路由到对应 Service Ingress 资源结构 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myapp-ingress namespace: production annotations: nginx....

March 27, 2024 · 7 分钟 · 1490 字 · 徐保金

kubectl 生产力指南:插件与别名

概述 kubectl 是 Kubernetes 管理员最常用的工具,但大多数人只用了它 20% 的功能。每天敲几十遍 kubectl get pods -n production,却不知道一行别名就能省掉一半字符;遇到问题只知道 kubectl describe 和 kubectl logs,却不知道 krew 插件能一键排查网络、资源、证书问题。本文逐步梳理 kubectl 的生产力提升工具链,从别名到插件到交互式工具,让你的 K8s 日常操作效率翻倍。 参考来源:kubectl 官方文档、krew 官网 一、kubectl 别名配置 1.1 基础别名 # ~/.bashrc 或 ~/.zshrc # 基础缩写 alias k='kubectl' alias kg='kubectl get' alias kd='kubectl describe' alias kdel='kubectl delete' alias ke='kubectl exec' alias kl='kubectl logs' alias kf='kubectl apply -f' alias kdf='kubectl delete -f' alias kr='kubectl run' # 常用资源缩写 alias kgp='kubectl get pods' alias kgs='kubectl get svc' alias kgn='kubectl get nodes' alias kgd='kubectl get deployments' alias kgsec='kubectl get secrets' alias kgcm='kubectl get configmaps' alias kging='kubectl get ingress' alias kgns='kubectl get namespaces' alias kgpv='kubectl get pv' alias kgpvc='kubectl get pvc' alias kdsa='kubectl describe sa' # 宽输出 + 自定义列 alias kgpw='kubectl get pods -o wide' alias kgsw='kubectl get svc -o wide' alias kgnw='kubectl get nodes -o wide' # watch 模式 alias kgpw='watch -n 2 kubectl get pods -o wide' alias kgnw='watch -n 5 kubectl get nodes -o wide' # 所有命名空间 alias kgpa='kubectl get pods --all-namespaces' alias kgsa='kubectl get svc --all-namespaces' # YAML 输出 alias kgpy='kubectl get pods -o yaml' alias kgsy='kubectl get svc -o yaml' 1....

March 12, 2024 · 14 分钟 · 2784 字 · 徐保金

容器持久化存储方案选型

K8s 存储体系:三层抽象 Kubernetes 存储体系通过三层抽象解耦了存储使用方与提供方,这是理解容器持久化存储的核心。根据 K8s 存储文档,三层结构如下: ┌──────────────────────────────────────────────────────┐ │ Pod (使用方) │ │ volumeMounts → volumes │ ├──────────────────────────────────────────────────────┤ │ PVC (声明) — 用户申请存储 │ │ "我需要 10Gi RWO 的存储" │ ├──────────────────────────────────────────────────────┤ │ StorageClass (动态供给) — 存储模板 │ │ "使用 ceph-rbd 驱动,reclaim: Retain" │ ├──────────────────────────────────────────────────────┤ │ PV (物理资源) — 实际存储 │ │ "10.0.0.5:/data/pvc-xxx (NFS)" │ └──────────────────────────────────────────────────────┘ PV(PersistentVolume) PV 是集群级资源,代表物理存储的抽象。PV 可以由管理员手动创建,也可通过 StorageClass 自动供给: apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-data spec: capacity: storage: 50Gi accessModes: - ReadWriteMany # 多节点读写 persistentVolumeReclaimPolicy: Retain nfs: server: 10....

February 6, 2024 · 4 分钟 · 821 字 · 徐保金

Kubernetes 资源管理:Requests 与 Limits

Requests 与 Limits 的语义 Kubernetes 中每个容器可以配置 CPU 和 Memory 的 requests 与 limits。很多开发者分不清二者的区别,导致 Pod 频繁被驱逐或 OOMKilled。 apiVersion: v1 kind: Pod metadata: name: api-server spec: containers: - name: app image: myapp:latest resources: requests: cpu: "250m" # 0.25 核 memory: "256Mi" limits: cpu: "500m" # 0.5 核 memory: "512Mi" 核心区别 维度 Requests Limits 作用阶段 调度时 运行时 含义 Pod 需要的最小资源保证 Pod 能使用的最大资源上限 调度器行为 调度器根据 requests 判断节点是否有足够资源 调度器不关心 limits 运行时行为 cgroups 中的保障份额 CPU 被节流(throttle),Memory 触发 OOMKilled 是否可超卖 可以(节点上所有 Pod 的 limits 之和可超过节点容量) 不建议超卖 Memory 简单理解:...

February 2, 2024 · 6 分钟 · 1069 字 · 徐保金