Appearance
本模块聚焦 Kubernetes 进阶知识与运维实战,涵盖调度策略、权限管理、存储、Operator、故障排查、性能调优和网络安全等高级主题,考察候选人在复杂场景下的 K8s 运维能力。
Q1: K8s的调度策略是什么?影响调度的因素有哪些? 「🔴 高级」
考察点:考察 K8s 调度原理的深度理解,筛掉只会默认调度、不了解调度机制和调优手段的人。
参考答案:
- K8s 调度器(kube-scheduler)的核心职责是为新创建的 Pod 选择最合适的 Node 节点运行。
- 调度过程分为两个阶段:过滤(Filtering) → 打分(Scoring)。
调度流程:
- 过滤阶段(Predicate):
- 遍历所有节点,过滤掉不满足 Pod 运行条件的节点。
- 过滤规则包括:资源是否充足、端口是否冲突、节点是否可调度、污点容忍、亲和性约束等。
- 打分阶段(Priority):
- 对通过过滤的节点进行打分排序,选择分数最高的节点。
- 打分维度:资源利用率、节点亲和性、Pod 亲和/反亲和、本地数据局部性等。
- 绑定阶段(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 分散到不同拓扑域,提高可用性。
- 节点亲和性(nodeAffinity):比 nodeSelector 更灵活,支持
- 污点和容忍(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:资源类型(如pods、deployments)。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 提供了三层存储抽象:PV、PVC、StorageClass,实现存储资源与应用解耦。
核心概念:
- PV(PersistentVolume,持久卷):
- 集群中的一块存储资源,由管理员预先创建或由 StorageClass 动态供给。
- 是集群级资源,不属于任何命名空间。
- 包含存储的具体信息:类型(NFS、iSCSI、云盘等)、容量、访问模式、回收策略等。
- PVC(PersistentVolumeClaim,持久卷声明):
- 用户对存储的"申请",声明所需的存储大小、访问模式等。
- 是命名空间级资源。
- PVC 与 PV 一一绑定后,Pod 就可以通过挂载 PVC 使用存储。
- 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):
- Level 1 - Basic Install:基本安装和配置。
- Level 2 - Seamless Upgrades:无缝升级。
- Level 3 - Full Lifecycle:完整生命周期(备份、恢复、故障处理)。
- Level 4 - Deep Insights:深度可观测性(指标、日志、告警)。
- 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:查看集群事件。
常见故障场景与排查思路:
Pod 一直 Pending:
kubectl describe pod查看 Events。- 常见原因:资源不足(CPU/内存不够调度)、镜像拉取失败、污点不匹配、PVC 绑定失败、节点不可调度。
- 排查:
kubectl describe node查看节点资源、kubectl get pvc查看存储声明。
Pod 处于 CrashLoopBackOff:
- 容器启动后不断崩溃重启。
- 排查:
kubectl logs查看应用日志、kubectl describe查看退出码和事件。 - 常见原因:应用配置错误、依赖服务不可用、健康检查配置不当、权限不足、资源限制导致 OOMKilled。
Pod 处于 ImagePullBackOff:
- 镜像拉取失败。
- 排查:镜像名称/标签是否正确、仓库认证(imagePullSecret)是否配置、网络是否可达、镜像是否存在。
Service 无法访问:
- 排查步骤:
- 直接访问 Pod IP + Port 确认应用正常。
- 检查 Service 的 Selector 是否匹配 Pod 标签。
- 检查 Endpoints/EndpointSlice 是否有后端 Pod。
- 检查 Service 端口和目标端口是否正确。
- 检查 kube-proxy 是否正常运行、iptables/IPVS 规则是否正确。
- 检查网络策略(NetworkPolicy)是否阻止了流量。
- 排查步骤:
节点 NotReady:
kubectl describe node查看节点状态和原因。- 常见原因:节点宕机、kubelet 故障、网络分区、磁盘压力、内存压力、PID 压力。
- 排查:登录节点查看 kubelet 状态、系统日志、资源使用情况。
DNS 解析异常:
- 应用报域名解析失败。
- 排查:CoreDNS Pod 是否正常、
/etc/resolv.conf配置是否正确、网络策略是否阻止了 DNS 流量、DNS 服务是否可达。
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。
- 流量来源/目标选择(三维度):
- 按 Pod 标签(
podSelector):选择同命名空间内的某些 Pod。 - 按命名空间(
namespaceSelector):选择整个命名空间的所有 Pod。 - 按 IP 段(
ipBlock):指定 CIDR 范围的 IP 地址。
- 按 Pod 标签(
- 端口控制:可以指定具体的端口号或端口范围,以及协议(TCP/UDP/SCTP)。
工作原理:
NetworkPolicy 本身只是规则定义,需要由支持 NetworkPolicy 的 CNI 插件来实现。
常见支持 NetworkPolicy 的 CNI:Calico、Cilium、Weave、kube-router 等。
Flannel 默认不支持 NetworkPolicy。
CNI 插件通过在节点上配置防火墙规则(iptables、eBPF 等)来实现流量控制。
示例:
yamlapiVersion: 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 还有哪些网络安全手段?