Skip to content

本模块聚焦 Kubernetes 进阶知识与运维实战,涵盖调度策略、权限管理、存储、Operator、故障排查、性能调优和网络安全等高级主题,考察候选人在复杂场景下的 K8s 运维能力。

Q1: K8s的调度策略是什么?影响调度的因素有哪些? 「🔴 高级」

考察点:考察 K8s 调度原理的深度理解,筛掉只会默认调度、不了解调度机制和调优手段的人。

参考答案

  • K8s 调度器(kube-scheduler)的核心职责是为新创建的 Pod 选择最合适的 Node 节点运行。
  • 调度过程分为两个阶段:过滤(Filtering)打分(Scoring)

调度流程

  1. 过滤阶段(Predicate)
    • 遍历所有节点,过滤掉不满足 Pod 运行条件的节点。
    • 过滤规则包括:资源是否充足、端口是否冲突、节点是否可调度、污点容忍、亲和性约束等。
  2. 打分阶段(Priority)
    • 对通过过滤的节点进行打分排序,选择分数最高的节点。
    • 打分维度:资源利用率、节点亲和性、Pod 亲和/反亲和、本地数据局部性等。
  3. 绑定阶段(Binding)
    • 将 Pod 绑定到目标节点,通过 apiserver 写入 etcd。

影响调度的关键因素

  • 节点选择器(nodeSelector)
    • 最简单的调度约束,Pod 只能调度到包含指定标签的节点上。
    • 硬约束,匹配不到则 Pod 处于 Pending。
  • 亲和性与反亲和性(Affinity / Anti-Affinity)
    • 节点亲和性(nodeAffinity):比 nodeSelector 更灵活,支持 In/NotIn/Exists/DoesNotExist 等操作符。
      • requiredDuringSchedulingIgnoredDuringExecution:硬约束,必须满足。
      • preferredDuringSchedulingIgnoredDuringExecution:软约束,尽量满足。
    • Pod 亲和性(podAffinity):希望某些 Pod 调度到同一个拓扑域(如同一节点、同一机架)。
    • Pod 反亲和性(podAntiAffinity):希望某些 Pod 分散到不同拓扑域,提高可用性。
  • 污点和容忍(Taints & Tolerations)
    • 节点上打 Taint(污点),Pod 上声明 Toleration(容忍),只有容忍对应污点的 Pod 才能调度到该节点。
    • 常见用途:专用节点(GPU 节点)、节点隔离、节点资源预留。
    • 污点效果:NoSchedule(不调度)、PreferNoSchedule(尽量不调度)、NoExecute(不调度且驱逐已有 Pod)。
  • 资源限制(Resources)
    • requests:调度时的最低资源要求,影响过滤和打分。
    • limits:运行时的资源上限,影响 cgroup 限制。
    • 调度器按 requests 计算节点剩余可分配资源。
  • 优先级与抢占(Priority & Preemption)
    • 高优先级 Pod 调度失败时,会抢占(驱逐)低优先级 Pod 的节点。
    • 用于核心业务优先保障。
  • 节点压力驱逐
    • 节点资源不足时(内存、磁盘、PID),kubelet 会驱逐低优先级 Pod。
yaml
# 亲和性示例:Pod 尽量分散到不同节点
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: web
        topologyKey: kubernetes.io/hostname

追问延伸

  • 调度器是怎么打分的?LeastRequested 和 MostRequested 策略有什么区别?
  • 什么是调度器框架(Scheduler Framework)?有哪些扩展点?
  • 如果一个 Pod 一直 Pending 调度失败,怎么排查原因?

Q2: K8s的RBAC是什么?如何工作? 「🟡 中级」

考察点:考察 K8s 权限管理知识,筛掉不了解 RBAC、不会配置权限控制的人。

参考答案

  • RBAC(Role-Based Access Control,基于角色的访问控制) 是 K8s 的权限管理机制,通过角色和角色绑定来控制用户或服务账户对 API 资源的访问权限。
  • RBAC 的核心三要素:角色(Role)主体(Subject)绑定(Binding)

核心概念

  • 角色(Role / ClusterRole)
    • 定义了一组权限规则(可以对哪些资源做哪些操作)。
    • Role:命名空间级别,只能授权其所在命名空间内的资源。
    • ClusterRole:集群级别,可以授权集群资源(如 nodes、persistentvolumes)、非资源 URL(如 /healthz)、所有命名空间的资源。
  • 主体(Subject)
    • User:普通用户,由外部认证系统管理(K8s 不直接管理用户)。
    • Group:用户组。
    • ServiceAccount:服务账户,Pod 内进程访问 API 时使用的身份。
  • 绑定(RoleBinding / ClusterRoleBinding)
    • 将角色绑定到主体,实现权限授予。
    • RoleBinding:在命名空间内绑定,只能授予该命名空间内的权限。
    • ClusterRoleBinding:集群级绑定,授予集群范围的权限。
