一、基础概念类
1. 什么是 Kubernetes?它解决了什么问题?
详细答案
Kubernetes(K8s)是开源的容器编排平台,核心解决以下问题:
- 自动化运维:自动部署、扩缩容、故障恢复
- 资源调度:高效利用集群资源(CPU/内存)
- 服务发现与负载均衡:动态管理容器间通信
- 配置与存储管理:统一管理配置和持久化存储
示例
当容器故障时,K8s自动重启或替换容器;流量激增时自动扩容Pod副本数。
拓展
前身是Google的Borg系统,现由CNCF管理。替代方案:Docker Swarm, Mesos。
2. Kubernetes 的核心组件有哪些?各自的作用是什么?
详细答案
| 组件 | 作用 |
|---|---|
| API Server | 集群操作入口,处理REST请求,更新etcd |
| etcd | 分布式键值数据库,存储集群所有状态数据 |
| Scheduler | 监听未调度Pod,根据策略分配节点(如资源需求、亲和性) |
| Controller Manager | 运行控制器(如Deployment控制器确保副本数) |
| Kubelet | 节点代理,管理Pod生命周期、容器健康检查 |
| Kube-proxy | 维护节点网络规则,实现Service的负载均衡(iptables/IPVS) |
| Container Runtime | 运行容器的引擎(如containerd、Docker) |
3. Pod 是什么?和容器有什么区别?
详细答案
- Pod:最小调度单元,包含1个或多个共享网络/存储命名空间的容器
- 区别:
- 容器是独立进程,Pod是容器的逻辑分组
- Pod内容器通过
localhost直接通信,共享Volume
示例
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25
- name: log-collector # 与nginx共享日志卷
image: busybox
command: ["sh", "-c", "tail -f /logs/access.log"]
volumeMounts:
- name: logs
mountPath: /logs
volumes:
- name: logs
emptyDir: {}
拓展
Pod设计初衷:支持紧密耦合的应用(如日志收集器+Web服务器)。
4. Deployment、ReplicaSet、StatefulSet、DaemonSet、Job、CronJob 的区别和应用场景?
详细答案
| 控制器 | 场景 | 关键特性 |
|---|---|---|
| Deployment | 无状态应用(如Web服务) | 滚动更新、回滚,管理ReplicaSet |
| ReplicaSet | 确保指定数量的Pod副本运行 | 通常由Deployment调用 |
| StatefulSet | 有状态应用(如MySQL、ZooKeeper) | 稳定网络标识、有序部署、持久存储 |
| DaemonSet | 每个节点运行一个Pod(如日志收集、监控) | 节点新增时自动部署 |
| Job | 运行一次性任务(如数据处理) | 任务完成即停止 |
| CronJob | 定时任务(如每日备份) | 基于Cron表达式调度 |
示例
# DaemonSet示例(在每个节点运行fluentd日志收集)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluentd:latest
5. Namespace 的作用是什么?
详细答案
- 资源隔离:逻辑分隔集群资源(Pod/Service等),实现多租户环境
- 权限控制:结合RBAC限制不同命名空间的访问权限
- 资源配额:通过
ResourceQuota限制命名空间的资源用量
示例
# 创建开发环境命名空间
kubectl create namespace dev
# 在dev命名空间部署应用
kubectl apply -f app.yaml -n dev
拓展
默认命名空间:default、kube-system(系统组件)、kube-public(公共资源)。
6. Service 有哪些类型?分别适用于哪些场景?
详细答案
| Service类型 | 场景 |
|---|---|
| ClusterIP | 默认类型,集群内部访问(如前端访问后端API) |
| NodePort | 通过节点IP+端口暴露服务(开发测试环境) |
| LoadBalancer | 云平台提供外部负载均衡器(生产环境公网访问) |
| ExternalName | 将服务映射到外部DNS(如访问数据库服务db.prod.com) |
| Headless | 无ClusterIP,直接返回Pod IP(StatefulSet需要固定网络标识) |
示例
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer # 云平台自动创建负载均衡器
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 8080
7. ConfigMap 与 Secret 的区别和使用方法?
详细答案
| 特性 | ConfigMap | Secret |
|---|---|---|
| 数据类型 | 普通配置(如JSON、环境变量) | 敏感数据(密码、Token) |
| 存储方式 | 明文存储 | Base64编码(非加密!) |
| 使用场景 | 应用配置文件、命令行参数 | 数据库密码、TLS证书 |
| 挂载方式 | 环境变量/Volume挂载 | 同左,建议限制Secret访问权限 |
示例
# ConfigMap定义
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
log_level: "INFO" # 键值对
# Secret定义(需base64编码)
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
password: cGFzc3dvcmQxMjM= # echo -n "password123" | base64
8. K8s 中的 Label、Selector、Annotation 有什么区别?
详细答案
| 概念 | 作用 | 示例 |
|---|---|---|
| Label | 标识对象属性,用于Selector分组资源 | env: prod, app: nginx |
| Selector | 根据Label筛选资源(等值匹配/集合匹配) | matchLabels: {app: nginx} |
| Annotation | 存储非标识性元数据(构建信息、维护者),不用于对象筛选 | deployer-version: v2.1 |
示例
# Deployment使用Selector关联Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
selector:
matchLabels:
app: nginx # 选择包含此Label的Pod
template:
metadata:
labels:
app: nginx # 给Pod打Label
annotations:
build-version: "v1.2.0" # 记录构建信息
9. K8s 中的滚动更新(Rolling Update)和回滚是怎么实现的?
详细答案
- 滚动更新:
- 创建新ReplicaSet并逐步增加Pod副本
- 旧ReplicaSet同步减少副本
- 通过
maxUnavailable(最大不可用比例)和maxSurge(超出期望副本数)控制更新节奏
- 回滚:
- Deployment记录历史版本(通过
revisionHistoryLimit配置保留数量) - 执行
kubectl rollout undo deployment/<name>回退到上一版本
- Deployment记录历史版本(通过
示例
# 触发滚动更新(修改镜像版本)
kubectl set image deployment/nginx-deploy nginx=nginx:1.26
# 查看更新状态
kubectl rollout status deployment/nginx-deploy
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deploy
10. K8s 中 Ingress 是什么?它的作用是什么?
详细答案
- 是什么:管理外部HTTP/S访问集群服务的API网关层
- 作用:
- 基于域名/路径路由流量到不同Service
- 提供TLS终止(HTTPS卸载)
- 负载均衡
- 需配合Ingress Controller(如Nginx、Traefik)实现
示例
# Ingress定义(路由规则)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service # 将/appi请求转发到api-service
port:
number: 80
二、调度与网络类
11. K8s 是如何调度 Pod 的?调度流程有哪些阶段?
详细答案
Pod 调度由 kube-scheduler 完成,分为两个核心阶段:
- 过滤(Filtering/Predicate):
- 排除不满足条件的节点(如资源不足、端口冲突、节点选择器不匹配)
- 检查项:CPU/内存资源、节点亲和性、污点容忍、节点状态等
- 打分(Scoring/Priority):
- 对通过过滤的节点打分(0-10分)
- 策略:资源空闲率优先(LeastRequestedPriority)、节点亲和性权重、均衡分布(SpreadPriority)
- 绑定(Binding):
- 选择最高分节点,更新 etcd 并通知 kubelet 启动 Pod
示例
# 查看调度事件
kubectl describe pod nginx-pod | grep Events -A10
# 输出示例:
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# Normal Scheduled 5s default-scheduler Successfully assigned default/nginx-pod to node-01
拓展
自定义调度器:可通过实现调度器扩展(Scheduler Extender)或开发独立调度器(如基于 AI 的资源调度)。
12. NodeSelector、Node Affinity、Taints & Tolerations 的区别?
详细答案
| 机制 | 作用 | 特点 |
|---|---|---|
| NodeSelector | 简单节点选择(标签匹配) | 硬性要求,无则调度失败 |
| Node Affinity | 复杂节点亲和规则(支持硬性/软性要求) | requiredDuringScheduling(硬性)preferredDuringScheduling(软性) |
| Taints & Tolerations | 节点排斥 Pod(除非 Pod 声明容忍) | 用于预留节点(如 GPU 节点) |
示例
# Node Affinity + Tolerations 组合
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu-type
operator: In
values: ["a100"]
tolerations:
- key: "reserved"
operator: "Equal"
value: "ai-job"
effect: "NoSchedule"
拓展
- Taint 的三种效果:
NoSchedule(禁止调度)、PreferNoSchedule(尽量避免)、NoExecute(驱逐已有 Pod) - 典型场景:专用 GPU 节点添加污点
gpu=true:NoSchedule
13. Pod 如何限制 CPU 和内存资源?
详细答案
在容器声明中定义 resources 字段:
requests:调度依据(资源预留)limits:运行时上限- 单位:
- CPU:
1000m= 1 核(可小数,如0.5) - 内存:
512Mi(兆字节)、2Gi(千兆字节)
- CPU:
示例
spec:
containers:
- name: app
resources:
requests:
cpu: "250m" # 0.25 核
memory: "512Mi" # 512 MB
limits:
cpu: "500m" # 0.5 核
memory: "1Gi" # 1 GB
拓展
- 超限后果:
- CPU 超限 → 被限流(Throttled)
- 内存超限 → OOM Kill(容器被终止)
- 资源配额:通过
ResourceQuota限制 Namespace 总资源
14. 什么是 Pod 优先级(PriorityClass)和抢占机制?
详细答案
- PriorityClass:
- 定义 Pod 优先级(数值越大优先级越高)
- 示例:系统组件 > 关键业务 > 普通任务
- 抢占(Preemption):
- 当高优先级 Pod 无法调度时,驱逐低优先级 Pod 释放资源
- 条件:节点资源不足且无其他可用节点
示例
# 定义 PriorityClass
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical
value: 1000000 # 优先级值
globalDefault: false
# Pod 引用
spec:
priorityClassName: critical
拓展
- 风险:抢占可能导致业务中断,需谨慎使用
- 适用场景:关键系统服务(如网络插件、日志代理)
15. Kubernetes 网络模型是如何设计的?
详细答案
Kubernetes 网络模型遵循三个基本原则:
- IP-per-Pod:每个 Pod 拥有独立 IP,所有 Pod 可直接通信
- 无 NAT 通信:Pod 跨节点通信不经过 NAT
- 服务发现:Service 提供稳定虚拟 IP(ClusterIP)
网络分层:
- Pod 内容器:通过
pause容器共享网络命名空间 - Pod 间通信:由 CNI 插件实现(如 VXLAN、BGP)
- Service 网络:由 kube-proxy 通过 iptables/IPVS 实现负载均衡
拓展
与 Docker 网络区别:Docker 默认使用 NAT,K8s 要求扁平网络。
16. CNI(Container Network Interface)是什么?常见的 CNI 插件有哪些?
详细答案
- CNI:容器网络接口标准,定义网络插件规范
- 工作流程:
- kubelet 创建 Pod 时调用 CNI 插件
- 插件为 Pod 分配 IP、配置网络路由
- 常见插件:
插件 特点 适用场景 Flannel 简单易用,支持 VXLAN/host-gw 中小集群 Calico 基于 BGP,支持网络策略(NetworkPolicy) 安全要求高的环境 Cilium 基于 eBPF,高性能和可观测性 大规模/云原生环境 Weave 支持加密通信 多租户隔离环境
示例
# 查看 Calico 节点状态
calicoctl node status
CNI和service都是用于给pod创建ip的,两者有什么区别
简单来说:
- CNI(容器网络接口):负责分配 Pod 的 IP 地址,并确保 Pod 之间能够通过这个 IP 地址进行直接的网络通信(Pod-to-Pod)。这是基础网络层。
- Service:不会分配新的 Pod IP。它提供一个稳定的、虚拟的 IP 地址(ClusterIP),作为一组动态 Pod(由标签选择器决定)的前端负载均衡器和访问入口。这是服务抽象层。
为了更直观地理解它们的分工与协作,下图清晰地展示了 CNI 和 Service 在 Kubernetes 网络模型中的不同位置和职责:
让我们来详细分解一下它们的区别:
CNI (Container Network Interface)
-
核心职责:
- Pod IP 地址分配:当 Pod 被调度到一个节点上时,kubelet 会调用该节点上配置的 CNI 插件(例如 Calico、Flannel、Cilium 等)来为 Pod 分配一个在集群内唯一的 IP 地址。这就是
kubectl get pods -o wide中看到的IP列。 - 网络连通性:CNI 插件负责建立 Pod 之间的网络通信通道。这包括:
- 同一节点内 Pod 之间的通信。
- 不同节点上 Pod 之间的通信(Overlay 网络或 Underlay 网络)。
- 通常还负责 Pod 与外部网络(互联网)的通信(通过 SNAT 等)。
- Pod IP 地址分配:当 Pod 被调度到一个节点上时,kubelet 会调用该节点上配置的 CNI 插件(例如 Calico、Flannel、Cilium 等)来为 Pod 分配一个在集群内唯一的 IP 地址。这就是
-
工作层级:OSI 模型的第 3 层(网络层)和第 4 层(传输层)。它关心的是 IP 地址、路由表和网络策略(NetworkPolicy)。
-
IP 地址的性质:它分配的是真实的、可路由的(在集群内)IP 地址。Pod 之间直接 ping 通或者用
curl访问的就是这个 IP。 -
生命周期:与 Pod 的生命周期强绑定。Pod 被创建 -> CNI 分配 IP;Pod 被删除 -> CNI 释放 IP。
-
类比:CNI 就像是房地产开发商和市政部门。
- 它负责给每栋房子(Pod)分配一个唯一的物理地址(Pod IP)。
- 它负责修建道路和桥梁(网络设备/路由),确保所有房子之间可以互通。
Service
-
核心职责:
- 服务发现与负载均衡:Pod 是短暂的(ephemeral),它们可能会因为故障、滚动更新或扩缩容而随时被创建或销毁,其 IP 地址也会随之改变。Service 解决了“如何找到一个由多个动态变化的 Pod 组成的服务”的问题。它通过标签选择器(Label Selector) 动态地找到一组后端 Pod(Endpoints)。
- 提供稳定的虚拟 IP(VIP):Service 会被分配一个固定的虚拟 IP 地址,称为
ClusterIP。无论后端的 Pod 如何变化,客户端只需要记住这个稳定的ClusterIP即可访问服务。
-
工作层级:OSI 模型的第 4 层(传输层)。它主要工作在 TCP/UDP 层面,进行端口映射和负载均衡。(Ingress 则工作在更高的第 7 层 - 应用层)。
-
IP 地址的性质:它提供的是一个虚拟 IP(VIP)。这个 IP 在物理网络上并不存在,它是由
kube-proxy组件通过 iptables 或 IPVS 规则在内核中魔术般实现的。你无法 ping 通一个 Service 的 ClusterIP,但它可以接收和转发 TCP/UDP 连接。 -
生命周期:与 Pod 的生命周期解耦。Service 是独立创建和销毁的 API 对象。它的存在是为了代表一个长期存在的服务,即使后端的 Pod 全部更换了,Service 依然不变。
-
类比:Service 就像是一个公司的总机号码(虚拟 IP)。
- 公司的员工(Pod)可能会离职或新入职(IP 变化)。
- 但客户(其他 Pod)不需要关心具体是哪个员工接电话,他们只需要记住总机号码(Service IP)即可。
- 总机接线员(
kube-proxy)会根据内部规则(iptables/IPVS)将来电(网络请求)转接到当前可用的员工(Pod)分机上。
总结对比表
| 特性 | CNI (容器网络接口) | Service (服务) |
|---|---|---|
| 核心目的 | 分配 Pod IP,建立 Pod 网络 | 服务发现、负载均衡、提供稳定访问入口 |
| 分配的 IP | 真实的 Pod IP (e.g., 10.244.1.5) | 虚拟的 Service IP (ClusterIP) (e.g., 10.103.100.50) |
| 工作层级 | L3/L4 (网络/传输层) | L4 (传输层,主要 TCP/UDP) |
| 关键组件 | CNI 插件 (Calico, Flannel, Cilium) | kube-proxy, coreDNS |
| 通信对象 | Pod-to-Pod | Client-to-Service (再由 Service 到 Pod) |
| 生命周期 | 与 Pod 绑定 | 与 应用服务 绑定,独立于 Pod |
| 能否被 ping | 可以 | 通常不行 (虚拟 IP) |
| 类比 | 市政规划,分配地址 | 公司总机,提供统一号码 |
协作流程
一个典型的访问流程完美体现了二者的分工合作:
- Pod 创建:Pod 被调度到节点 NodeA。
- CNI 工作:CNI 插件(如 Calico)被调用,为 Pod 分配一个真实的 IP 地址
10.244.1.5,并设置好网络路由。 - Service 创建:管理员创建一个 Service,它通过标签选择器
app=my-app定位到上一步创建的 Pod。 - kube-proxy 工作:
kube-proxy监听到 Service 和 Pod 的变化,在所有节点上配置 iptables 规则,规则是:“所有发往虚拟 IP10.103.100.50:80的流量,立刻转发到真实 Pod IP10.244.1.5:9376上”。 - 客户端访问:另一个 Pod 想要访问
my-app服务,它直接向稳定的 Service 地址http://10.103.100.50:80发起请求。 - 网络流转:请求被本机的
kube-proxy设置的 iptables 规则拦截并转发,最终通过 CNI 构建的网络通路到达目标 Pod10.244.1.5:9376。
结论:CNI 打下了让 Pod 能互通的地基,而 Service 是在这个地基之上修建了一个方便的交通枢纽和指路牌。 两者相辅相成,共同构成了 Kubernetes 强大的网络模型。
17. ClusterIP、NodePort、LoadBalancer、ExternalName 的区别?
详细答案
| 类型 | 访问方式 | 典型场景 |
|---|---|---|
| ClusterIP | 集群内部 IP(默认类型) | 服务间内部通信(如前端调后端) |
| NodePort | <节点IP>:<30000-32767> 端口 | 开发测试环境临时访问 |
| LoadBalancer | 云厂商负载均衡器的公网 IP | 生产环境公网暴露服务 |
| ExternalName | 返回 CNAME 记录(指向外部服务) | 集成集群外服务(如云数据库) |
| Headless | 无 ClusterIP,直接返回 Pod IP | StatefulSet 需要稳定 DNS 的场景 |
示例
# Headless Service(用于 StatefulSet)
apiVersion: v1
kind: Service
metadata:
name: cassandra
spec:
clusterIP: None # Headless 模式
ports:
- port: 9042
selector:
app: cassandra
18. K8s 中 DNS 是如何工作的?
详细答案
- 核心组件:CoreDNS(替代 kube-dns)
- 域名解析规则:
- Service:
<service>.<ns>.svc.cluster.local→ ClusterIP - Pod:
<pod-ip>.<ns>.pod.cluster.local(需启用 Pod DNS 记录)
- Service:
- 解析流程:
- Pod 查询
nginx-service.default.svc.cluster.local - 请求发送到 CoreDNS(监听
10.96.0.10:53) - CoreDNS 返回 Service 对应的 ClusterIP
- Pod 查询
示例
# 在 Pod 内测试 DNS
kubectl exec -it busybox -- nslookup kubernetes.default
# 输出示例:
# Server: 10.96.0.10
# Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
# Name: kubernetes.default
# Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
拓展
自定义 DNS:修改 coredns ConfigMap 添加私有域名解析。
19. K8s 中如何实现跨 Namespace 的服务访问?
详细答案
通过 全限定域名(FQDN) 访问:
<service-name>.<namespace>.svc.cluster.local
- 原理:CoreDNS 根据命名空间解析 Service
- 权限控制:结合 NetworkPolicy 限制跨 Namespace 访问
示例
# 从 dev 命名空间访问 prod 的 MySQL
mysql.connect("mysql.prod.svc.cluster.local:3306")
拓展
简化访问:在 Pod 的 /etc/resolv.conf 中设置搜索域(search svc.cluster.local),允许短名称访问(如 mysql.prod)。
20. 什么是 NetworkPolicy?如何实现 Pod 之间的网络隔离?
详细答案
- NetworkPolicy:定义 Pod 网络流量的防火墙规则
- 核心元素:
podSelector:应用策略的目标 PodpolicyTypes:规则类型(Ingress/Egress)ingress/egress:允许的入站/出站流量规则
- 前提:需支持 NetworkPolicy 的 CNI 插件(如 Calico、Cilium)
示例
# 禁止 default 命名空间所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {} # 选择所有 Pod
policyTypes: ["Ingress"]
ingress: [] # 空规则 = 拒绝所有入站
# 允许带标签 role=frontend 的 Pod 访问 role=db 的 Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-db-access
spec:
podSelector:
matchLabels:
role: db
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- port: 5432 # PostgreSQL 端口
拓展
- 默认策略:未配置 NetworkPolicy 时,CNI 插件通常允许所有流量
- 多层防御:结合 Namespace 隔离 + Service Account 权限控制
三、存储与数据管理类
21. Volume、PersistentVolume(PV)、PersistentVolumeClaim(PVC)的区别?
详细答案
| 概念 | 角色 | 生命周期 |
|---|---|---|
| Volume | Pod 挂载的存储声明(临时/持久) | 随 Pod 销毁 |
| PersistentVolume (PV) | 集群级存储资源(如 NFS 卷、云磁盘) | 独立于 Pod 存在 |
| PersistentVolumeClaim (PVC) | 用户存储请求(指定大小/访问模式) | 绑定到 PV 后持久存在 |
工作流程:
- 管理员创建 PV(物理存储的抽象)
- 用户创建 PVC(存储需求声明)
- Kubernetes 将 PVC 绑定到匹配的 PV
- Pod 挂载 PVC 使用存储
示例:
# PV 定义(NFS 存储)
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.0.0.1
path: "/data"
# PVC 定义
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # 请求小于 PV 的 10Gi
# Pod 挂载 PVC
spec:
containers:
volumeMounts:
- name: data
mountPath: /var/data
volumes:
- name: data
persistentVolumeClaim:
claimName: app-pvc
22. 什么是 StorageClass?动态供给(Dynamic Provisioning)是怎么实现的?
详细答案
- StorageClass:存储类抽象,定义动态创建 PV 的模板
- 动态供给流程:
- 用户创建 PVC(指定 StorageClass)
- StorageClass 控制器调用 CSI 驱动
- CSI 驱动自动创建存储资源(如 AWS EBS)
- 创建 PV 并绑定到 PVC
优势:
- 按需自动创建存储,无需管理员手动预配 PV
- 支持存储特性参数(如磁盘类型、IOPS)
示例:
# StorageClass 定义(AWS EBS)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ebs
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "10000"
throughput: "250"
# PVC 使用 StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
storageClassName: fast-ebs # 触发动态供给
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
23. EmptyDir、HostPath、NFS、Ceph、GlusterFS、CSI 的区别?
详细答案
| 存储类型 | 特点 | 适用场景 |
|---|---|---|
| EmptyDir | Pod 临时存储(内存/磁盘),随 Pod 删除 | 缓存、临时文件 |
| HostPath | 挂载节点本地目录(慎用!) | 单节点开发测试 |
| NFS | 网络文件共享 | 多 Pod 共享读/写 |
| Ceph | 分布式存储系统(RBD/CEPHFS) | 生产环境持久化存储 |
| GlusterFS | 分布式文件系统 | 大规模文件共享 |
| CSI | 容器存储接口标准(对接云存储/企业存储) | 云环境或混合云 |
示例:
# EmptyDir 示例(内存介质)
volumes:
- name: cache
emptyDir:
medium: Memory # 使用内存而非磁盘
24. StatefulSet 中如何保证数据持久化?
详细答案
StatefulSet 通过以下机制保证有状态应用数据持久化:
- 稳定网络标识:
- Pod 名称固定(
<statefulset-name>-<ordinal>) - DNS 解析稳定(
pod-0.nginx.default.svc.cluster.local)
- Pod 名称固定(
- 专属 PVC 模板:
- 每个 Pod 自动创建独立 PVC
- PVC 命名规则:
<volumeClaimTemplate-name>-<pod-name>
- 有序部署:
- Pod 按顺序创建(0→1→2),确保主从初始化顺序
示例:
# StatefulSet 定义(MySQL 集群)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-hs # Headless Service
replicas: 3
template:
spec:
containers:
- name: mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates: # 每个 Pod 创建独立 PVC
- metadata:
name: data
spec:
storageClassName: fast-ebs
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi
25. PVC 绑定策略(Binding Mode)有哪些?
详细答案
| 绑定模式 | 行为 |
|---|---|
| Immediate | PVC 创建后立即绑定 PV(默认) |
| WaitForFirstConsumer | 延迟绑定,直到 Pod 使用 PVC 时才绑定 PV |
WaitForFirstConsumer 优势:
- 解决跨可用区绑定问题(如 AWS EBS 不能跨 AZ)
- 调度器根据 Pod 需求选择合适节点的 PV
示例:
# StorageClass 配置延迟绑定
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: delayed-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer # 关键配置
26. 如何在 Pod 中挂载多个 PVC?
详细答案
在 Pod 的 volumes 中声明多个 PVC,然后在容器内挂载到不同路径:
示例:
spec:
containers:
- name: app
volumeMounts:
- name: config-data # 配置存储
mountPath: /etc/config
- name: app-data # 应用数据存储
mountPath: /var/data
volumes:
- name: config-data
persistentVolumeClaim:
claimName: config-pvc
- name: app-data
persistentVolumeClaim:
claimName: data-pvc
拓展:
- 每个 PVC 必须已绑定到 PV
- 支持不同存储类型组合(如 SSD + HDD)
27. ConfigMap、Secret 如何挂载到 Pod 中?
详细答案
两种挂载方式:
- 环境变量注入:
env: - name: LOG_LEVEL valueFrom: configMapKeyRef: name: app-config key: log_level - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password - Volume 挂载:
volumes: - name: config-vol configMap: name: app-config # 整个 ConfigMap 挂载 - name: secret-vol secret: secretName: db-secret containers: - volumeMounts: - name: config-vol mountPath: /etc/config - name: secret-vol mountPath: /etc/secrets readOnly: true
关键区别:
- 环境变量:适合少量数据,更新需重启 Pod
- Volume 挂载:支持热更新(约 1-2 分钟同步延迟)
28. K8s 中如何实现数据库等有状态服务的高可用?
详细答案
核心方案:
- StatefulSet + Headless Service:
- 提供稳定网络标识(Pod 名称、DNS 记录)
- 持久化存储:
- 每个实例使用独立 PVC(避免单点故障)
- 存储后端需高可用(如 Ceph、云厂商多可用区磁盘)
- 集群配置:
- 主从复制(如 MySQL Group Replication)
- 使用 InitContainer 初始化集群关系
- 探针保障:
livenessProbe/readinessProbe检测数据库状态
- 备份恢复:
- 定时备份到对象存储(如 MinIO)
- 使用 Velero 实现灾难恢复
示例架构(MySQL 高可用):
四、集群管理与运维类
29. 如何查看 Pod 启动失败的原因?
详细答案
排查步骤:
- 检查 Pod 状态:
kubectl get pods -o wide - 查看事件日志:
kubectl describe pod <pod-name>(重点关注Events部分) - 查看容器日志:
- 运行中容器:
kubectl logs <pod-name> - 崩溃容器:
kubectl logs <pod-name> --previous
- 运行中容器:
- 进入容器调试:
kubectl exec -it <pod-name> -- sh
常见原因:
- 镜像拉取失败(ImagePullBackOff)
- 资源不足(Pending)
- 启动命令错误(CrashLoopBackOff)
- 健康检查失败
示例:
# 查看 Pod 事件
kubectl describe pod nginx | grep Events -A20
# 输出示例:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m10s default-scheduler Successfully assigned default/nginx to node-1
Warning Failed 1m45s kubelet Failed to pull image "nginx:invalid-tag": rpc error: code = Unknown desc = failed to pull and unpack image...
30. Pod 处于 CrashLoopBackOff、ImagePullBackOff、Pending 状态分别怎么排查?
详细答案
| 状态 | 排查步骤 | 常见原因 |
|---|---|---|
| CrashLoopBackOff | 1. kubectl logs --previous2. 检查启动命令/参数 3. 验证配置文件/依赖 | 应用崩溃、启动脚本错误、OOM |
| ImagePullBackOff | 1. kubectl describe pod 查看镜像名称2. 检查镜像仓库权限 3. 网络连通性 | 镜像不存在、认证失败、网络问题 |
| Pending | 1. kubectl describe pod 查看调度失败原因2. 检查节点资源 3. 检查 PVC 绑定 | 资源不足、节点亲和性不匹配、PV 不可用 |
示例(ImagePullBackOff):
# 查看镜像拉取错误详情
kubectl describe pod web-app | grep -i "failed to pull"
# 输出示例:
Warning Failed 11s (x4 over 77s) kubelet Failed to pull image "private-registry.com/app:v1":
rpc error: code = Unknown desc = failed to pull and unpack image: failed to resolve reference
"private-registry.com/app:v1": pull access denied, repository does not exist or may require authorization
31. 如何进行 Pod 的日志查看和实时监控?
详细答案
日志查看:
- 单 Pod:
kubectl logs -f <pod-name>(-f实时跟踪) - 多容器 Pod:
kubectl logs -f <pod-name> -c <container-name> - 标签筛选:
kubectl logs -l app=nginx
实时监控:
- 资源监控:
kubectl top pods(需安装 metrics-server)kubectl top nodes
- 事件流监控:
kubectl get events --watch - 可视化工具:
- Prometheus + Grafana(指标监控)
- EFK Stack(日志收集:Elasticsearch+Fluentd+Kibana)
示例:
# 实时查看日志(带时间戳)
kubectl logs -f nginx --timestamps
# 监控 CPU/Memory 使用
kubectl top pods --sort-by=cpu
32. kubectl 常用命令有哪些?
详细答案
| 类别 | 命令示例 | 作用 |
|---|---|---|
| 基础操作 | kubectl get pods | 查看资源列表 |
kubectl describe pod <name> | 查看资源详情 | |
kubectl create -f deploy.yaml | 通过文件创建资源 | |
kubectl apply -f deploy.yaml | 声明式配置更新 | |
| 调试 | kubectl exec -it <pod> -- sh | 进入容器 |
kubectl logs <pod> | 查看日志 | |
kubectl port-forward svc/nginx 8080:80 | 端口转发 | |
| 部署管理 | kubectl rollout status deploy/nginx | 查看部署状态 |
kubectl rollout undo deploy/nginx | 回滚部署 | |
kubectl scale deploy/nginx --replicas=5 | 扩缩容 | |
| 配置 | kubectl config use-context prod-cluster | 切换集群上下文 |
kubectl get configmap <name> -o yaml | 导出 ConfigMap |
33. 如何升级 Kubernetes 集群?
详细答案
升级原则:
- 版本跨度不超过 1 个次版本(如 1.24 → 1.25)
- 先升级控制平面,再升级工作节点
步骤:
- 备份:
etcd和关键资源(使用 Velero) - 升级控制平面:
- 升级
kubeadm:apt-get upgrade kubeadm - 执行升级计划:
kubeadm upgrade plan - 升级 Master:
kubeadm upgrade apply v1.25.0
- 升级
- 升级节点:
- 驱逐节点:
kubectl drain <node> --ignore-daemonsets - 升级组件:
apt-get upgrade kubelet kubectl - 重启:
systemctl restart kubelet - 取消驱逐:
kubectl uncordon <node>
- 驱逐节点:
验证:kubectl get nodes 查看版本状态
34. 如何在不影响业务的情况下升级应用?
详细答案
核心策略:
- 滚动更新(RollingUpdate):
- Deployment 默认策略
- 逐步替换旧 Pod,通过
maxUnavailable控制影响
- 蓝绿部署:
- 同时运行新旧版本,通过 Service 切换流量
- 需要双倍资源,零宕机
- 金丝雀发布:
- 逐步将流量导入新版本(如 5% → 50% → 100%)
- 通过 Ingress 或服务网格(Istio)实现
示例(金丝雀发布):
# Ingress-Nginx 金丝雀配置
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10%" # 10% 流量到新版本
35. K8s 中如何实现蓝绿部署、金丝雀发布?
详细答案
| 策略 | 实现方式 | 工具 |
|---|---|---|
| 蓝绿部署 | 1. 部署 v2 版本并测试 2. 切换 Service 的 selector 到 v2 标签 3. 删除 v1 资源 | kubectl、Argo Rollouts |
| 金丝雀发布 | 1. 部署少量 v2 Pod 2. 通过 Ingress/ServiceMesh 分流部分流量 3. 监控指标后逐步扩大 | Istio、Ingress-Nginx |
示例(蓝绿部署):
# 步骤1:部署 v2(标签 app: nginx, version: v2)
kubectl apply -f nginx-v2.yaml
# 步骤2:切换 Service
kubectl patch svc nginx -p '{"spec":{"selector":{"version":"v2"}}}'
36. 什么是 Helm?它解决了什么问题?
详细答案
- Helm:Kubernetes 包管理工具
- 核心概念:
Chart:应用模板(包含 YAML 文件和参数化配置)Release:Chart 的运行时实例
- 解决的问题:
- 复杂应用一键部署(如含 20+ 资源的 Kafka 集群)
- 版本管理和回滚(
helm rollback) - 参数化配置(通过
values.yaml定制)
示例:
# 安装 MySQL Chart
helm install my-mysql bitnami/mysql -f custom-values.yaml
# 查看发布
helm list
37. K8s 如何做集群备份与恢复(etcd 备份)?
详细答案
etcd 备份步骤:
- 手动备份:
# 在 Master 节点执行 ETCDCTL_API=3 etcdctl snapshot save snapshot.db \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key - 自动备份:配置 CronJob 定期执行备份
- 恢复步骤:
- 停止 kube-apiserver
- 执行
etcdctl snapshot restore - 重启 etcd 和 kube-apiserver
拓展:
- 全集群备份工具:Velero(备份 PV、资源定义)
38. 如何定位和解决集群性能问题?
详细答案
排查流程:
- 节点级:
kubectl top nodes→ 定位高负载节点kubectl describe node→ 检查资源分配/事件
- Pod 级:
kubectl top pods→ 定位异常 Pod- 分析日志/资源限制
- 组件级:
kube-apiserver:监控请求延迟(kubectl get --raw /metrics)etcd:检查写入延迟(etcdctl check perf)
- 网络:
- 测试 Pod 间带宽:
iperf3 - 检查 CNI 插件日志
- 测试 Pod 间带宽:
优化方案:
- 调整 kubelet 参数(
--max-pods) - 启用 etcd 压缩(
auto-compaction-retention) - 使用节点亲和性分散负载
工具:
- Prometheus 警报规则
kubectl debug(节点故障排查)
五、安全与权限管理类
39. Kubernetes 的 RBAC 是什么?如何配置?
详细答案
RBAC(Role-Based Access Control)是基于角色的访问控制机制,核心组件:
- Role/ClusterRole:定义权限规则(能操作哪些资源)
- Role:命名空间级别
- ClusterRole:集群级别
- RoleBinding/ClusterRoleBinding:将角色绑定到主体(用户/组/ServiceAccount)
配置步骤:
- 创建 Role/ClusterRole
- 创建 RoleBinding/ClusterRoleBinding
- 验证权限
示例:
# 创建 Role(允许在 default 命名空间操作 Pod)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-manager
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "create", "delete"]
---
# 绑定 Role 到用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-manager-binding
namespace: default
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-manager
apiGroup: rbac.authorization.k8s.io
拓展:
- 权限检查:
kubectl auth can-i delete pods --as=dev-user - 最佳实践:遵循最小权限原则
40. ServiceAccount 是什么?和用户权限的关系是什么?
详细答案
- ServiceAccount:为 Pod 中运行的进程提供身份标识
- 与用户权限的区别:
主体 适用场景 管理方式 User Account 真实用户(如管理员) 由外部身份提供商管理 ServiceAccount Pod 内的应用或服务 由 Kubernetes API 管理
关键点:
- 每个命名空间有默认 SA:
default - Pod 通过
spec.serviceAccountName指定 SA - SA 绑定 RBAC 角色后,Pod 才能访问集群资源
示例:
# 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: monitoring-sa
---
# 将 ClusterRole 绑定到 SA
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: monitoring-crb
subjects:
- kind: ServiceAccount
name: monitoring-sa
namespace: default
roleRef:
kind: ClusterRole
name: view # 预置只读角色
apiGroup: rbac.authorization.k8s.io
41. PodSecurityPolicy(PSP)和 Pod Security Standards(PSS)的区别?
详细答案
| 项目 | PodSecurityPolicy(PSP) | Pod Security Standards(PSS) |
|---|---|---|
| 状态 | 已废弃(K8s v1.21+) | 正式标准(K8s v1.23+) |
| 实现方式 | 准入控制器插件 | 内置准入控制器(PodSecurity) |
| 策略定义 | 通过 PSP 资源对象 | 通过命名空间标签或 Pod 安全准入控制 |
| 策略级别 | Privileged/Baseline/Restricted | 同左 |
PSS 使用示例:
# 在命名空间启用基线策略
apiVersion: v1
kind: Namespace
metadata:
name: secure-ns
labels:
pod-security.kubernetes.io/enforce: baseline
策略对比:
- Privileged:无限制(不安全)
- Baseline:禁止已知危险配置(如 hostNetwork)
- Restricted:最严格(强制非 root 用户运行)
42. 如何限制容器的权限(如 root 用户运行)?
详细答案
通过 Pod/Container 的 securityContext 配置:
securityContext:
runAsNonRoot: true # 必须非 root 运行
runAsUser: 1000 # 指定用户 ID
runAsGroup: 3000 # 指定组 ID
capabilities:
drop: ["ALL"] # 移除所有 Linux Capabilities
seccompProfile:
type: RuntimeDefault # 启用 seccomp 沙箱
完整示例:
apiVersion: v1
kind: Pod
metadata:
name: security-demo
spec:
containers:
- name: sec-ctx-demo
image: nginx
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
拓展:
- 使用 Open Policy Agent (OPA) 实现更细粒度的策略控制
43. Secret 的加密存储方式有哪些?
详细答案
- 静态加密(etcd 加密):
- 配置
EncryptionConfiguration - 支持 AES-CBC、AES-GCM 等算法
- 配置
- KMS 插件:
- 集成云厂商 KMS(如 AWS KMS, Google Cloud KMS)
- 外部 Secret 管理:
- HashiCorp Vault
- SealedSecrets(Bitnami)
加密配置示例:
# EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-key> # 32字节密钥
- identity: {} # 允许未加密读取(过渡期)
SealedSecret 使用:
# 加密 Secret
kubeseal < secret.yaml > sealed-secret.yaml
44. NetworkPolicy 如何做安全防护?
详细答案
NetworkPolicy 实现 Pod 网络隔离:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-isolation
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 5432 # PostgreSQL
安全能力:
- 基于标签的流量控制
- 命名空间隔离
- IP 段限制
- 端口级控制
前提条件:
- 需支持 NetworkPolicy 的 CNI 插件(Calico/Cilium)
45. API Server 如何做访问控制和认证?
详细答案
认证(Authentication):
| 方式 | 描述 |
|---|---|
| X.509 证书 | 客户端证书认证(TLS 双向认证) |
| Bearer Token | ServiceAccount 的 JWT Token |
| Webhook | 对接外部认证服务(如 OIDC) |
授权(Authorization):
- RBAC(推荐)
- Node(节点授权)
- ABAC(基于属性,已淘汰)
配置示例(OIDC):
# API Server 启动参数
--oidc-issuer-url=https://oidc.provider.com
--oidc-client-id=kubernetes
--oidc-username-claim=email
访问流程图:
拓展:
- 审计日志:记录所有 API 操作
- Webhook 准入控制器:实现自定义策略
六、进阶与高可用架构类
46. Kubernetes 的 Master 节点是如何高可用的?
详细答案
Master 节点高可用通过以下机制实现:
- 多节点冗余:
- 部署至少 3 个 Master 节点(满足 etcd 的 RAFT 多数存活要求)
- 负载均衡器:
- 外部负载均衡器(如 HAProxy/Nginx)分发 API Server 请求
- 组件高可用:
kube-apiserver:无状态,所有节点同时运行kube-controller-manager/kube-scheduler:Leader 选举机制(--leader-elect=true)
- etcd 集群:
- 独立部署或与 Master 节点共存
- RAFT 协议保证数据一致性
- 持久化存储:
- etcd 数据存储在高可用共享存储(如云磁盘)
架构示例:
最佳实践:
- 跨可用区部署
- 定期 etcd 快照备份
- 使用
kube-vip实现控制平面 VIP
47. etcd 的作用是什么?如何保证 etcd 数据的安全性和高可用性?
详细答案
- 作用:分布式键值存储,保存 Kubernetes 集群所有状态数据
- 安全性与高可用保障:
- 集群部署:至少 3 节点(奇数个),跨物理机/可用区
- 数据持久化:
- WAL(Write-Ahead Log)日志
- 定期快照(Snapshot)
- 访问安全:
- TLS 双向认证
- 基于角色的访问控制(RBAC)
- 备份恢复:
# 备份 ETCDCTL_API=3 etcdctl snapshot save snapshot.db # 恢复 etcdctl snapshot restore snapshot.db --data-dir=/new/etcd/data - 加密:静态数据加密(KMS 集成)
监控指标:
etcd_server_has_leader(是否有 leader)etcd_disk_wal_fsync_duration_seconds(写入延迟)
48. 控制平面和数据平面的区别?
详细答案
| 维度 | 控制平面(Control Plane) | 数据平面(Data Plane) |
|---|---|---|
| 组件 | API Server、Scheduler、Controller Manager | Kubelet、kube-proxy、容器运行时 |
| 职责 | 决策:调度、状态维护、API 响应 | 执行:运行容器、网络转发、状态上报 |
| 高可用 | 多节点冗余 + Leader 选举 | 工作节点横向扩展 |
| 资源消耗 | CPU/内存密集型 | 网络/IO 密集型 |
| 扩展方式 | 垂直扩展(更强配置) | 水平扩展(更多节点) |
类比:
- 控制平面 → 大脑(决策)
- 数据平面 → 四肢(执行)
49. K8s 的调度器是如何选择最佳 Node 的?
详细答案
调度流程分两阶段:
- 过滤(Predicates):
- 检查硬性条件:资源需求、端口冲突、节点选择器匹配等
- 输出候选节点列表
- 打分(Priorities):
- 评估指标:
LeastRequestedPriority:空闲资源最多BalancedResourceAllocation:CPU/内存使用均衡NodeAffinityPriority:亲和性匹配度TaintTolerationPriority:污点容忍
- 总分最高节点获胜
- 评估指标:
自定义调度:
- 编写调度器扩展(Extender)
- 使用调度框架(Scheduling Framework)添加插件
示例:
# 查看调度事件
kubectl describe pod nginx | grep Events -A10
# 输出:Scheduled Successfully assigned default/nginx to node-3
50. HPA、VPA、Cluster Autoscaler 的区别?
详细答案
| 扩缩容类型 | 操作对象 | 扩缩方向 | 特点 |
|---|---|---|---|
| HPA (Horizontal) | Pod 副本数量 | 水平扩展 | 适用无状态服务,最常用 |
| VPA (Vertical) | Pod 资源请求 (CPU/内存) | 垂直扩展 | 需重启 Pod,适合有状态服务 |
| Cluster Autoscaler | 工作节点数量 | 集群层面 | 根据 Pending Pod 自动增删节点 |
HPA 示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
组合使用:
HPA + Cluster Autoscaler = 全自动弹性伸缩
51. K8s 如何实现多集群管理?
详细答案
主流方案:
- Kubefed (Kubernetes Federation v2):
- 官方方案,统一 API 跨集群部署资源
- 支持多集群服务发现
- 商业产品:
- Rancher:集群生命周期管理
- Google Anthos:混合云管理
- 开源工具:
- Karmada (华为):兼容原生 API
- Cluster API:声明式集群管理
核心功能:
- 全局负载均衡
- 跨集群灾难恢复
- 统一策略管理
部署示例:
# 使用 kubefedctl 加入集群
kubefedctl join cluster2 --host-cluster-context=cluster1
52. Sidecar 模式是什么?常见的应用场景有哪些?
详细答案
- Sidecar 模式:在应用容器旁运行辅助容器,扩展主容器功能
- 场景:
- 日志收集:Fluentd 容器转发日志
- 服务网格:Envoy 代理处理流量
- 配置管理:监听 ConfigMap 变更并热加载
- 安全代理:mTLS 加密通信
示例:
containers:
- name: main-app
image: nginx:1.25
- name: log-agent # Sidecar
image: fluentd
volumeMounts:
- name: logs
mountPath: /var/log/nginx
volumes:
- name: logs
emptyDir: {}
优势:
- 解耦应用与基础设施代码
- 复用标准组件
53. Operator 模式是什么?有哪些优缺点?
详细答案
- Operator 模式:通过自定义控制器和 CRD 管理复杂有状态应用
- 核心组件:
- CRD(Custom Resource Definition):扩展 K8s API
- Controller:监听 CR 变化并执行运维操作
- 工作流程:
- 优点:
- 自动化复杂运维任务(备份/恢复/升级)
- 封装领域知识
- 缺点:
- 学习曲线陡峭
- 可能引入非标准接口
知名 Operator:
- Prometheus Operator:管理监控栈
- etcd Operator:自动化 etcd 集群
54. 如何在 K8s 中进行灰度发布?
详细答案
实现方案:
- 原生 Deployment:
- 逐步增加新版本副本数(手动调节)
- Ingress 金丝雀:
# Nginx Ingress 注解 annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20%" - 服务网格(Istio):
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: product-vs spec: hosts: ["product.svc.cluster.local"] http: - route: - destination: host: product subset: v1 weight: 90 - destination: host: product subset: v2 weight: 10 - Argo Rollouts:
- 高级渐进式交付工具
- 支持蓝绿/金丝雀/分析
关键步骤:
- 部署新版本(初始 0% 流量)
- 逐步切流(5% → 20% → 50% → 100%)
- 监控关键指标(错误率/延迟)
- 出现问题时快速回滚
七、云原生与生态
55. K8s 与 Docker Swarm、Mesos 的区别?
详细答案
| 维度 | Kubernetes | Docker Swarm | Apache Mesos |
|---|---|---|---|
| 架构 | 声明式 API + 控制器模型 | 简单命令式架构 | 两级调度(Framework + Master) |
| 学习曲线 | 陡峭 | 平缓 | 中等 |
| 扩展性 | 强(CRD/Operator) | 有限 | 强(通过 Framework) |
| 网络 | CNI 标准(多插件选择) | 原生 Overlay 网络 | 依赖 CNI 或 Mesos CNI |
| 存储 | 完善 PV/PVC/StorageClass | 基础卷管理 | 通过 CSI 支持 |
| 适用场景 | 大规模生产环境 | 中小集群快速部署 | 混合负载(容器+传统应用) |
| 社区生态 | 最大(CNCF) | 停滞(Docker 公司战略转移) | 衰退(被 K8s 取代) |
选择建议:
- 需要企业级功能 → Kubernetes
- 快速部署简单应用 → Docker Swarm
- 混合运行容器和非容器负载 → Mesos(历史场景)
56. K8s 如何与 Service Mesh(如 Istio、Linkerd)结合?
详细答案
集成方式:
- Sidecar 注入:
- 自动注入代理容器(如 Envoy)到每个 Pod
- 命令:
istioctl kube-inject -f app.yaml | kubectl apply -f -
- 控制平面:
- Istiod(Istio)或 Linkerd Control Plane 部署在独立 Namespace
- 流量管理:
- 通过 VirtualService/ServiceProfile 配置路由规则
- 安全:
- mTLS 自动加密服务间通信
示例(Istio 路由):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: product-vs
spec:
hosts: ["product.svc.cluster.local"]
http:
- route:
- destination:
host: product
subset: v1
weight: 90
- destination:
host: product
subset: v2
weight: 10
价值:
- 非侵入式微服务治理
- 可观测性(分布式追踪)
- 零信任安全
57. 什么是 CRD(CustomResourceDefinition)?如何编写?
详细答案
- CRD:扩展 Kubernetes API 的自定义资源类型
- 核心元素:
Group/Version/Kind(如stable.example.com/v1.CronTab)Spec:用户可配置参数Status:控制器更新的状态
编写步骤:
- 定义 CRD YAML
- 创建 CRD:
kubectl apply -f crd.yaml - 开发 Controller 监听 CR
示例:
# cron-tab-crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
schedule: {type: string}
command: {type: string}
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
---
# 使用 CR
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-cron
spec:
schedule: "*/5 * * * *"
command: "/opt/cleanup.sh"
工具:
- Kubebuilder
- Operator SDK
58. Kubernetes 如何与 CI/CD 集成?
详细答案
典型流程:
工具链:
| 环节 | 工具 |
|---|---|
| CI | Jenkins/GitLab CI/GitHub Actions |
| 镜像构建 | Kaniko/Buildkit |
| 仓库 | Docker Hub/Harbor |
| CD | Argo CD/Flux |
| 部署 | Helm/Kustomize |
GitOps 实践:
- Git 作为唯一事实源
- Argo CD 自动同步集群状态到 Git 声明
- 回滚 = Git revert
示例(Argo CD 应用定义):
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: production-app
spec:
project: default
source:
repoURL: https://github.com/team/repo
path: k8s/production
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
59. K8s 在大规模集群下的优化方案有哪些?
详细答案
优化方向:
- 控制平面:
- API Server:
- 启用聚合层(–enable-aggregator-routing)
- 增加 --max-requests-inflight(默认 400→800)
- etcd:
- SSD 磁盘 + 独立部署
- 调优参数:
--auto-compaction-retention=1h
- API Server:
- 节点管理:
- 限制 DaemonSet(避免非必要组件)
- 调整 kubelet --max-pods(默认 110→250)
- 网络:
- 高性能 CNI(Cilium eBPF)
- 优化 iptables 为 IPVS(kube-proxy --proxy-mode=ipvs)
- 资源:
- 使用 RuntimeClass 运行低开销容器(gVisor/Kata)
- 设置合理的 HPA 冷却时间(–horizontal-pod-autoscaler-downscale-stabilization)
监控指标:
- API Server 延迟:
apiserver_request_duration_seconds - etcd 写入延迟:
etcd_disk_wal_fsync_duration_seconds
60. 你在生产环境中踩过哪些 Kubernetes 的坑?如何解决的?
详细答案
典型问题与解决方案:
| 问题场景 | 原因分析 | 解决方案 |
|---|---|---|
| 节点 NotReady 雪崩 | kubelet 内存泄漏 | 升级 kubelet + 限制 --node-status-update-frequency |
| HPA 频繁抖动 | 指标采样间隔太短 | 调整 --horizontal-pod-autoscaler-sync-period 为 1m |
| CoreDNS 超时 | 默认配置抗压能力差 | 增加副本数 + 启用 autopath 插件 |
| 镜像拉取限流 | Docker Hub 匿名访问限制 | 迁移到私有仓库 + 配置 imagePullSecret |
| 长连接服务升级断连 | kube-proxy iptables 刷新 | 使用会话保持(service.spec.sessionAffinity) |
| PV 删除卡住 | Finalizer 死锁 | 手动移除 finalizers 字段 |
实战案例:
问题:集群突然出现大量 ImagePullBackOff
排查:
kubectl describe pod→ 显示toomanyrequests- 确认使用 Docker Hub 且未配置认证
解决:
- 创建私有镜像仓库(Harbor)
- 添加 imagePullSecret:
kubectl create secret docker-registry my-secret \ --docker-server=harbor.example.com \ --docker-username=admin \ --docker-password=pass - 更新 Deployment:
spec: template: spec: imagePullSecrets: - name: my-secret
避坑指南:
- 遵循 12-Factor 应用原则
- 混沌工程定期测试(如 Chaos Mesh)
- 监控全覆盖(控制平面+节点+应用)
1146

被折叠的 条评论
为什么被折叠?



