Kubernetes 调度场景实战指南

发布时间:2023年12月31日

Kubernetes 调度是确保集群中的 Pod 在合适的节点上运行的关键组件。通过灵活配置调度策略,可以提高资源利用率、负载均衡和高可用性。在本文中,我们将深入研究一些实际的 Kubernetes 调度场景,并提供相应的配置示例和最佳实践。

1. 基础场景 - NodeSelector

场景描述: 我们有一些节点标记了具有 SSD 硬盘的标签,我们希望将需要高性能存储的 Pod 调度到这些节点上。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: high-performance-pod
spec:
  containers:
  - name: my-container
    image: my-image
  nodeSelector:
    disktype: ssd

2. 高级场景 - Node Affinity

场景描述: 我们希望将需要 GPU 的任务调度到具有 GPU 标签的节点上。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: my-container
    image: my-image
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: gpu
            operator: In
            values:
            - "true"

3. 资源分配 - Pod 优先级和预选调度

场景描述: 为了确保关键任务具有更高的优先级,我们可以定义 PriorityClass,并将其应用于 Pod。

PriorityClass 配置:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "High priority class"

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: high-priority-pod
spec:
  containers:
  - name: my-container
    image: my-image
  priorityClassName: high-priority

4. 防止 Pod 在相同节点上运行 - Pod Anti-Affinity

场景描述: 通过 Pod Anti-Affinity,我们可以确保同一组中的 Pod 不会被调度到同一个节点上,以提高高可用性。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: anti-affinity-pod
spec:
  containers:
  - name: my-container
    image: my-image
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - web
        topologyKey: kubernetes.io/hostname

5. 多副本的拓扑域分布 - Pod Topology Spread

场景描述: 确保同一应用的多个 Pod 分布在不同的拓扑域中,提高可用性。

Deployment 配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: "app"
                operator: In
                values:
                - "web"
            topologyKey: "kubernetes.io/hostname"

6. 节点 Taints 和 Pod Tolerations

场景描述: 通过节点的 Taints,我们可以标记节点,只有具有相应 Tolerations 的 Pod 才能被调度到这些节点上。

Node 配置:

apiVersion: v1
kind: Node
metadata:
  name: node1
spec:
  taints:
  - key: special
    value: unique
    effect: NoSchedule

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: toleration-pod
spec:
  containers:
  - name: my-container
    image: my-image
  tolerations:
  - key: "special"
    operator: "Equal"
    value: "unique"
    effect: "NoSchedule"

7.?Custom Scheduler - 自定义调度器

场景描述: 通过自定义调度器,实现特定调度需求,例如根据业务规则或特殊硬件条件。

自定义调度器示例:

  1. 创建自定义调度器插件
// my_scheduler.go
package main

import (
	"k8s.io/kubernetes/pkg/scheduler"
	"k8s.io/kubernetes/pkg/scheduler/framework"
	"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
	"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption"
	"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
)

const (
	// YourSchedulerName is the name of your custom scheduler
	YourSchedulerName = "my-scheduler"
)

// New initializes a new scheduler with your custom plugins
func New() *scheduler.Config {
	return &scheduler.Config{
		Client:              scheduler.NewHTTPClient(),
		SchedulerName:       YourSchedulerName,
		PercentageOfNodesToScore: 0.25,
		Profiles: []scheduler.Profile{
			{
				Name: YourSchedulerName,
				Plugins: []scheduler.Plugin{
					defaultpreemption.Name: defaultpreemption.New,
					defaultbinder.Name:     defaultbinder.New,
					names.NewNodeResourcesFit(),
					names.NewNodePorts(),
					names.NewNodeAffinity(YourSchedulerName),
					names.NewNodeAffinityPriority(YourSchedulerName),
				},
			},
		},
	}
}

func main() {
	// Use the New() function to create a new scheduler with your custom plugins
	config := New()
	command := app.NewSchedulerCommand(
		// Use the WithConfig function to set your custom scheduler configuration
		app.WithConfig(config),
	)
	f := command.Flags()
	f.AddGoFlagSet(flag.CommandLine)

	if err := command.Execute(); err != nil {
		os.Exit(1)
	}
}
  1. 编译和运行自定义调度器
go build my_scheduler.go
./my_scheduler

8.?Pod Priority and Preemption - Pod 优先级和抢占

场景描述: 通过设置 Pod 的优先级和抢占策略,确保关键任务得到优先调度。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: priority-pod
spec:
  containers:
  - name: my-container
    image: my-image
  priorityClassName: high-priority

9.?资源限制和请求 - Resource Limits and Requests

场景描述: 通过设置 Pod 的资源限制和请求,调度器可以更好地优化资源利用率。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: resource-pod
spec:
  containers:
  - name: my-container
    image: my-image
    resources:
      limits:
        cpu: "2"
        memory: "1Gi"
      requests:
        cpu: "1"
        memory: "500Mi"

10.?Affinity and Anti-Affinity Rules - 亲和性和反亲和性规则

场景描述: 使用亲和性和反亲和性规则,确保 Pod 在特定节点上或避免与其他 Pod 调度到相同节点。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: affinity-pod
spec:
  containers:
  - name: my-container
    image: my-image
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - "high"
        topologyKey: kubernetes.io/hostname

11.?Pod Disruption Budget - Pod 中断预算

场景描述: 通过 Pod 中断预算,限制在维护期间允许中断的 Pod 数量,确保系统的稳定性。

PodDisruptionBudget 配置:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: web

12.?Horizontal Pod Autoscaler - 水平扩展器

场景描述: 使用水平扩展器根据 CPU 使用率或其他指标自动调整 Pod 的数量,以满足应用程序的需求。

HorizontalPodAutoscaler 配置:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

13.?Pod Overhead - Pod 开销

场景描述: 通过设置 Pod 开销,告知调度器考虑 Pod 所需的附加资源,以避免在节点上调度过多的 Pod。

Pod 配置:

apiVersion: v1
kind: Pod
metadata:
  name: overhead-pod
spec:
  containers:
  - name: my-container
    image: my-image
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
    overhead:
      podFixed: 100Mi
      ephemeral-storage: 1Gi

14.?Node Local DNS Cache - 节点本地 DNS 缓存

场景描述: 在节点上启用本地 DNS 缓存,提高 DNS 查询性能。

kubelet 配置:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDomain: cluster.local
featureGates:
  CoreDNSLocalCache: true

15.?Pod Priority Class - Pod 优先级类

场景描述: 使用 Pod 优先级类将 Pod 分为不同的优先级,确保关键任务优先调度。

PriorityClass 配置:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "High priority class"
preemptionPolicy: PreemptLowerPriority

这些场景覆盖了从基本到高级的 Kubernetes 调度实战案例。根据你的需求,可以选择合适的场景进行配置,以优化集群的资源利用和性能。在实际应用中,根据具体需求调整配置,确保调度器的策略满足业务和性能需求。

文章来源:https://blog.csdn.net/u012172506/article/details/135234273
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。