RBAC 授权模型:
Subject (User/SA/Group) ──绑定──► Role/ClusterRole ──规则──► Resources + Verbs
  • 权限规则要素

    • apiGroups:API 组(如 apps"" 表示核心组)。
    • resources:资源类型(如 podsdeployments)。
    • verbs:操作(get、list、watch、create、update、patch、delete、deletecollection)。
    • resourceNames:具体资源名称(可选,细粒度控制)。
  • 示例

    yaml
    # 定义 Role:允许读取 default 命名空间的 Pod
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: pod-reader
      namespace: default
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
    
    # 绑定 Role 到 ServiceAccount
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: myapp
      namespace: default
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
  • 最佳实践

    • 遵循最小权限原则,只授予必要的权限。
    • 优先使用命名空间级别的 Role 和 RoleBinding。
    • 使用 ServiceAccount 而非 User 管理应用权限。
    • 定期审计权限配置,清理不再使用的绑定。
    • 使用聚合 ClusterRole 组合权限。

追问延伸

  • K8s 中 User 和 ServiceAccount 有什么区别?
  • 什么是 ClusterRole 的聚合(Aggregation)?有什么用?
  • 除了 RBAC,K8s 还有哪些鉴权方式?(ABAC、Node、Webhook)
  • 如何调试 RBAC 权限问题?(kubectl auth can-i)

Q3: K8s的持久化存储怎么做?PV、PVC、StorageClass 「🟡 中级」

考察点:考察 K8s 存储管理知识,筛掉不理解存储抽象层、不会配置持久化存储的人。

参考答案

  • K8s 提供了三层存储抽象:PVPVCStorageClass,实现存储资源与应用解耦。

核心概念

  1. PV(PersistentVolume,持久卷)
    • 集群中的一块存储资源,由管理员预先创建或由 StorageClass 动态供给。
    • 是集群级资源,不属于任何命名空间。
    • 包含存储的具体信息:类型(NFS、iSCSI、云盘等)、容量、访问模式、回收策略等。
  2. PVC(PersistentVolumeClaim,持久卷声明)
    • 用户对存储的"申请",声明所需的存储大小、访问模式等。
    • 是命名空间级资源。
    • PVC 与 PV 一一绑定后,Pod 就可以通过挂载 PVC 使用存储。
  3. StorageClass(存储类)
    • 定义存储的"类型"和动态供给(Dynamic Provisioning)的参数。
    • 通过 StorageClass,用户只需创建 PVC,系统自动创建对应的 PV,无需管理员预先创建。
    • 每个 StorageClass 对应一个 Provisioner(存储供给器)。

绑定机制

  • PV 和 PVC 根据容量访问模式StorageClass 进行匹配绑定。
  • 一对一绑定,绑定关系是双向的,一旦绑定就不会解除。
  • 静态供给(Static Provisioning):管理员预先创建 PV,用户创建 PVC 进行绑定。
  • 动态供给(Dynamic Provisioning):通过 StorageClass 自动创建 PV,是更推荐的方式。

访问模式(AccessModes)

  • ReadWriteOnce(RWO):单节点读写,最常见。
  • ReadOnlyMany(ROX):多节点只读。
  • ReadWriteMany(RWX):多节点读写,需要共享存储支持(NFS、Ceph 等)。

回收策略(ReclaimPolicy)

  • Retain:保留,PVC 删除后 PV 和数据保留,需手动清理。
  • Delete:删除,PVC 删除后 PV 和数据自动删除(动态供给默认)。
  • Recycle:回收,清空数据后 PV 可重新绑定(已废弃,推荐用动态供给)。
存储模型:
Pod → PVC → PV → 实际存储(NFS/云盘/Ceph/...)

       StorageClass 动态供给
  • 最佳实践
    • 优先使用 StorageClass 动态供给,减少运维成本。
    • 根据业务需求选择合适的存储类型和访问模式。
    • 重要数据使用 Retain 回收策略,防止误删。
    • 使用 StatefulSet + volumeClaimTemplates 管理有状态应用存储。
    • 定期备份 PV 数据(VolumeSnapshot)。

