📖 目录
一、基础概念篇
1. 什么是Kubernetes?它解决了什么问题?
答案:
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。
解决的问题:
- 容器调度:在哪个节点运行哪个容器
- 服务发现:容器如何找到彼此
- 负载均衡:流量如何分配到多个容器实例
- 自动扩缩容:根据负载自动调整容器数量
- 滚动更新:零停机更新应用
- 自愈能力:容器崩溃时自动重启
比喻理解:
Kubernetes就像一个交响乐团的指挥,协调各个乐手(容器)完成演奏(应用服务)。
2. 简述Kubernetes的架构组成?
答案:
Kubernetes集群由两部分组成:
控制平面(Control Plane)
┌──────────────────────────────────────┐
│ 控制平面节点 │
├──────────────────────────────────────┤
│ 1. API Server - 统一入口 │
│ 2. etcd - 配置存储 │
│ 3. Scheduler - 调度器 │
│ 4. Controller - 控制器 │
│ 5. Cloud Controller - 云控制器 │
└──────────────────────────────────────┘
工作节点(Worker Nodes)
┌──────────────────────────────────────┐
│ 工作节点 │
├──────────────────────────────────────┤
│ 1. kubelet - 节点代理 │
│ 2. kube-proxy - 网络代理 │
│ 3. Container Runtime - 容器运行时 │
└──────────────────────────────────────┘
3. Master节点和Node节点的职责分别是什么?
答案:
| 角色 | 主要职责 | 关键组件 |
|---|---|---|
| Master节点 | 集群管理、调度决策、API服务 | API Server, etcd, Scheduler, Controller |
| Node节点 | 运行容器、执行任务 | kubelet, kube-proxy, Container Runtime |
Master节点作用:
- 做出调度决策
- 监控和响应事件
- 维护集群状态
- 提供REST API
Node节点作用:
- 运行Pod和容器
- 向Master报告状态
- 执行Master指令
- 管理网络和存储
4. Pod的概念和作用是什么?
答案:
Pod定义:
- Kubernetes中最小的部署和管理单位
- 一个或多个容器的组合
- 共享网络命名空间和存储卷
特点:
yaml
# Pod示例
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
- name: sidecar
image: busybox
command: ["sleep", "3600"]
作用:
- 资源共享:Pod内容器共享网络IP、端口空间、存储卷
- 协同工作:支持sidecar模式(如日志收集、代理容器)
- 生命周期管理:Pod是调度、扩展、删除的最小单位
5. Deployment、ReplicaSet、Pod的关系?
答案:
Deployment
↓ 管理
ReplicaSet
↓ 管理
Pod → 真正的容器
关系链:
-
Deployment:声明式更新管理
yamlapiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx -
ReplicaSet:确保Pod副本数量
- 由Deployment自动创建
- 负责维护指定数量的Pod
-
Pod:运行的实际容器
为什么需要三层?
- Deployment:处理滚动更新、回滚
- ReplicaSet:管理副本数量
- Pod:运行应用
6. ConfigMap和Secret的区别和用法?
答案:
| 特性 | ConfigMap | Secret |
|---|---|---|
| 用途 | 存储配置数据 | 存储敏感信息 |
| 内容类型 | 普通文本 | Base64编码 |
| 安全问题 | 明文存储 | 考虑加密 |
| 大小限制 | 1MB | 1MB |
ConfigMap示例:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "mysql://localhost:3306"
debug_mode: "true"
---
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
envFrom:
- configMapRef:
name: app-config
Secret示例:
yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
username: YWRtaW4= # base64: admin
password: cGFzc3dvcmQ= # base64: password
---
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: app-secret
key: username
7. 什么是Service?有哪些类型?
答案:
Service定义了Pod的逻辑集合和访问策略。
Service类型:
-
ClusterIP(默认)
yamlapiVersion: v1 kind: Service spec: type: ClusterIP # 仅集群内部访问 ports: - port: 80 -
NodePort
yamlspec: type: NodePort ports: - port: 80 nodePort: 30080 # 访问 <NodeIP>:30080 -
LoadBalancer
yamlspec: type: LoadBalancer # 云厂商负载均衡器 -
ExternalName
yamlspec: type: ExternalName externalName: example.com # DNS重定向
8. Namespace的作用是什么?
答案:
Namespace提供虚拟集群能力,用于资源隔离和管理。
作用:
bash
# 查看所有Namespace
kubectl get namespaces
# 创建Namespace
kubectl create namespace production
# 在指定Namespace创建资源
kubectl create deployment nginx --image=nginx -n production
常用场景:
- 环境隔离:dev、staging、production
- 团队隔离:不同团队独立管理
- 资源配额:限制Namespace资源使用
示例:
yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
---
# 创建带资源限制的Namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
9. Label和Selector的作用?
答案:
Label用于标识和组织资源,Selector用于选择资源。
Label示例:
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
env: production
tier: frontend
version: v1.0
spec:
containers:
- name: nginx
image: nginx:1.20
Selector示例:
yaml
apiVersion: apps/v1
kind: Deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
查询示例:
bash
# 通过Label选择Pod
kubectl get pods -l app=nginx
kubectl get pods -l env=production,tier=frontend
# 不匹配选择
kubectl get pods -l 'app!=nginx'
# 集合选择
kubectl get pods -l 'env in (production,staging)'
10. 什么是声明式管理和命令式管理?
答案:
命令式管理: 告诉系统"做什么"
bash
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
kubectl set image deployment nginx nginx=nginx:1.21
声明式管理: 描述"期望状态"
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.21
区别:
- 命令式:执行具体操作
- 声明式:描述目标状态,由系统保证
推荐:
- 生产环境使用声明式(YAML文件)
- 开发测试可使用命令式
二、核心组件篇
11. API Server的作用和特点?
答案:
API Server是Kubernetes集群的统一入口。
作用:
- 提供RESTful API接口
- 认证和授权
- 准入控制
- 数据验证
- 与etcd交互
特点:
bash
# API Server地址
kubectl cluster-info
# API Server端点
https://kubernetes.default.svc
工作流程:
用户请求 → kubectl → API Server
↓
验证(认证、授权、准入控制)
↓
存储到etcd
↓
通知相关组件(如Scheduler)
无状态设计:
- 可以水平扩展
- 不存储任何状态
- 所有状态在etcd中
12. etcd的作用和工作原理?
答案:
etcd是Kubernetes的配置数据库。
作用:
bash
# etcd存储的数据
- 所有资源定义(Pod、Service等)
- 集群状态
- 配置信息
- 服务发现信息
特点:
- 分布式键值存储
- 强一致性(Raft协议)
- 高可用(3/5/7副本)
数据备份:
bash
# 备份etcd数据
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
# 恢复etcd数据
etcdctl snapshot restore snapshot.db
重要提示:
- etcd是Kubernetes的单点故障点
- 必须定期备份
- 生产环境需要多个etcd实例
13. Scheduler的工作原理和调度策略?
答案:
Scheduler负责将Pod调度到合适的节点。
工作流程:
1. Pod创建 → API Server
2. 写入etcd
3. Scheduler watch到新Pod
4. 过滤节点(Predicates)
5. 评分节点(Priorities)
6. 选择最优节点
7. 绑定节点(通过kubelet)
调度策略示例:
yaml
apiVersion: v1
kind: Pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
常见调度策略:
- nodeSelector:节点选择
- nodeAffinity:节点亲和性
- podAffinity:Pod亲和性
- taint/toleration:污点和容忍
- 资源需求:CPU/内存限制
14. Controller Manager的功能?
答案:
Controller Manager包含多个控制器,维护期望状态。
主要控制器:
- Replication Controller
- ReplicaSet Controller
- Deployment Controller
- StatefulSet Controller
- DaemonSet Controller
- Job Controller
- CronJob Controller
- Node Controller
- Service Controller
- Endpoint Controller
工作流程:
go
for {
// 1. 获取期望状态(Desired State)
desired := getDesiredState()
// 2. 获取当前状态(Current State)
current := getCurrentState()
// 3. 对比差异
diff := compare(current, desired)
// 4. 执行操作使当前状态接近期望状态
execute(diff)
// 5. 等待一段时间后循环
time.Sleep(1 * time.Second)
}
示例:
bash
# 查询控制器状态
kubectl get controllerrevisions
kubectl describe deployment nginx
15. kubelet的作用和职责?
答案:
kubelet是Node节点的代理,管理Pod生命周期。
职责:
- 从API Server获取Pod清单
- 启动/停止容器
- 监控容器健康状态
- 向Master报告状态
- 挂载存储卷
- 容器网络配置
命令示例:
bash
# 查看kubelet状态
systemctl status kubelet
# 查看kubelet日志
journalctl -u kubelet -f
# kubelet配置
cat /var/lib/kubelet/config.yaml
工作流程:
API Server → kubelet → CRI → Container Runtime → 启动容器
16. kube-proxy如何实现负载均衡?
答案:
kube-proxy负责实现Service的负载均衡。
三种模式:
-
userspace模式(早期)
- 用户空间实现
- 性能较差
-
iptables模式(默认)
bash# 查看iptables规则 iptables -t nat -L KUBE-SERVICES # 工作原理 # 生成iptables规则转发流量 -
ipvs模式(推荐生产)
bash# 启用ipvs kubeadm init --config kubeadm-config.yaml # 或修改kube-proxy配置
负载均衡算法:
- Round Robin(轮询)
- Session Affinity(会话保持)
- Least Connection(最少连接)
17. Container Runtime的作用?
答案:
Container Runtime负责运行容器。
常见实现:
- Docker(历史最早)
- containerd(CNCF项目)
- CRI-O(Red Hat)
- gvisor(Google)
CRI接口:
Kubernetes → CRI → Container Runtime
切换Runtime示例:
yaml
# containerd
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
18. 解释Kubernetes的声明式API模型?
答案:
声明式API是Kubernetes的核心设计理念。
对比:
| 特性 | 命令式API | 声明式API(Kubernetes) |
|---|---|---|
| 操作 | "创建X" | "X应该存在" |
| 重复执行 | 可能失败 | 幂等性 |
| 状态追踪 | 不追踪 | 自动追踪 |
YAML示例:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3 # 声明:期望3个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.20
控制器保证:
bash
# 无论如何操作,最终都是3个Pod
kubectl delete pod nginx-xxx # 自动重建
kubectl scale deployment nginx --replicas=1 # 会恢复到3
19. Master节点高可用如何实现?
答案:
通过部署多个Master节点实现高可用。
架构:
LoadBalancer
┌───────┼───────┐
↓ ↓ ↓
Master1 Master2 Master3
└───────┼───────┘
↓
etcd集群(3节点)
组件高可用:
- API Server:无状态,支持负载均衡
- etcd:Raft协议,奇数节点(3/5/7)
- Scheduler/Controller:Leader选举机制
部署示例:
bash
# 查看Master节点
kubectl get nodes -l node-role.kubernetes.io/master
# etcd集群信息
etcdctl member list
20. Node节点的健康检查和状态?
答案:
kubelet定期向Master报告节点状态。
节点状态:
bash
# 查看节点状态
kubectl get nodes
# 查看详细状态
kubectl describe node <node-name>
# 节点条件(Conditions)
- Ready: 节点是否健康
- MemoryPressure: 内存压力
- DiskPressure: 磁盘压力
- PIDPressure: 进程ID压力
节点操作:
bash
# 标记节点为不可调度
kubectl cordon <node-name>
# 驱逐节点上的Pod
kubectl drain <node-name> --ignore-daemonsets
# 取消不可调度标记
kubectl uncordon <node-name>
# 删除节点
kubectl delete node <node-name>
三、Pod和容器篇
21. Pod的生命周期和状态转换?
答案:
Pod状态:
Pending → Running → Succeeded/Failed
↓
Unknown
状态说明:
- Pending:调度中,等待被调度到节点
- ContainerCreating:创建容器
- Running:至少一个容器运行中
- Succeeded:所有容器成功退出
- Failed:至少一个容器失败退出
- Unknown:无法获取Pod状态
示例:
bash
# 查看Pod状态
kubectl get pods
# 查看详细信息
kubectl describe pod <pod-name>
# 查看Pod事件
kubectl get events --field-selector involvedObject.name=<pod-name>
22. Init Container的作用和用法?
答案:
Init Container在应用容器启动前运行。
用途:
yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
initContainers:
# 等待数据库就绪
- name: wait-db
image: busybox
command: ['sh', '-c']
args:
- |
until nc -z db 3306; do
echo "waiting for db..."
sleep 2
done
# 初始化数据
- name: init-data
image: init-tools
command: ['/init.sh']
containers:
- name: app
image: myapp:latest
特点:
- 按顺序执行
- 必须成功退出
- 应用容器启动前运行
23. Pod的健康检查机制?
答案:
Kubernetes提供三种探针。
探针类型:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
# 存活探针
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# 就绪探针
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# 启动探针
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10
区别:
| 探针 | 失败后果 | 用途 |
|---|---|---|
| liveness | 重启容器 | 检查应用是否存活 |
| readiness | 从Service移除 | 检查是否就绪接收流量 |
| startup | 重启容器 | 慢启动应用 |
24. Pod的资源限制如何设置?
答案:
通过requests和limits限制资源使用。
示例:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
resources:
# 请求资源(调度参考)
requests:
memory: "64Mi"
cpu: "250m" # 0.25 CPU
# 限制资源(运行限制)
limits:
memory: "128Mi"
cpu: "500m" # 0.5 CPU
说明:
- requests:Pod调度所需资源
- limits:Pod运行时限制
CPU单位:
1= 1 CPU核心500m= 0.5 CPU核心250m= 0.25 CPU核心
内存单位:
64Mi= 64 Mebibyte1Gi= 1 Gibibyte
资源配额:
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
25. 如何实现优雅关闭?
答案:
通过SIGTERM信号实现优雅关闭。
Pod配置:
yaml
apiVersion: v1
kind: Pod
metadata:
name: graceful-shutdown
spec:
containers:
- name: app
image: myapp:latest
# 优雅关闭等待时间(默认30秒)
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"]
工作流程:
1. 收到删除请求
2. Pod状态变为Terminating
3. 从Service移除Pod
4. 发送SIGTERM信号
5. 等待gracePeriodSeconds(默认30秒)
6. 强制终止(SIGKILL)
代码示例:
python
import signal
import sys
def signal_handler(sig, frame):
print('收到SIGTERM,开始优雅关闭...')
# 清理工作
cleanup()
sys.exit(0)
signal.signal(signal.SIGTERM, signal_handler)
if __name__ == '__main__':
# 应用逻辑
run_app()
26. Sidecar模式的应用场景?
答案:
Sidecar是在同一个Pod中运行的辅助容器。
场景示例:
yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
# 主容器
- name: app
image: myapp:latest
volumeMounts:
- name: shared-log
mountPath: /var/log
# Sidecar容器
- name: log-agent
image: fluentd:latest
volumeMounts:
- name: shared-log
mountPath: /var/log
- name: fluentd-config
mountPath: /etc/fluentd
volumes:
- name: shared-log
emptyDir: {}
- name: fluentd-config
configMap:
name: fluentd-config
常见Sidecar用途:
- 日志收集
- 监控指标采集
- 服务代理
- 配置热重载
27. 什么是Ephemeral Storage?
答案:
临时的本地存储。
用途:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
volumeMounts:
- name: scratch
mountPath: /tmp
volumes:
- name: scratch
emptyDir:
sizeLimit: 1Gi
特点:
- Pod删除后丢失
- 用于缓存、临时文件
- 可设置大小限制
28. Pod安全策略(Security Context)?
答案:
配置Pod和容器的安全属性。
示例:
yaml
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
# Pod级别的安全上下文
securityContext:
runAsUser: 1000
fsGroup: 2000
containers:
- name: demo
image: nginx
# 容器级别的安全上下文
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
常用配置:
runAsNonRoot:非root运行readOnlyRootFilesystem:只读文件系统capabilities:Linux能力
四、网络和服务篇
29. Service的负载均衡原理?
答案:
通过Endpoints和iptables/ipvs实现。
工作流程:
客户端 → Service:80 → iptables/ipvs → Pod IP
查看Endpoints:
bash
# Service选择Pod
kubectl get endpoints nginx-service
# Endpoints内容
# nginx-service 10.244.1.2:80,10.244.1.3:80,10.244.2.1:80
iptables规则:
bash
# 查看Service的iptables规则
iptables -t nat -L -n | grep KUBE-SVC
# 负载均衡规则
-A KUBE-SVC-XXXXXXXX -m statistic --mode random --probability 0.333...
-A KUBE-SVC-XXXXXXXX -m statistic --mode random --probability 0.5 ...
-A KUBE-SVC-XXXXXXXX -m tcp -p tcp -j DNAT --to-destination <Pod IP>:80
30. Ingress的作用和配置?
答案:
Ingress提供HTTP/HTTPS路由。
示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
ingressClassName: nginx
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 8080
# HTTPS配置
tls:
- hosts:
- app1.example.com
secretName: app1-tls
常见Ingress控制器:
- NGINX Ingress
- Traefik
- HAProxy
- Istio Gateway
31. Headless Service的用途?
答案:
无ClusterIP的Service。
示例:
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
clusterIP: None # Headless Service
selector:
app: nginx
ports:
- port: 80
用途:
- StatefulSet
- 直接访问Pod IP
- 服务发现(如DNS查询)
DNS解析:
bash
# 普通Service返回ClusterIP
nslookup nginx-service
# -> 返回一个IP
# Headless Service返回所有Pod IP
nslookup nginx-headless
# -> 返回多个Pod IP
32. Network Policy的作用?
答案:
Network Policy实现Pod级别的网络隔离。
示例:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
# 允许来自特定Pod的入站流量
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
# 允许出站到数据库
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
前提条件:
- 需要CNI插件支持(如Calico、Cilium)
33. 如何实现会话保持(Session Affinity)?
答案:
通过Service的sessionAffinity配置。
示例:
yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: ClusterIP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 3小时
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
原理:
- 基于客户端IP的会话保持
- 同一IP的请求路由到同一Pod
- 适合需要会话状态的应用
34. Service和Pod的DNS解析?
答案:
Kubernetes提供DNS服务(CoreDNS)。
DNS名称规则:
Service: <service-name>.<namespace>.svc.cluster.local
Pod: <pod-ip>.<namespace>.pod.cluster.local
示例:
bash
# 同Namespace
ping nginx-service
# 跨Namespace
ping nginx-service.production
# 完整域名
ping nginx-service.production.svc.cluster.local
Pod的DNS配置:
yaml
apiVersion: v1
kind: Pod
spec:
dnsPolicy: ClusterFirst
dnsConfig:
nameservers:
- 8.8.8.8
searches:
- default.svc.cluster.local
options:
- name: ndots
value: "2"
五、存储管理篇
35. PV、PVC、StorageClass的关系?
答案:
StorageClass(存储类)
↓ 自动创建
PV(持久化卷)
↓ 绑定
PVC(持久化卷声明)
↓ 使用
Pod
示例:
yaml
# 1. StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
---
# 2. PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi
---
# 3. Pod使用
apiVersion: v1
kind: Pod
spec:
containers:
- name: mysql
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
36. Volume的类型和使用?
答案:
emptyDir:临时存储
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir:
sizeLimit: 1Gi
hostPath:主机路径
yaml
volumes:
- name: host-data
hostPath:
path: /data
type: DirectoryOrCreate
secret/configMap:配置数据
yaml
volumes:
- name: config
configMap:
name: app-config
- name: secret
secret:
secretName: app-secret
37. StatefulSet使用存储的特点?
答案:
StatefulSet需要持久化存储。
示例:
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 3
template:
spec:
containers:
- name: mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-ssd"
resources:
requests:
storage: 100Gi
特点:
- 每个Pod有独立的PVC
- 有序创建和删除
- 稳定的网络标识
38. 如何备份和恢复PVC数据?
答案:
通过Velero或手动备份。
Velero示例:
bash
# 安装Velero
velero install
# 备份PVC
velero backup create mysql-backup \
--include-namespaces production \
--snapshot-volumes
# 恢复
velero restore create \
--from-backup mysql-backup
手动备份:
bash
# 创建备份Pod
kubectl run backup-pod --image=restic/restic:latest \
--restart=Never --rm -it \
-v <pvc-name>:/data \
-- sh
# 在Pod内执行备份
# restic backup /data
六、调度和资源管理篇
39. Pod的调度过程?
答案:
创建Pod → API Server → etcd
↓
Scheduler监听
↓
过滤节点(Predicates)
↓
评分节点(Priorities)
↓
选择最优节点
↓
绑定到节点(kubelet)
↓
节点上创建容器
调度示例:
bash
# 查看调度事件
kubectl get events --field-selector reason=FailedScheduling
# 手动指定节点
apiVersion: v1
kind: Pod
spec:
nodeName: node-1 # 直接指定节点
40. 节点亲和性和Pod亲和性?
答案:
Node Affinity:Pod与节点
yaml
apiVersion: v1
kind: Pod
spec:
affinity:
nodeAffinity:
# 必须满足
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- gpu
# 优选
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: disk-type
operator: In
values:
- ssd
Pod Affinity:Pod与Pod
yaml
apiVersion: v1
kind: Pod
spec:
affinity:
podAffinity:
# 必须与app=redis部署在同一节点
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis
topologyKey: kubernetes.io/hostname
41. Taint和Toleration的作用?
答案:
污点和容忍用于节点调度控制。
节点污点:
bash
# 添加污点
kubectl taint nodes node1 key=value:NoSchedule
# 删除污点
kubectl taint nodes node1 key=value:NoSchedule-
# 查看污点
kubectl describe node node1
Pod容忍:
yaml
apiVersion: v1
kind: Pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
- key: "node.kubernetes.io/unschedulable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
污点效果:
NoSchedule:不调度PreferNoSchedule:尽量避免NoExecute:驱逐已运行的Pod
42. HPA自动扩缩容?
答案:
HorizontalPodAutoscaler自动调整Pod数量。
示例:
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
自定义指标:
yaml
metrics:
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: "1k"
43. 资源配额和限制范围?
答案:
ResourceQuota:Namespace配额
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
persistentvolumeclaims: "4"
pods: "10"
LimitRange:默认限制
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: "1Gi"
cpu: "500m"
defaultRequest:
memory: "512Mi"
cpu: "250m"
type: Container
七、实战操作篇
44. 如何部署一个有状态应用?
答案:
使用StatefulSet部署有状态应用。
MySQL StatefulSet示例:
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
clusterIP: None
selector:
app: mysql
ports:
- port: 3306
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
my.cnf: |
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
45. 如何实现滚动更新和回滚?
答案:
滚动更新:
bash
# 方式1:更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.21
# 方式2:修改YAML
kubectl apply -f deployment.yaml
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
# 查看更新历史
kubectl rollout history deployment/nginx-deployment
回滚:
bash
# 回滚到上一版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到特定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# 查看详细历史
kubectl rollout history deployment/nginx-deployment --revision=2
更新策略:
yaml
apiVersion: apps/v1
kind: Deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25% # 最多不可用25%
maxSurge: 25% # 最多多25%额外
minReadySeconds: 30 # 就绪等待时间
progressDeadlineSeconds: 600 # 超时时间
46. 如何使用ConfigMap和Secret?
答案:
创建ConfigMap:
bash
# 从文件创建
kubectl create configmap app-config \
--from-file=config.properties \
--from-file=log4j.properties
# 从字面量创建
kubectl create configmap app-config \
--from-literal=key1=value1 \
--from-literal=key2=value2
在Pod中使用:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
# 环境变量方式
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
# 所有键值对
envFrom:
- configMapRef:
name: app-config
# 文件挂载
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config
创建Secret:
bash
# 从文件创建
kubectl create secret generic app-secret \
--from-file=username.txt \
--from-file=password.txt
# 从字面量创建
kubectl create secret generic app-secret \
--from-literal=username=admin \
--from-literal=password=secret123
47. 如何设置资源限制和配额?
答案:
Pod资源限制:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Namespace配额:
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
persistentvolumeclaims: "10"
secrets: "20"
configmaps: "20"
LimitRange默认限制:
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: "512Mi"
cpu: "500m"
defaultRequest:
memory: "256Mi"
cpu: "250m"
max:
memory: "2Gi"
cpu: "2"
min:
memory: "128Mi"
cpu: "100m"
type: Container
48. 如何实现健康检查?
答案:
配置三种探针。
健康检查配置:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
spec:
containers:
- name: app
image: myapp:latest
ports:
- containerPort: 8080
# 存活探针
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# 就绪探针
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
# 启动探针
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10
探针类型:
yaml
# HTTP探针
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
# TCP探针
livenessProbe:
tcpSocket:
port: 8080
# 命令探针
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
49. 如何排查Pod问题?
答案:
系统化的排查步骤。
步骤1:查看Pod状态
bash
# 基本信息
kubectl get pods
# 详细信息
kubectl describe pod <pod-name>
# 查看YAML
kubectl get pod <pod-name> -o yaml
步骤2:查看日志
bash
# 当前日志
kubectl logs <pod-name>
# 指定容器
kubectl logs <pod-name> -c <container-name>
# 跟踪日志
kubectl logs -f <pod-name>
# 之前容器的日志(已重启)
kubectl logs <pod-name> --previous
步骤3:进入容器调试
bash
# 进入Pod
kubectl exec -it <pod-name> -- /bin/sh
# 进入特定容器
kubectl exec -it <pod-name> -c <container-name> -- /bin/sh
# 执行命令
kubectl exec <pod-name> -- env
步骤4:查看事件
bash
# Pod事件
kubectl get events --field-selector involvedObject.name=<pod-name>
# 所有事件
kubectl get events --sort-by='.lastTimestamp'
# 查看特定类型的事件
kubectl get events --field-selector type=Warning
步骤5:资源检查
bash
# 节点资源
kubectl top nodes
# Pod资源使用
kubectl top pods
# 节点详细信息
kubectl describe node <node-name>
50. 如何扩容和缩容?
答案:
手动扩缩容:
bash
# 扩容
kubectl scale deployment nginx --replicas=5
# 缩容
kubectl scale deployment nginx --replicas=2
# 查看扩容状态
kubectl get deployment nginx
自动扩缩容(HPA):
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
垂直扩缩容(VPA):
bash
# 安装VPA
kubectl apply -f https://github.com/kubernetes/autoscaler/vertical-pod-autoscaler/releases/latest/download/vpa-release.yaml
# 创建VPA
kubectl autoscale vpa app-vpa --min=2 --max=10
51. 如何备份和恢复集群?
答案:
etcd备份:
bash
# 备份etcd
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
# 查看备份状态
etcdctl --write-out=table snapshot status snapshot.db
Velero备份(推荐):
bash
# 安装Velero
velero install \
--provider aws \
--bucket velero-backup \
--secret-file ./credentials-velero
# 创建备份
velero backup create cluster-backup
# 列出备份
velero backup get
# 恢复
velero restore create --from-backup cluster-backup
手动备份资源:
bash
# 导出所有资源
kubectl get all --all-namespaces -o yaml > backup.yaml
# 导出特定资源
kubectl get deployment nginx -o yaml > nginx.yaml
52. 如何进行CI/CD集成?
答案:
Jenkins集成:
groovy
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'docker build -t myapp:$BUILD_NUMBER .'
sh 'docker push myapp:$BUILD_NUMBER'
}
}
stage('Deploy to K8s') {
steps {
sh '''
kubectl set image deployment/myapp \
myapp=myapp:$BUILD_NUMBER
'''
}
}
}
}
GitLab CI集成:
yaml
.deploy:
script:
- kubectl set image deployment/app app=app:$CI_COMMIT_SHA
- kubectl rollout status deployment/app
ArgoCD(GitOps):
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
spec:
source:
repoURL: https://github.com/example/repo
path: k8s
destination:
server: https://kubernetes.default.svc
namespace: production
八、故障排查篇
53. Pod一直处于Pending状态?
答案:
排查步骤:
1. 查看调度失败原因
bash
kubectl describe pod <pod-name>
# 查看 Events 部分
常见原因:
- 资源不足(CPU/内存)
- 节点选择器不匹配
- 污点未容忍
- PV/PVC问题
2. 查看节点资源
bash
kubectl top nodes
kubectl describe node <node-name>
3. 检查节点选择器
bash
kubectl get nodes --show-labels
kubectl get pod <pod-name> -o yaml | grep nodeSelector
4. 查看调度事件
bash
kubectl get events --field-selector \
reason=FailedScheduling
54. Pod一直处于CrashLoopBackOff状态?
答案:
排查步骤:
bash
# 1. 查看当前状态
kubectl get pod <pod-name>
# 2. 查看日志
kubectl logs <pod-name>
# 3. 查看之前容器的日志
kubectl logs <pod-name> --previous
# 4. 查看详细信息
kubectl describe pod <pod-name>
# 5. 查看事件
kubectl get events --field-selector \
involvedObject.name=<pod-name>
常见原因和解决:
- 应用错误:修复代码
- 配置错误:检查ConfigMap/Secret
- 资源不足:增加资源限制
- 健康检查失败:调整探针
55. Service无法访问Pod?
答案:
排查步骤:
1. 检查Service和Endpoints
bash
kubectl get svc <service-name>
kubectl get endpoints <service-name>
# Endpoints应该包含Pod IP
2. 检查Pod选择器
bash
kubectl get pods --show-labels
kubectl get svc <service-name> -o yaml
# 确保selector匹配Pod的labels
3. 检查端口映射
bash
kubectl get svc <service-name> -o yaml | grep targetPort
# 确保端口正确
4. 测试Pod连通性
bash
# 从另一个Pod测试
kubectl run test --image=busybox -it -- sh
wget -O- http://<service-name>:80
5. 检查Network Policy
bash
kubectl get networkpolicies
56. 节点NotReady问题排查?
答案:
排查步骤:
1. 查看节点状态
bash
kubectl get nodes
kubectl describe node <node-name>
2. 检查kubelet状态
bash
# SSH到节点
ssh <node-name>
# 查看kubelet状态
systemctl status kubelet
# 查看kubelet日志
journalctl -u kubelet -f
3. 检查常见问题
bash
# 容器运行时
systemctl status docker
# 或
systemctl status containerd
# 网络插件
kubectl get pods -n kube-system
# 磁盘空间
df -h
4. 检查证书
bash
# 证书是否过期
openssl x509 -in /var/lib/kubelet/pki/kubelet-client.crt \
-noout -dates
57. PVC无法绑定?
答案:
排查步骤:
1. 查看PVC状态
bash
kubectl get pvc
kubectl describe pvc <pvc-name>
2. 查看PV
bash
kubectl get pv
kubectl describe pv <pv-name>
3. 检查StorageClass
bash
kubectl get storageclass
kubectl describe storageclass <sc-name>
4. 常见问题:
- StorageClass不存在
- PV资源不足
- accessModes不匹配
- nodeAffinity限制
58. 集群性能问题排查?
答案:
1. 查看资源使用
bash
# 节点资源
kubectl top nodes
# Pod资源
kubectl top pods --all-namespaces
# 查看资源限制
kubectl describe nodes | grep -A 5 "Allocated resources"
2. 查看慢查询
bash
# etcd慢查询
etcdctl --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 \
endpoint health
3. 检查DNS性能
bash
# 测试DNS解析速度
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
4. 监控指标
bash
# 使用Prometheus/Grafana监控
# 或Metrics Server
kubectl top --help
59. 镜像拉取失败?
答案:
排查步骤:
1. 查看Pod状态
bash
kubectl describe pod <pod-name>
# 查找 ImagePullBackOff 或 ErrImagePull
2. 检查镜像名称
bash
# 确保镜像名称正确
kubectl get pod <pod-name> -o yaml | grep image:
3. 检查私有镜像
yaml
# 创建Secret
kubectl create secret docker-registry regcred \
--docker-server=<registry> \
--docker-username=<username> \
--docker-password=<password>
# 在Pod中使用
apiVersion: v1
kind: Pod
spec:
imagePullSecrets:
- name: regcred
containers:
- name: app
image: private-registry.com/app:latest
4. 测试镜像拉取
bash
# 在节点上测试
docker pull <image-name>
60. etcd数据损坏如何恢复?
答案:
备份恢复:
bash
# 1. 停止所有etcd Pod(单Master或多Master)
kubectl get pods -n kube-system | grep etcd
# 2. 备份当前数据(如果有)
kubectl cp <etcd-pod-name>:/etc/kubernetes/etcd.yaml ./backup/
# 3. 恢复备份
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--name etcd-0 \
--initial-cluster etcd-0=https://127.0.0.1:2380 \
--initial-advertise-peer-urls https://127.0.0.1:2380
# 4. 重启etcd
# 5. 重启kubelet
systemctl restart kubelet
🎯 面试准备总结
推荐学习路径
-
理论基础(1-2周)
- 掌握核心概念
- 理解架构原理
- 学习资源对象
-
实践操作(2-3周)
- 搭建K8s集群
- 部署实际应用
- 练习常用命令
-
进阶提升(1个月)
- 学习运维技能
- 掌握故障排查
- 了解生态工具
-
面试准备(1周)
- 刷题巩固知识
- 模拟面试场景
- 总结项目经验
面试注意事项
-
技术深度
- 不要只背概念,要理解原理
- 准备具体案例和项目经验
-
实操能力
- 熟悉kubectl命令
- 会写YAML配置文件
- 能排查常见问题
-
沟通表达
- 条理清晰地回答
- 结合具体例子说明
- 展示解决问题的能力
推荐资源
祝面试顺利!🚀