架构与组件
Kubernetes 核心组件有哪些?
- Master(控制平面):kube-apiserver(API 入口)、etcd(配置存储)、kube-scheduler(调度)、kube-controller-manager(控制器)、cloud-controller-manager(云厂商控制器,可选)。
- Node(工作节点):kubelet(Pod 生命周期)、kube-proxy(网络代理/负载均衡)、containerd(容器运行时)。
kube-apiserver 的作用? 集群统一 API 入口,所有组件通过它通信。它是唯一直接读写 etcd 的组件,负责认证(Authentication)、鉴权(Authorization)、准入控制(Admission)、校验与持久化,并提供 Watch 机制供其他组件监听资源变化。
etcd 的作用? 分布式 KV 存储,保存集群所有配置和状态数据。基于 Raft 协议保证强一致性,因此生产环境推荐 3/5 个奇数节点做高可用;它是集群的唯一真实数据源,备份 etcd 就等于备份整个集群。
kube-scheduler 如何调度 Pod?
过滤(Filtering)→ 打分(Scoring)→ 绑定(Binding)。过滤阶段剔除不满足条件的节点(资源不足、污点不容忍、端口冲突、亲和性不符);打分阶段按优先级函数(资源均衡、亲和性权重等)排序选出最优节点;最后把结果写入 Pod 的 nodeName(Binding)。调度考虑资源、亲和性、污点容忍、拓扑分布等。
kube-controller-manager 的作用? 运行一系列控制循环(Reconcile Loop),让实际状态不断逼近期望状态。常见控制器:Deployment、ReplicaSet、StatefulSet、DaemonSet、Node、Job、EndpointSlice、ServiceAccount 等。多个控制器共享同一进程以减少复杂度。
kubelet 的作用? 每个节点上的代理,负责 Pod 生命周期管理(创建、监控、销毁)。它监听 API Server 上属于自己的 Pod,通过 CRI 调用容器运行时拉起容器,并上报节点与 Pod 状态;它不管理非本节点创建的静态 Pod 之外的容器。
kube-proxy 的 iptables 和 IPVS 模式区别?
- iptables:基于规则链线性匹配,规则数量随 Service 数量增长而膨胀,适合小规模集群;随机负载均衡。
- IPVS:基于哈希表,性能高、支持 rr/wrr/lc/sh 等多种负载均衡算法与会话保持,适合大规模集群。
- 两者都只做四层转发,都从 EndpointSlice 获取后端地址。
一个 Pod 从创建到运行的完整流程?
- kubectl 提交 YAML → apiserver 认证、鉴权、准入(Mutating/Validating)→ 写入 etcd。
- controller-manager 中的 Deployment/ReplicaSet 控制器发现后创建对应的 Pod 对象。
- scheduler 监听到未绑定的 Pod,筛选节点后写入
nodeName。 - 目标节点的 kubelet watch 到该 Pod,调用 CRI 拉镜像、先跑 Init 容器、再按顺序启动业务容器;调用 CNI 分配 IP、挂载 Volume。
- kubelet 上报状态,EndpointSlice 控制器把就绪 Pod 写入 Service 后端,CoreDNS 提供域名解析。
Pod
Pod 是什么?
Kubernetes 最小调度单元,一组容器的集合,共享网络(同一 Network Namespace 与 IP)和存储(Volume),可共享 UTS/IPC。每个 Pod 都有一个 pause 容器(Infra 容器)持有网络命名空间,业务容器加入其中。
为什么 Pod 是 K8s 调度的最小单元? 调度、网络、存储和资源配额都以 Pod 为粒度:
- 网络、存储和资源配额:容器只是进程的封装,如果容器需要共享 Network/UTS/IPC 命名空间与 Volume,必须被调度到同一节点,单独调度无法保证共置。
- 调度:资源 requests/limits、QoS 等级、亲和性与污点容忍都定义在 Pod 级别(容器级别只是求和)。
- 生命周期:Pod 是原子生命周期单位,副本数、滚动更新、扩缩容的计数对象都是 Pod。
Pod 的生命周期状态有哪些?
- Pending(等待调度/拉镜像)
- Running(至少一个容器运行中)
- Succeeded(全部容器成功退出且不会重启)
- Failed(至少一个容器异常退出且不会重启)
- Unknown(与节点失联)
- 容器自身的状态则为 Waiting、Running、Terminated。
Init 容器的作用? 在主容器启动前串行执行、必须成功退出,常用于等待依赖服务就绪、初始化配置、修改数据卷权限;与普通容器不同的还有:不支持探针、不计入 QoS 计算。
Pod 与 Deployment 的区别? Pod 是单个调度单元,生命周期短暂,重启/迁移后 IP 变化;Deployment 通过 ReplicaSet 管理 Pod 副本,提供声明式副本数、滚动更新和回滚。
Pod 健康检查的探针有哪些?
三种探针:
- Liveness Probe(存活探针,失败则按 restartPolicy 重启容器)
- Readiness Probe(就绪探针,失败则从 Service 后端摘除、不转发流量)
- Startup Probe(启动探针,成功前抑制其他探针,适合慢启动应用)
实现方式:exec(执行命令)、httpGet、tcpSocket、grpc。参数有 initialDelaySeconds、periodSeconds、timeoutSeconds、failureThreshold。
讲一下Pod重启,restartPolicy 有哪些?
- 重启是重启容器而不是重建 Pod,所以 Pod IP 不变,但重启间隔会指数退避(10s→20s→40s…上限 5min),这就是 CrashLoopBackOff。
- 重启策略:Always(默认,Deployment 用)、OnFailure、Never(Job 常用)。
Pod 处于 CrashLoopBackOff / ImagePullBackOff 怎么办?
- CrashLoopBackOff:
kubectl logs --previous看上次崩溃日志,常见原因有配置错误、依赖服务不可用、探针配置过严、OOMKilled(kubectl describe pod看 Last State)。 - ImagePullBackOff:镜像名/标签错误、私有仓库缺少
imagePullSecrets、节点网络不通。 - Pending:资源不足、没有可调度节点、PVC 未绑定。
- Terminating 卡住:finalizer 未清理或节点失联。
Pod 的 QoS 等级?
- Guaranteed(所有容器都设了 requests == limits)
- Burstable(设了部分 requests,不满足 Guaranteed)
- BestEffort(完全没设)
- 节点内存不足时按 BestEffort → Burstable → Guaranteed 的顺序驱逐
Service 与网络
Service 的类型有哪些?
- ClusterIP(默认,仅集群内访问,虚拟 IP);
- NodePort(每个节点开放 30000-32767 端口映射);
- LoadBalancer(调用云厂商 LB,通常是 NodePort 的超集);
- ExternalName(CNAME/DNS 别名,不转发流量);
- 另外还有无头服务 Headless Service(
clusterIP: None,直接返回 Pod IP,供 StatefulSet 使用)。
Service 的实现原理?
Service 只是一组 iptables/IPVS 规则的抽象:apiserver 分配 ClusterIP 后,kube-proxy 监听 Service 与 EndpointSlice 变化并下发规则,把访问 ClusterIP 的流量 DNAT 到某个就绪 Pod 的 IPsvc.namespace.svc.cluster.local 解析为 ClusterIP。三层结构 = DNS 名称 → ClusterIP → Pod IP。
Ingress 是什么?与 Service 的关系? Ingress 提供集群外部到 Service 的 HTTP/HTTPS 路由规则集合(基于 Host/Path 转发、TLS 终止),本身只是一份配置,必须由 Ingress Controller(Nginx Ingress、Traefik、Higress 等)解析并生效。流量路径为:客户端 → Ingress Controller → Service → Pod。Ingress 是七层,Service 是四层。
CNI 是什么?常见实现? Container Network Interface,容器网络插件标准(负责给 Pod 分配 IP、配置路由与网卡)。常见:Flannel(Overlay 网络,VXLAN/host-gw,简单但无 NetworkPolicy)、Calico(BGP 三层网络或 IPIP,性能好且支持 NetworkPolicy)、Cilium(eBPF,性能和可观测性更强)。
K8s 如何实现负载均衡? 分层次实现:
- 四层(Service):kube-proxy 通过 iptables/IPVS 把 ClusterIP 的流量随机/轮询转发到后端 Pod,可用
sessionAffinity: ClientIP做会话保持。 - 七层(Ingress / Gateway API):按域名、路径、Header、权重做路由。
- 外部入口:LoadBalancer 类型 Service 或云厂商 SLB/Nginx 做最外层负载均衡。
- 客户端侧:无头 Service + 客户端自行负载均衡(gRPC 常用)。
Pod 之间如何通信?跨节点呢?
- 同一 Pod 内通过 localhost;
- 同节点不同 Pod 通过 CNI 创建的 veth/bridge 通信;
- 跨节点由 CNI 路由(Flannel VXLAN 封装、Calico BGP 路由)完成,要求满足 K8s 网络模型:每个 Pod 一个 IP,Pod 间可直接通信无需 NAT。
Service 访问不通怎么排查?
kubectl get endpointslices确认后端是否有就绪 Pod(没有则检查探针/标签选择器)。kubectl exec进 Pod 测nslookup与curl ClusterIP,定位是 DNS 还是转发问题。- 检查
targetPort与容器实际监听端口是否一致。 - 检查 NetworkPolicy 是否拦截流量。
存储
PV、PVC、StorageClass 的关系?
- PV(PersistentVolume):集群级存储资源,由管理员静态创建或由 provisioner 动态创建。
- PVC(PersistentVolumeClaim):用户存储申请(容量、accessMode、storageClassName),绑定到某个 PV。
- StorageClass:动态存储供给配置,声明 provisioner 与参数(如
reclaimPolicy、磁盘类型),PVC 引用它即可自动创建 PV。
访问模式 accessMode 有哪些?
- ReadWriteOnce(RWO,单节点读写,最常见)
- ReadOnlyMany(ROX)
- ReadWriteMany(RWX,需 NFS/CephFS 等支持)
- ReadWriteOncePod
- 回收策略有 Retain / Delete / Recycle
PVC 处于 Pending 状态的可能原因? 没有匹配的 PV(容量 / accessMode / storageClassName / 标签选择器不匹配);StorageClass 不存在或 provisioner 故障;WaitForFirstConsumer 模式下还没有 Pod 使用它。
如何配置持久化存储?
三步:创建 StorageClass(或管理员静态建 PV)→ 创建 PVC 申请 → Pod 通过 volumes 引用 PVC。
apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: fastprovisioner: kubernetes.io/aws-ebs # 或 csi 驱动reclaimPolicy: DeletevolumeBindingMode: WaitForFirstConsumer---apiVersion: v1kind: PersistentVolumeClaimmetadata: name: dataspec: storageClassName: fast accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi---apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: dataemptyDir、hostPath 与 PVC 的区别? emptyDir 生命周期与 Pod 相同(Pod 删除即清空),适合缓存与容器间共享;hostPath 挂载宿主机目录,Pod 漂移后数据仍在但强绑定节点,仅适合特殊场景(日志采集);PVC 才是真正的持久化、与 Pod 解耦的存储。
配置与安全
ConfigMap 和 Secret 的区别?
ConfigMap 存明文非敏感配置;Secret 存敏感信息,值以 base64 编码存储(并非加密),可限制为 type: Opaque 或 dockerconfigjson 等。使用时都可以通过环境变量或 Volume 挂载注入。
注意:base64 是可逆编码不是加密,要真正安全需开启 etcd 静态加密、RBAC 限制读取、或使用外部密钥管理(Vault/KMS)。
更新 ConfigMap/Secret 后 Pod 会立即生效吗?
环境变量方式注入的不会生效,必须重建 Pod(Deployment 可用 kubectl rollout restart);以 Volume 挂载方式的最终会更新(kubelet 周期同步,约 1 分钟),但应用需自行 reload。
RBAC 中 Role 和 ClusterRole 的区别? Role 作用于单个 Namespace;ClusterRole 作用于整个集群(或用于跨 Namespace 复用与集群级资源如 Node、PV)。通过 RoleBinding 绑定 Role/ClusterRole(限定在某 Namespace),通过 ClusterRoleBinding 绑定 ClusterRole(全集群生效)。RBAC 是纯允许模型,没有拒绝规则。
ServiceAccount 的作用?
Pod 访问 API Server 时的身份标识,未指定则使用 default。Token 会自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount,配合 RoleBinding 即可实现 Pod 级别最小权限。
Pod 安全限制有哪些手段? SecurityContext(runAsUser、readOnlyRootFilesystem、capabilities、privileged)、Pod Security Admission(baseline/restricted)、NetworkPolicy(网络隔离)、ResourceQuota/LimitRange(资源约束)。
高级资源
StatefulSet 和 Deployment 的区别?
- Deployment 用于无状态应用,Pod 完全等价、可随意替换;
- StatefulSet 用于有状态应用,常用于数据库、消息队列、ZooKeeper 等,提供:
- 稳定的网络标识(
pod-name-0.svc依赖 Headless Service) - 稳定的独立存储(volumeClaimTemplates)
- 有序的创建/删除/滚动(0→N创建,逆序删除)
- 稳定的网络标识(
DaemonSet 的典型应用场景? 每个(或指定的)节点运行一个 Pod,如日志收集(Fluentd/Filebeat)、节点监控(Node Exporter)、CNI 组件、kube-proxy。新节点加入时会自动部署。
HPA 是什么?
Horizontal Pod Autoscaler,基于 CPU/内存或自定义指标自动扩缩容 Pod 副本数。默认每 15s 采集一次指标(依赖 Metrics Server),按 期望副本数 = 当前副本数 × 当前指标 / 目标指标 计算并受 tolerance 与扩缩容冷却时间限制。配套还有 VPA(垂直调资源)与 Cluster Autoscaler(扩节点)。
Job 和 CronJob 的区别? Job 运行一次性任务直到成功(可设 completions/parallelism、backoffLimit);CronJob 按 cron 表达式周期性创建 Job,支持 concurrencyPolicy 与历史保留数。
如何限制 Pod 资源使用?
在 Pod 的 resources 字段定义 requests(调度依据,保证下限)和 limits(运行时上限,超出内存会被 OOMKilled、超出 CPU 会被限流)。命名空间级别可用 LimitRange 设默认值与上下限,用 ResourceQuota 限制总量。
节点亲和性与污点容忍的区别?
- 亲和性是 Pod 主动选择节点(吸引,支持 requiredDuringScheduling 硬性 与 preferredDuringScheduling 软性、nodeAffinity/podAffinity/podAntiAffinity);
- 污点容忍是 Pod 被动适应节点(排斥),节点打污点排斥 Pod,Pod 加容忍才能调度上去。污点效果有 NoSchedule、PreferNoSchedule、NoExecute(NoExecute 还会驱逐不容忍的存量 Pod)。
包管理
Helm
Helm 是什么? Kubernetes 的包管理器,把一组 YAML 抽象成可参数化、可版本化、可复用的 Chart。三个核心概念:Chart(模板包)、Release(Chart 的一次部署实例)、Repository(Chart 仓库)。
常用命令?
helm repo add bitnami https://charts.bitnami.com/bitnamihelm search repo nginxhelm install my-nginx bitnami/nginx -n web --create-namespace -f values.yamlhelm upgrade my-nginx bitnami/nginx --set replicaCount=3helm rollback my-nginx 1 # 回滚到指定 revisionhelm history my-nginxhelm uninstall my-nginx -n webhelm template ./chart # 本地渲染,不部署Helm 的目录结构?
Chart.yaml(元数据)、values.yaml(默认值)、templates/(Go Template 模板 YAML)、charts/(子 Chart 依赖)。升级/回滚依赖 release 的 revision 记录(存在 Secret 中)。
kustomize
kustomize 是什么?
K8s 原生命令(kubectl apply -k)的配置定制工具。不用模板,而是通过 base + overlay 的叠加(patch)方式复用同一份基础 YAML,适配不同环境。
典型目录结构?
base/ kustomization.yaml # resources: [deployment.yaml, service.yaml] deployment.yamloverlays/ dev/kustomization.yaml # resources: [../../base]; replicas/patch 覆盖 prod/kustomization.yamlkustomize 常用能力?
resources 引入基础资源、patchesStrategicMerge/patches 覆盖字段、replicas 改副本数、images 改镜像 tag、namePrefix/commonLabels 统一前缀与标签、configMapGenerator 自动生成配置并触发滚动更新。
Helm 与 kustomize 怎么选? Helm 适合对外分发、需要参数化与版本管理的场景;kustomize 适合内部多环境、以 patch 为主、不想维护模板语法的场景。两者常组合使用(Helm 渲染 base + kustomize 做 overlay patch)。
更新与发布
什么是滚动更新?如何实现滚动更新与回滚?(命令) 滚动更新(RollingUpdate)是 Deployment 的默认策略:新建一个 ReplicaSet,逐步增加新 Pod 副本、同时减少旧 Pod 副本,过程中始终有可用实例,实现零中断发布。
kubectl set image deploy/app app=nginx:1.25 # 触发更新kubectl rollout status deploy/app # 观察进度kubectl rollout history deploy/app # 查看历史版本kubectl rollout undo deploy/app --to-revision=2 # 回滚kubectl rollout pause/resume deploy/app # 暂停/继续滚动更新涉及哪些组件?如何控制?
链路是 Deployment → ReplicaSet → Pod:Deployment 控制器发现 Pod 模板变更后创建新的 ReplicaSet 并扩缩两个 RS 的副本数,kubelet 负责实际起停容器。控制参数在 strategy.rollingUpdate:
maxSurge:更新过程中最多超出期望副本数的 Pod 数(默认 25%);maxUnavailable:最多不可用的 Pod 数(默认 25%,设为 0 即”先扩后缩”的零中断更新);minReadySeconds:Pod 就绪后多久才认为可用;progressDeadlineSeconds:超时未完成则标记为失败。 滚动更新不丢请求的前提是配置了 Readiness 探针与优雅退出(preStop + terminationGracePeriodSeconds)。
什么是 Recreate 策略?
Recreate 是一种用于更新应用的 Deployment 策略。它通过先终止所有旧的 Pod,再创建新的 Pod来完成更新。存在停机时间。适合不能同时运行多个版本的应用(如数据库迁移)。
什么是灰度发布 / 金丝雀发布?如何实现? 灰度(金丝雀)发布指先让一小部分流量进入新版本,观察指标正常后再逐步放量到 100%。实现方式:
- 副本比例:新旧两个 Deployment 共用同一个 Service 的标签,靠调节副本数比例分流(最粗糙,比例受 Pod 数限制)。
- Ingress 注解:Nginx Ingress 的
nginx.ingress.kubernetes.io/canary: "true"+canary-weight: 10/ canary-by-header 精确切流。 - 服务网格:Istio VirtualService 按权重/Header/用户维度切流,粒度最细。
- 渐进式交付工具:Argo Rollouts、Flagger,支持自动分析指标并自动回滚。
滚动更新、蓝绿、金丝雀的区别?
- 滚动更新:逐个替换实例,资源占用小,回滚快,但新旧版本会短暂共存。
- 蓝绿发布:同时部署完整的新旧两套环境,切流量即完成发布/回滚,需要双倍资源,回滚最快。
- 金丝雀发布:按比例放量,风险最小,需要完善的监控与流量控制能力。
其他
K8s 为何要关闭 Swap?
- 资源确定性被破坏:K8s 依赖 cgroups 严格限制 Pod 的内存上限(limits)。如果开启 Swap,Pod 写数据可能被换出到磁盘,导致
cgroups统计的内存使用量不准确,容器无法精准判断自己是否达到内存限制。 - 性能不可控:Swap 依赖磁盘 I/O,速度比内存慢几个数量级。一旦发生大量换页,Pod 响应延迟会急剧飙升,且这种抖动毫无预兆,破坏了 Kubernetes 承诺的 服务质量(QoS)。
- 调度误判:Kubelet 根据节点上的内存容量进行 Pod 调度,如果 Swap 被占用,实际可用内存被稀释,容易产生节点资源枯竭但调度器不知情的情况。
K8s 节点上只有 containerd 而没有 Docker,如何构建镜像? Docker 和 containerd 都是运行时,构建镜像需要单独的构建器:
- nerdctl + BuildKit:
nerdctl是兼容 Docker CLI 的 containerd 客户端,nerdctl build依赖buildkitd(需单独部署,buildkitd --oci-worker-no-process-sandbox),也支持nerdctl compose。 - buildctl + buildkitd:直接用 BuildKit 原生客户端,支持多平台构建与缓存导入导出。
- 在集群内构建:Kaniko(无需特权,在 Pod 内构建)、Buildpacks、或 Tekton/Argo Workflows 流水线。
- 生产实践通常是 CI 里用 Docker/BuildKit 构建并推送镜像,节点只负责拉取运行。
K8s 与 Docker 的关系? Docker 是容器技术的早期实现(CLI + daemon + 运行时 + 镜像格式);K8s 是容器编排系统。早期 K8s 通过 dockershim 调用 Docker,1.24 起移除 dockershim,直接使用 CRI 对接 containerd/CRI-O,因此“K8s 弃用 Docker”弃用的是 dockershim 这层适配,镜像(OCI 标准)依然通用。
常用排错命令?
kubectl get pod -A -o wide # 全量 Pod 与所在节点kubectl describe pod <pod> # 事件、探针、调度失败原因kubectl logs <pod> -c <container> -f # 日志(--previous 看上次崩溃)kubectl exec -it <pod> -- shkubectl top node / pod # 资源使用(依赖 metrics-server)kubectl get events --sort-by=.lastTimestampkubectl get pod <pod> -o yaml # 看最终生效的 speckubectl auth can-i get pods --as=system:serviceaccount:default:default分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 26 天
部分内容可能已过时