追问延伸

  • 什么是 VolumeSnapshot?怎么使用?
  • 本地存储(Local PV)和普通 PV 有什么区别?适用什么场景?
  • CSI 是什么?和树内(in-tree)存储插件有什么区别?
  • PV 和 PVC 的绑定是怎么匹配的?如果有多个匹配的 PV 会选哪个?

Q4: 什么是Operator和CRD? 「🔴 高级」

考察点:考察 K8s 扩展能力和云原生理念,筛掉只停留在使用内置资源、不了解 K8s 扩展机制的人。

参考答案

  • CRD(Custom Resource Definition,自定义资源定义)

    • K8s 提供的扩展机制,允许用户定义自己的资源类型,像使用内置资源(Pod、Deployment)一样使用自定义资源。
    • CRD 定义了自定义资源的结构(schema、字段、版本),注册到 API Server 后即可通过 kubectl 操作。
    • CRD 本身只是数据定义,没有业务逻辑。
  • Controller(控制器)

    • 是一个运行中的程序,通过 Watch 机制监听自定义资源的变化,并执行相应的业务逻辑。
    • 遵循控制循环(Control Loop)模式:观察当前状态 → 与期望状态对比 → 执行操作使状态趋近。
    • K8s 内置的 Deployment Controller、ReplicaSet Controller 都是这个模式。
  • Operator 模式

    • Operator = CRD + Controller + 领域知识。
    • Operator 将运维人员的运维经验和领域知识编码为软件,实现应用的自动化部署、升级、备份、故障恢复等运维操作。
    • 核心思想:用 K8s 原生的方式(声明式 API)管理有状态应用和复杂系统。
    • Operator 框架:Operator SDK、Kubebuilder,帮助快速开发 Operator。
  • 常见的 Operator

    • etcd Operator:管理 etcd 集群的部署、扩缩容、备份恢复。
    • Prometheus Operator:管理 Prometheus、Alertmanager 等监控组件的部署和配置。
    • MySQL Operator / Postgres Operator:管理数据库集群。
    • Istio Operator:管理 Istio 服务网格的安装和升级。
    • ArgoCD Operator:管理 GitOps 工具 ArgoCD。
Operator 工作原理:
┌──────────────────────────────────────────────┐
│              Kubernetes API Server           │
│   ┌─────────┐                                │
│   │  CRD    │  (自定义资源定义)               │
│   │ MyDB    │                                │
│   └────┬────┘                                │
│        │                                     │
│   ┌────▼────┐                                │
│   │ CR 实例 │  (用户创建的资源)               │
│   │ mydb-01 │                                │
│   └────┬────┘                                │
└────────┼─────────────────────────────────────┘
         │ Watch
   ┌─────▼──────┐
   │ Controller │──► 调谐循环:创建/更新/删除
   │  (Operator)│     StatefulSet/Service/PV...
   └────────────┘
  • Operator 的成熟度模型(Operator Capability Level)
    1. Level 1 - Basic Install:基本安装和配置。
    2. Level 2 - Seamless Upgrades:无缝升级。
    3. Level 3 - Full Lifecycle:完整生命周期(备份、恢复、故障处理)。
    4. Level 4 - Deep Insights:深度可观测性(指标、日志、告警)。
    5. Level 5 - Auto Pilot:自动驾驶(自动调优、自动故障修复)。

追问延伸

  • Operator 和 Helm 有什么区别?各自适用什么场景?
  • 开发一个 Operator 需要哪些步骤和技术栈?
  • 什么是 Operator Hub?有什么用?
  • 控制循环(Reconcile Loop)的幂等性为什么很重要?

Q5: K8s常见故障怎么排查? 「🔴 高级」

考察点:考察实际运维和故障排查能力,筛掉只会用 K8s 但遇到问题就束手无策的人。

参考答案

  • K8s 故障排查是一个系统化的过程,需要从应用层、Pod 层、节点层、集群层逐步深入定位。

常用排查命令

  • kubectl get:查看资源状态。
  • kubectl describe:查看资源详情和事件(Events),最常用的排查命令。
  • kubectl logs:查看容器日志。
  • kubectl exec:进入容器内部排查。
  • kubectl top:查看资源使用率。
  • kubectl events:查看集群事件。

