K8s Node 节点亲和性与污点容忍:实现服务(Web 服务 + 数据库)的节点分组部署
·
Kubernetes节点亲和性与污点容忍:实现Web服务与数据库的分组部署
在Kubernetes(K8s)中,节点亲和性(Node Affinity)用于控制Pod调度到特定节点组,而污点容忍(Toleration)允许Pod在有污点的节点上运行。这可以帮助实现资源隔离,例如将Web服务和数据库服务部署到不同的节点组,以提高性能、安全性和可靠性。以下是逐步实现方案,确保结构清晰、易于操作。
1. 核心概念简述
- 节点亲和性:通过节点标签(Labels)指定Pod应调度到哪些节点。例如,给节点添加标签
role=web或role=db,然后Pod使用亲和性规则匹配这些标签。 - 污点容忍:节点污点(Taint)用于排斥Pod调度(如
dedicated=db:NoSchedule),只有添加了容忍(Toleration)的Pod才能被调度到该节点。这强制了节点专用性。 - 目标场景:
- Web服务Pod(如Nginx或应用服务)部署到一组节点(标签
role=web)。 - 数据库服务Pod(如MySQL或PostgreSQL)部署到另一组节点(标签
role=db)。 - 通过亲和性和污点,确保两类服务完全隔离,避免资源竞争。
- Web服务Pod(如Nginx或应用服务)部署到一组节点(标签
2. 实现步骤
以下步骤基于Kubernetes集群操作,使用 kubectl 命令和YAML配置文件。假设集群中有多个节点,我们将它们分为两组。
步骤1: 为节点添加标签和污点
首先,将节点分组并设置污点,确保节点只运行指定类型的Pod。
- Web节点组:添加标签
role=web,并设置污点排斥非Web Pod。# 为节点添加标签(例如节点名为node-web-1) kubectl label nodes node-web-1 role=web # 设置污点:只有容忍此污点的Pod才能调度 kubectl taint nodes node-web-1 dedicated=web:NoSchedule - 数据库节点组:添加标签
role=db,并设置污点排斥非数据库 Pod。# 为节点添加标签(例如节点名为node-db-1) kubectl label nodes node-db-1 role=db # 设置污点:只有容忍此污点的Pod才能调度 kubectl taint nodes node-db-1 dedicated=db:NoSchedule - 验证节点配置:
kubectl get nodes --show-labels # 查看所有节点标签 kubectl describe node node-web-1 | grep Taints # 查看节点污点
步骤2: 配置Web服务Pod的亲和性和容忍
在Web服务的Deployment配置中,使用节点亲和性匹配 role=web 的节点,并添加容忍以忽略Web节点的污点。
- 示例YAML(web-deployment.yaml):
apiVersion: apps/v1 kind: Deployment metadata: name: web-service spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: role operator: In values: - web # 强制Pod调度到role=web的节点 tolerations: - key: "dedicated" operator: "Equal" value: "web" effect: "NoSchedule" # 容忍污点dedicated=web:NoSchedule containers: - name: nginx image: nginx:latest ports: - containerPort: 80 - 应用配置:
kubectl apply -f web-deployment.yaml
步骤3: 配置数据库服务Pod的亲和性和容忍
在数据库服务的Deployment配置中,使用节点亲和性匹配 role=db 的节点,并添加容忍以忽略数据库节点的污点。
- 示例YAML(db-deployment.yaml):
apiVersion: apps/v1 kind: Deployment metadata: name: db-service spec: replicas: 2 selector: matchLabels: app: db template: metadata: labels: app: db spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: role operator: In values: - db # 强制Pod调度到role=db的节点 tolerations: - key: "dedicated" operator: "Equal" value: "db" effect: "NoSchedule" # 容忍污点dedicated=db:NoSchedule containers: - name: mysql image: mysql:latest env: - name: MYSQL_ROOT_PASSWORD value: "password" ports: - containerPort: 3306 - 应用配置:
kubectl apply -f db-deployment.yaml
步骤4: 验证部署结果
检查Pod是否调度到正确节点组。
- 查看Pod分布:
kubectl get pods -o wide # 查看Pod所在节点- 预期输出:所有
web-servicePod在node-web-*节点,所有db-servicePod在node-db-*节点。
- 预期输出:所有
- 测试隔离性:
- 尝试删除一个数据库Pod:它应重新调度到
role=db的节点。 - 如果添加新节点但未配置标签/污点,Pod不会调度到该节点。
- 尝试删除一个数据库Pod:它应重新调度到
3. 注意事项
- 节点资源匹配:确保节点有足够资源(CPU/内存)。可以通过节点亲和性的
preferredDuringSchedulingIgnoredDuringExecution添加软约束。 - 污点效果:
NoSchedule仅影响新调度;PreferNoSchedule是软约束;NoExecute会驱逐现有Pod。 - 高可用性:为每个节点组添加多个节点,并在亲和性中使用
topologySpreadConstraints避免Pod集中。 - 错误处理:如果Pod无法调度,检查节点标签、污点和Pod容忍是否匹配。使用
kubectl describe pod <pod-name>查看事件。 - 扩展性:此方案可扩展到更多分组(如缓存服务),只需添加新标签和污点。
通过以上步骤,您可以实现Web服务和数据库服务的完全隔离部署,提升集群的稳定性和效率。如果需要进一步优化,请提供具体场景!
更多推荐
所有评论(0)