Kubernetes 容器编排
Kubernetes 容器编排 #
云原生容器编排平台,自动化部署、扩展、容器化应用
📋 目录 #
核心概念 #
集群架构 #
核心组件 #
| 组件 | 节点类型 | 作用 |
|---|---|---|
| API Server | 控制面板 | 统一入口,处理REST请求 |
| etcd | 控制面板 | 分布式键值存储,存储集群状态 |
| Scheduler | 控制面板 | 调度Pod到节点 |
| Controller | 控制面板 | 维护期望状态 |
| kubelet | 工作节点 | 与控制面板通信,管理Pod |
| kube-proxy | 工作节点 | 网络代理,Service负载均衡 |
| Containerd | 工作节点 | 容器运行时 |
核心对象 #
Pod #
最小调度单元 ⭐⭐⭐⭐⭐
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
关键配置:
| 配置 | 说明 |
|---|---|
resources.requests |
最小资源需求 |
resources.limits |
最大资源限制 |
readinessProbe |
就绪探针,未就绪不转发流量 |
livenessProbe |
存活探针,失败后重启Pod |
restartPolicy |
重启策略: Always/OnFailure/Never |
Deployment #
管理Pod,支持扩缩容和滚动更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Service #
服务发现与负载均衡
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP # ClusterIP/NodePort/LoadBalancer
Service类型:
| 类型 | 说明 | 外部访问 |
|---|---|---|
| ClusterIP | 集群内访问 | ❌ |
| NodePort | 节点端口访问 | ✅ 节点IP:端口 |
| LoadBalancer | 负载均衡器 | ✅ VIP |
| ExternalName | 映射外部服务 | ✅ |
ConfigMap #
配置管理
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
application.properties: |
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app
envFrom:
- configMapRef:
name: my-config
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-config
Ingress #
七层负载均衡
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
常用命令 #
集群管理 #
# 查看集群信息
kubectl cluster-info
# 查看节点状态
kubectl get nodes -o wide
# 查看 Namespace
kubectl get namespaces
# 创建 Namespace
kubectl create namespace dev
Pod 操作 #
# 查看Pod
kubectl get pods -n dev
# 查看Pod详情
kubectl describe pod my-pod -n dev
# 查看Pod日志
kubectl logs my-pod -n dev
# 进入Pod
kubectl exec -it my-pod -n dev -- /bin/bash
# 删除Pod
kubectl delete pod my-pod -n dev
# 强制删除Pod
kubectl delete pod my-pod -n dev --force --grace-period=0
Deployment 操作 #
# 创建Deployment
kubectl apply -f deployment.yaml
# 查看Deployment
kubectl get deployments -n dev
# 扩容
kubectl scale deployment my-app --replicas=5 -n dev
# 更新镜像
kubectl set image deployment/my-app app=my-app:2.0.0 -n dev
# 回滚
kubectl rollout undo deployment/my-app -n dev
kubectl rollout history deployment/my-app -n dev
# 查看更新状态
kubectl rollout status deployment/my-app -n dev
Service 操作 #
# 查看Service
kubectl get services -n dev
# 查看Service详情
kubectl describe service my-service -n dev
# 端口转发(调试用)
kubectl port-forward service/my-service 8080:80 -n dev
调试命令 #
# 查看事件
kubectl get events -n dev --sort-by=.metadata.creationTimestamp
# 查看资源使用
kubectl top nodes
kubectl top pods -n dev
# 查看YAML
kubectl get pod my-pod -n dev -o yaml
# 查看关联资源
kubectl get all -l app=my-app -n dev
# 查看资源配额
kubectl describe nodes | grep -A 5 "Allocated resources"
应用部署 #
完整部署示例 #
# namespace.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: my-app
---
# configmap.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
namespace: my-app
data:
application.yml: |
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://mysql:3306/mydb
username: root
password: root123
---
# deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
envFrom:
- configMapRef:
name: my-config
volumeMounts:
- name: logs
mountPath: /app/logs
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
volumes:
- name: logs
emptyDir: {}
---
# service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-app
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
---
# hpa.yaml
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: my-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
部署流程 #
# 1. 创建所有资源
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f hpa.yaml
# 或者一次性应用
kubectl apply -f k8s/
# 2. 检查状态
kubectl get pods -n my-app
kubectl get services -n my-app
kubectl get hpa -n my-app
# 3. 查看日志
kubectl logs -f deployment/my-app -n my-app
# 4. 进入容器调试
kubectl exec -it deployment/my-app -n my-app -- /bin/bash
生产实践 #
资源限制 #
resources:
requests:
memory: "256Mi" # 最小内存需求
cpu: "250m" # 0.25个核心
limits:
memory: "512Mi" # 最大内存限制
cpu: "500m" # 0.5个核心
Requests vs Limits:
requests: 调度依据,Kubelet保证limits: 资源上限,超出可能被kill
健康检查 #
readinessProbe: # 就绪检查
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
livenessProbe: # 存活检查
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
自动扩缩容 #
# CPU利用率扩缩容
kubectl autoscale deployment my-app \
--cpu-percent=70 \
--min=3 \
--max=10 \
-n my-app
# 内存利用率扩缩容
kubectl autoscale deployment my-app \
--memory-percent=80 \
--min=3 \
--max=10 \
-n my-app
故障排查 #
# 1. Pod状态异常
kubectl describe pod pod-name -n namespace
# 2. 查看事件
kubectl get events -n namespace --sort-by=.metadata.creationTimestamp
# 3. 查看日志
kubectl logs pod-name -n namespace
kubectl logs -f pod-name -n namespace # 实时
# 4. 进入容器
kubectl exec -it pod-name -n namespace -- /bin/bash
# 5. 查看资源使用
kubectl describe nodes | grep -A 5 "Allocated resources"
kubectl top pods -n namespace
# 6. 查看配置
kubectl get configmap -n namespace
kubectl get secret -n namespace
面试题汇总 #
基础篇 #
- Kubernetes核心架构?
- Pod vs Deployment vs Service?
- Pod生命周期?
- Kubelet作用?
实践篇 #
- 如何实现滚动更新?
- 如何实现自动扩缩容?
- 如何实现服务发现?
- 如何进行故障排查?
进阶篇 #
- K8s网络模型?
- Ingress vs NodePort vs LoadBalancer?
- 资源requests vs limits?
- 调度策略有哪些?
面试题答案详解 #
基础篇 #
- Kubernetes核心架构?
答案:
Kubernetes集群分为**控制面板(Control Plane)和工作节点(Worker Nodes)**两部分:
控制面板组件:
| 组件 | 作用 |
|---|---|
| API Server | 集群统一入口,处理REST请求,认证授权 |
| etcd | 分布式键值存储,保存集群所有状态数据 |
| Scheduler | 调度器,将Pod分配到合适的Worker节点 |
| Controller Manager | 控制器,维护集群期望状态(副本、端点等) |
工作节点组件:
| 组件 | 作用 |
|---|---|
| kubelet | 节点代理,与控制面板通信,管理Pod生命周期 |
| kube-proxy | 网络代理,维护Service网络规则和负载均衡 |
| Containerd | 容器运行时,负责容器的创建和管理 |
- Pod vs Deployment vs Service?
答案:
| 对象 | 作用 | 关系 |
|---|---|---|
| Pod | 最小调度单元,包含1个或多个容器 | Deployment管理Pod的创建和更新 |
| Deployment | 声明式管理Pod,支持扩缩容和滚动更新 | 控制Pod的副本数和更新策略 |
| Service | 服务发现和负载均衡,提供稳定访问入口 | 屏蔽Pod的动态变化,通过Label Selector关联Pod |
典型架构:
Deployment → Pods → Service → Ingress → 外部访问
- Pod生命周期?
答案:
Pod生命周期分为以下阶段:
| 阶段 | 说明 |
|---|---|
| Pending | API Server创建Pod对象,正在调度或拉取镜像 |
| Running | Pod已调度到节点,所有容器已创建,至少有一个容器在运行 |
| Succeeded | 所有容器成功执行完毕且不再重启 |
| Failed | 所有容器已终止,至少有一个容器异常退出 |
| Unknown | 无法获取Pod状态(通常是节点通信问题) |
关键事件:
- Init Containers先执行,完成后再启动App Containers
- Readiness Probe就绪检查通过后才接收流量
- Liveness Probe存活检查失败后重启容器
- Kubelet作用?
答案:
Kubelet是运行在每个Worker节点上的代理,主要作用:
- Pod管理:根据API Server的要求创建、更新、删除Pod
- 容器监控:监控容器运行状态,执行健康检查
- 节点注册:向API Server注册节点,汇报节点状态
- 资源上报:上报节点资源使用情况(CPU、内存等)
- Volume管理:挂载Pod所需的存储卷
实践篇 #
- 如何实现滚动更新?
答案:
通过Deployment的RollingUpdate策略实现:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多超出期望副本数的数量
maxUnavailable: 0 # 最多不可用的副本数
流程:
- 创建新版本Pod
- 等待新版本Pod就绪
- 终止旧版本Pod
- 重复直到所有Pod更新完成
回滚:
kubectl rollout undo deployment/my-app # 回滚到上一个版本
kubectl rollout history deployment/my-app # 查看历史版本
- 如何实现自动扩缩容?
答案:
使用HorizontalPodAutoscaler(HPA)根据资源使用率自动扩缩容:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
命令创建:
kubectl autoscale deployment my-app --cpu-percent=70 --min=3 --max=10
- 如何实现服务发现?
答案:
Kubernetes通过Service和DNS实现服务发现:
Service类型:
| 类型 | 访问方式 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内通过Service名称访问 | 内部服务间调用 |
| NodePort | 节点IP:端口访问 | 开发测试,少量外部访问 |
| LoadBalancer | 云厂商负载均衡器VIP访问 | 生产环境外部访问 |
DNS解析:
- 同一Namespace:
service-name - 不同Namespace:
service-name.namespace.svc.cluster.local
- 如何进行故障排查?
答案:
常用排查步骤:
- 查看Pod状态
kubectl get pods -n namespace
kubectl describe pod pod-name -n namespace
- 查看Pod日志
kubectl logs pod-name -n namespace
kubectl logs -f pod-name -n namespace # 实时日志
- 查看事件
kubectl get events -n namespace --sort-by=.metadata.creationTimestamp
- 进入容器调试
kubectl exec -it pod-name -n namespace -- /bin/bash
- 查看资源使用
kubectl top nodes
kubectl top pods -n namespace
进阶篇 #
- K8s网络模型?
答案:
Kubernetes网络模型的核心要求:
- Pod间互通:任意Pod可以直接通信,无需NAT
- Pod与Node互通:Pod可以与所有Node通信
- IP-per-Pod:每个Pod有独立IP
网络插件(CNI)实现:
- Flannel:简单的覆盖网络
- Calico:网络策略 + BGP路由
- Cilium:eBPF实现,高性能
Pod网络通信:
- 同一Node内Pod:通过虚拟网桥通信
- 不同Node间Pod:通过Overlay网络或路由通信
- Ingress vs NodePort vs LoadBalancer?
答案:
| 类型 | 层级 | 特点 | 适用场景 |
|---|---|---|---|
| NodePort | L4 | 在每个Node上开放端口,简单但端口有限 | 开发测试 |
| LoadBalancer | L4 | 云厂商LB,性能好但成本高 | 生产环境单服务 |
| Ingress | L7 | HTTP/HTTPS路由,支持域名、路径分发 | 生产环境多服务 |
Ingress示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
rules:
- host: api.example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
- 资源requests vs limits?
答案:
| 配置 | 作用 | 影响 |
|---|---|---|
| requests | 资源需求最小值,调度依据 | Kubelet保证至少有这么多资源 |
| limits | 资源上限,不可超过 | 超出CPU被节流,超出内存被OOM Kill |
示例:
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
最佳实践:
- 始终设置requests和limits
- requests与limits比例适中(1:2或1:1.5)
- 生产环境limits不能过大
- 调度策略有哪些?
答案:
Kubernetes调度分为预选和优选两个阶段:
预选策略(Predicate): 过滤不满足条件的节点
- PodFitsResources:节点资源足够
- MatchNodeSelector:Node标签匹配
- CheckNodeCondition:节点状态正常
- NoVolumeZoneConflict:Volume可用区匹配
优选策略(Priority): 对满足条件的节点打分
- LeastRequestedPriority:资源使用率低的节点优先
- BalancedResourceAllocation:资源均衡分配的节点优先
- ImageLocalityPriority:已有镜像的节点优先
高级调度:
- Node Affinity:节点亲和性
- Pod Affinity/AntiAffinity:Pod亲和/反亲和
- Taints/Tolerations:污点/容忍
- Topology Spread Constraints:拓扑分布约束
🔗 相关笔记 #
最后更新: 2026-04-29