常见故障场景与排查思路

  1. Pod 一直 Pending

    • kubectl describe pod 查看 Events。
    • 常见原因:资源不足(CPU/内存不够调度)、镜像拉取失败、污点不匹配、PVC 绑定失败、节点不可调度。
    • 排查:kubectl describe node 查看节点资源、kubectl get pvc 查看存储声明。
  2. Pod 处于 CrashLoopBackOff

    • 容器启动后不断崩溃重启。
    • 排查:kubectl logs 查看应用日志、kubectl describe 查看退出码和事件。
    • 常见原因:应用配置错误、依赖服务不可用、健康检查配置不当、权限不足、资源限制导致 OOMKilled。
  3. Pod 处于 ImagePullBackOff

    • 镜像拉取失败。
    • 排查:镜像名称/标签是否正确、仓库认证(imagePullSecret)是否配置、网络是否可达、镜像是否存在。
  4. Service 无法访问

    • 排查步骤:
      1. 直接访问 Pod IP + Port 确认应用正常。
      2. 检查 Service 的 Selector 是否匹配 Pod 标签。
      3. 检查 Endpoints/EndpointSlice 是否有后端 Pod。
      4. 检查 Service 端口和目标端口是否正确。
      5. 检查 kube-proxy 是否正常运行、iptables/IPVS 规则是否正确。
      6. 检查网络策略(NetworkPolicy)是否阻止了流量。
  5. 节点 NotReady

    • kubectl describe node 查看节点状态和原因。
    • 常见原因:节点宕机、kubelet 故障、网络分区、磁盘压力、内存压力、PID 压力。
    • 排查:登录节点查看 kubelet 状态、系统日志、资源使用情况。
  6. DNS 解析异常

    • 应用报域名解析失败。
    • 排查:CoreDNS Pod 是否正常、/etc/resolv.conf 配置是否正确、网络策略是否阻止了 DNS 流量、DNS 服务是否可达。
  7. Ingress 访问异常

    • 排查:Ingress 规则是否正确、Ingress Controller 是否正常、后端 Service 是否可达、TLS 证书是否有效、路径匹配是否正确。

排查方法论

  • 从外到内:先看入口(Ingress/Service),再看应用(Pod),最后看底层(节点/网络)。
  • 看日志和事件:Events 和日志是排障的第一手信息。
  • 对比法:对比正常 Pod 和异常 Pod 的配置差异。
  • 二分法:逐步缩小排查范围,快速定位问题所在层。

追问延伸

  • 怎么排查 Pod 之间网络不通的问题?有哪些工具和方法?
  • 集群整体不可用怎么排查?优先检查哪些组件?
  • 怎么排查 etcd 性能问题?
  • 你遇到过最棘手的 K8s 故障是什么?怎么解决的?

Q6: K8s的性能调优有哪些方向? 「🔴 高级」

考察点:考察 K8s 性能优化的系统性知识,筛掉只停留在使用层面、对集群性能没有概念的人。

参考答案

  • K8s 性能调优是一个系统性工程,涉及控制平面、节点、网络、存储等多个层面。

1. etcd 优化

  • etcd 是集群的核心存储,其性能直接影响整个集群。
  • 硬件层面:使用 SSD 甚至 NVMe 磁盘,保证低延迟 IO;独立部署 etcd,不与其他组件争用资源。
  • 配置层面
    • 调整 --quota-backend-bytes(默认 2GB),根据实际数据量调整。
    • 启用 compaction 和 defrag,定期压缩历史版本,控制数据库大小。
    • 合理设置心跳间隔(--heartbeat-interval)和选举超时(--election-timeout)。
  • 部署层面:3 节点或 5 节点集群,奇数节点;节点分布在不同可用区保证高可用。
  • 监控:关注 etcd 的 watch 数量、db size、proposal 延迟、磁盘 fsync 延迟。

2. API Server 调优

  • 水平扩展:API Server 是无状态的,可以多副本部署分担压力。
  • 请求限流:配置 --max-requests-inflight--max-mutating-requests-inflight 防止过载。
  • 缓存优化:合理设置 watch 缓存,减少 etcd 压力。
  • API 聚合:使用 API Priority and Fairness 对不同优先级请求分级处理。
  • 减少 API 调用:使用 informer 本地缓存,避免频繁直接调用 API。

3. 调度器优化

  • 调度算法:根据集群规模选择合适的调度算法和插件。
  • 调度周期:调整 --kube-api-qps--kube-api-burst,提高 API 访问速率。
  • 禁用不必要的调度插件,减少调度开销。
  • 大规模集群:使用调度器框架、配置百分比阈值(percentageOfNodesToScore)减少打分节点数。

