K8S-控制器
概述
在 Kubernetes 中,控制器是实现自动化运维和状态管理的核心组件。它们通过控制回路(Control Loop)机制持续监控系统状态,并确保当前状态与期望状态保持一致。这种设计模式借鉴了传统的自动化控制系统
控制回路基础
基本概念
控制回路是一个非终止循环,用于持续调节系统状态。
- 期望状态:资源对象中定义的
spec字段 - 当前状态:集群中资源的实际状态
- 控制动作:通过 API 服务器调整资源状态
控制器工作机制
通过 API 服务器控制
Job 控制器示例:
Job 控制器是 Kubernetes 内置控制器的典型代表,它负责管理批处理任务:
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ['echo', 'Hello Kubernetes!']
restartPolicy: Never
backoffLimit: 4
当创建新 Job 时:
- Job 控制器检测到新任务
- 控制器通过 API 服务器创建所需的 Pod
- 监控 Pod 执行状态
- 任务完成后更新 Job 状态为 Finished
控制器不直接运行容器,而是通过 API 服务器协调资源,体现了 Kubernetes 的声明式API设计理念。
直接控制模式
某些控制器需要与集群外部系统交互:
// 伪代码:节点扩展控制器的工作逻辑
func manageNodePool() {
for {
desiredNodes := getDesiredNodeCount()
currentNodes := getCurrentNodeCount()
if currentNodes < desiredNodes {
createNewNodeInCloudProvider() // 与云平台API交互
} else if currentNodes > desiredNodes {
removeNodeFromCluster() // 安全移除节点
}
reportStatusToAPIServer() // 向API服务器报告状态
time.Sleep(syncInterval)
}
}
这种模式允许 Kubernetes 扩展 beyond the cluster,管理与基础设施相关的资源。
控制器设计理念
期望状态 vs 当前状态
Kubernetes 采用云原生,承认集群状态始终处于变化中:
- 集群可能永远不会达到完全稳定状态
- 控制器持续工作以缩小当前状态与期望状态之间的差距
- 故障自动修复是常态而非例外
分布式控制器架构
Kubernetes 采用多个专用控制器而非单一单体控制器:
| 控制器类型 | 管理资源 | 功能描述 |
|---|---|---|
| Deployment控制器 | ReplicaSet | 确保指定数量的Pod副本运行 |
| Node控制器 | Node | 监控节点状态并响应节点故障 |
| Service控制器 | Service | 管理负载均衡器和服务发现 |
| Namespace控制器 | Namespace | 管理命名空间生命周期 |
优势:
- 单一故障不会影响整个系统
- 每个控制器专注特定领域
- 更容易扩展和维护
控制器运行模式
内置控制器
Kubernetes 内置控制器运行在 kube-controller-manager 中:
# kube-controller-manager 启动示例
kube-controller-manager \
--cluster-cidr=10.244.0.0/16 \
--allocate-node-cidrs=true \
--controllers=deployment,service,endpoint,namespace \
--leader-elect=true
主要内置控制器包括:
- Deployment 控制器:管理应用部署和更新
- Job/CronJob 控制器:管理批处理和定时任务
- Node 控制器:监控节点健康状况
- Service 控制器:管理服务发现和负载均衡
Deployment 控制器
工作原理
Deployment 控制器通过管理 ReplicaSet 来实现应用部署的声明式更新:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
annotations:
deployment.kubernetes.io/revision: "1"
spec:
replicas: 3
revisionHistoryLimit: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx:1.20.1
ports:
- containerPort: 80
核心功能
-
滚动更新策略
# 触发滚动更新 kubectl set image deployment/web-app nginx=nginx:1.21.1 # 监控更新状态 kubectl rollout status deployment/web-app -
版本回退机制
# 查看更新历史 kubectl rollout history deployment/web-app # 回退到上一版本 kubectl rollout undo deployment/web-app # 回退到特定版本 kubectl rollout undo deployment/web-app --to-revision=2 -
扩缩容管理
# 手动扩缩容 kubectl scale deployment/web-app --replicas=5 # 基于CPU使用率自动扩缩容 kubectl autoscale deployment/web-app --min=2 --max=10 --cpu-percent=80
典型工作流程
高级功能
-
配置健康检查
livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 15 periodSeconds: 20 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10 -
资源限制配置
resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
Job/CronJob 控制器
适合用于批处理任务管理
Job 控制器
管理一次性任务至完成:
apiVersion: batch/v1
kind: Job
metadata:
name: data-processing
spec:
completions: 5 # 需要完成的任务数
parallelism: 2 # 并行执行的任务数
backoffLimit: 4 # 重试次数
template:
spec:
containers:
- name: processor
image: data-processor:latest
command: ["process", "--input", "/data/input", "--output", "/data/output"]
restartPolicy: OnFailure
CronJob 控制器
基于时间调度的周期性任务:
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # 每天凌晨2点执行
startingDeadlineSeconds: 600
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
args: ["--mode", "full", "--target", "s3://backup-bucket"]
restartPolicy: OnFailure
使用场景
-
数据处理任务
# 创建数据处理Job kubectl create job data-export --image=exporter:latest -- \ --source=database --format=csv -
定时清理任务
schedule: "0 0 * * 0" # 每周日凌晨执行清理 -
并行批处理
completions: 100 parallelism: 10 # 同时运行10个Pod,共完成100个任务
监控与调试
# 查看Job执行状态
kubectl describe job/data-processing
# 查看CronJob下次执行时间
kubectl get cronjob/daily-backup -o jsonpath='{.status.nextScheduleTime}'
# 查看Pod日志
kubectl logs job/data-processing-xyz123
Node 控制器:节点生命周期管理
核心职责
-
节点状态监控
- 定期检查节点健康状况
- 管理节点心跳机制
- 处理节点不可达状态
-
节点标签管理
# 查看节点信息 kubectl get nodes -o wide # 给节点添加标签 kubectl label nodes node-1 disktype=ssd # 基于节点标签调度Pod kubectl get nodes --selector=disktype=ssd
节点状态转换
节点问题处理
-
节点网络分区
# 手动标记节点不可调度 kubectl cordon node-1 # 驱逐节点上所有Pod kubectl drain node-1 --ignore-daemonsets -
节点维护
# 维护前操作 kubectl cordon node-1 kubectl drain node-1 # 维护完成后 kubectl uncordon node-1
Service 控制器:服务发现与负载均衡
Service 类型与管理
apiVersion: v1
kind: Service
metadata:
name: web-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
selector:
app: web-app
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
type: LoadBalancer
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
核心功能实现
-
端点管理
# 查看Service端点 kubectl get endpoints web-service # 查看EndpointSlice kubectl get endpointslice -
负载均衡配置
# 外部负载均衡器配置 externalTrafficPolicy: Local healthCheckNodePort: 32456 loadBalancerIP: 192.168.0.100 -
服务发现机制
- DNS服务发现:
web-service.default.svc.cluster.local - 环境变量注入
- Kubernetes API查询
- DNS服务发现:
网络策略集成
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-service-policy
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: frontend
ports:
- protocol: TCP
port: 80
最佳实践
-
准备就绪网关模式
# 使用Readiness Gates控制服务流量 readinessGates: - conditionType: "www.example.com/feature-1" -
拓扑感知路由
# 启用拓扑感知提示 topologyKeys: - "topology.kubernetes.io/zone" - "topology.kubernetes.io/region" - "*" -
服务网格集成
# Istio服务网格注解 annotations: traffic.sidecar.istio.io/includeInboundPorts: "80,443"
对比
| 控制器类型 | 管理资源 | 关键特性 | 使用场景 |
|---|---|---|---|
| Deployment | ReplicaSet, Pod | 滚动更新、版本回退、自动扩缩容 | 无状态应用部署 |
| Job/CronJob | Pod | 任务完成保证、并行处理、定时调度 | 批处理任务、定时作业 |
| Node | Node | 节点健康检查、Pod驱逐、节点维护 | 集群节点管理 |
| Service | Endpoints, EndpointSlice | 负载均衡、服务发现、网络策略 | 服务暴露和访问 |
自定义控制器
Kubernetes 允许开发自定义控制器来扩展功能:
# 自定义控制器部署示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-resource-controller
spec:
replicas: 2
selector:
matchLabels:
app: custom-controller
template:
metadata:
labels:
app: custom-controller
spec:
serviceAccountName: controller-service-account
containers:
- name: controller
image: my-custom-controller:latest
env:
- name: WATCH_NAMESPACE
value: ""
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
控制器模式最佳实践
标签选择器的重要性
控制器使用标签选择器区分其管理的资源:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: frontend
tier: web
template:
metadata:
labels:
app: frontend
tier: web
spec:
containers:
- name: nginx
image: nginx:1.19
这种设计确保多个控制器不会意外干扰彼此管理的资源。
水平扩缩容模式
Deployment 控制器实现水平扩缩容:
# 扩展Deployment
kubectl scale deployment/frontend --replicas=5
# 自动扩缩容
kubectl autoscale deployment/frontend --min=2 --max=10 --cpu-percent=80
控制器会自动调整Pod数量以满足期望状态。
优雅故障处理
控制器设计包含故障恢复机制:
- 指数退避重试:失败操作会以指数增加的时间间隔重试
- 限制操作频率:防止控制器过度响应临时故障
- 最终一致性:系统最终会达到一致状态,即使中间有临时不一致
高级控制器模式
Operator 模式
Operator 是自定义控制器的进阶实现,封装了领域特定知识:
// Operator 伪代码示例
type DatabaseOperator struct {
kubeClient kubernetes.Interface
crdClient customClientset.Interface
}
func (o *DatabaseOperator) Run() {
for {
// 监听自定义资源变化
databases := o.watchDatabaseCRD()
for _, db := range databases {
// 协调数据库状态
o.reconcileDatabase(db)
}
}
}
func (o *DatabaseOperator) reconcileDatabase(db *v1alpha1.Database) {
// 检查数据库状态
// 创建/更新相关资源
// 处理备份和故障转移
}
控制器监控和观测
监控控制器性能对于确保集群健康至关重要:
# 控制器监控指标示例
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kube-controller-manager
spec:
endpoints:
- port: http-metrics
interval: 30s
selector:
matchLabels:
component: kube-controller-manager
关键监控指标包括:
- 控制器同步次数:反映控制器活动水平
- 同步错误率:标识潜在问题
- 协调延迟:衡量控制器响应时间
故障排除和调试
常见控制器问题
- 资源泄漏:控制器意外创建过多资源
- 权限问题:控制器缺乏必要API权限
- 竞争条件:多个控制器同时修改同一资源
- 性能问题:控制器处理大量资源时变慢
调试技巧
# 检查控制器日志
kubectl logs -n kube-system kube-controller-manager-abc123
# 查看控制器状态
kubectl get deployments
kubectl describe deployment/my-app
# 检查事件历史
kubectl get events --sort-by=.lastTimestamp
更多推荐


所有评论(0)