4. 节点资源调优

  • 资源预留:配置 kubelet 的 --system-reserved--kube-reserved,为系统和 K8s 组件预留资源,防止 Pod 占用全部资源。
  • 驱逐阈值:合理设置内存、磁盘、PID 驱逐阈值,提前驱逐低优先级 Pod。
  • Pod 密度:根据节点配置合理控制单节点 Pod 数量上限(--max-pods),默认 110。
  • CPU 管理策略static 策略为 Guaranteed QoS 的 Pod 绑定独占 CPU 核心,减少上下文切换。
  • 内存管理:启用 QoS 分级(Guaranteed/Burstable/Besteffort),OOM 时按优先级驱逐。

5. 网络性能优化

  • kube-proxy 模式:大规模集群使用 IPVS 模式替代 iptables,规则匹配性能更好。
  • CNI 选择:根据场景选择合适的 CNI(Calico、Cilium、Flannel 等),Cilium 基于 eBPF 性能更优。
  • Service 拓扑:使用 Topology Aware Hints,让流量优先访问同节点/同可用区的后端,减少跨节点网络开销。
  • 网络策略:避免过多的 NetworkPolicy 规则影响性能。

6. 应用层面优化

  • 合理设置 requests 和 limits,避免资源浪费和争抢。
  • 使用 HPA/VPA 自动扩缩容,应对流量波动。
  • 优化镜像大小和启动速度,加快调度和扩缩容响应。
K8s 性能调优优先级:
etcd → API Server → 调度器 → 节点 → 网络 → 应用

最关键,也是最容易成为瓶颈的地方

追问延伸

  • 怎么判断 etcd 是性能瓶颈?有哪些关键指标?
  • IPVS 相比 iptables 为什么性能更好?原理是什么?
  • 大规模 K8s 集群(万级节点)会遇到哪些挑战?怎么解决?
  • 什么是 eBPF?它在 K8s 网络中有什么优势?

Q7: 什么是网络策略(NetworkPolicy)? 「🟡 中级」

考察点:考察 K8s 网络安全知识,筛掉不知道 NetworkPolicy、对 Pod 间网络安全没有概念的人。

参考答案

  • NetworkPolicy(网络策略) 是 K8s 中用于控制 Pod 间网络流量的 API 对象,实现 Pod 级别的网络隔离和访问控制。
  • 默认情况下,K8s 中所有 Pod 之间网络是互通的(扁平网络),NetworkPolicy 提供了白名单机制来限制流量。

核心概念

  • 作用对象:通过 podSelector 选择要应用策略的 Pod 组。
  • 策略类型
    • Ingress:入站流量控制(谁可以访问这些 Pod)。
    • Egress:出站流量控制(这些 Pod 可以访问谁)。
    • 两种都不指定则默认都限制,或显式指定 policyTypes
  • 流量来源/目标选择(三维度):
    1. 按 Pod 标签podSelector):选择同命名空间内的某些 Pod。
    2. 按命名空间namespaceSelector):选择整个命名空间的所有 Pod。
    3. 按 IP 段ipBlock):指定 CIDR 范围的 IP 地址。
  • 端口控制:可以指定具体的端口号或端口范围,以及协议(TCP/UDP/SCTP)。

工作原理

  • NetworkPolicy 本身只是规则定义,需要由支持 NetworkPolicy 的 CNI 插件来实现。

  • 常见支持 NetworkPolicy 的 CNI:Calico、Cilium、Weave、kube-router 等。

  • Flannel 默认不支持 NetworkPolicy。

  • CNI 插件通过在节点上配置防火墙规则(iptables、eBPF 等)来实现流量控制。

  • 示例

    yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: backend
      policyTypes:
      - Ingress
      - Egress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: frontend
        ports:
        - protocol: TCP
          port: 8080
      egress:
      - to:
        - podSelector:
            matchLabels:
              app: database
        ports:
        - protocol: TCP
          port: 5432

最佳实践

  • 默认拒绝:先创建默认拒绝所有流量的 NetworkPolicy,再按需放通。
  • 最小权限:只开放必要的端口和来源。
  • 按业务分层:前端、后端、数据库层之间通过 NetworkPolicy 隔离。
  • 命名空间隔离:不同环境(prod/staging/dev)使用不同命名空间并通过网络策略隔离。
  • 配合 RBAC:限制 NetworkPolicy 的修改权限,防止被恶意修改。

追问延伸

  • NetworkPolicy 是怎么实现的?Calico 和 Cilium 的实现方式有什么不同?
  • 什么是默认拒绝策略?怎么配置?
  • NetworkPolicy 支持七层规则吗?(不支持,是四层的,七层需要服务网格)
  • 除了 NetworkPolicy,K8s 还有哪些网络安全手段?