控制节点选择

本节提供有关如何将Redis Enterprise集群pod调度为仅放置在特定节点或节点池上的信息。

许多Kubernetes集群部署具有不同类型的节点,这些节点具有不同的CPU和内存资源,可用于调度集群工作负载。Redis Enterprise for Kubernetes具有多种能力,可以通过在Redis Enterprise集群自定义资源定义(CRD)中指定的属性来控制调度Redis Enterprise集群节点Pod。

Redis Enterprise集群(REC)作为StatefulSet部署,管理Redis Enterprise集群节点pod。 调度程序在以下情况下选择节点来部署新的Redis Enterprise集群节点pod:

  • 集群已创建
  • 集群已调整大小
  • 一个 pod 失败

以下是您可以控制Pod调度的方式:

使用节点选择器

集群规范中的nodeSelector属性使用与Kubernetes nodeSelector相同的值和结构。通常,节点标签是一种简单的方法,用于确保特定节点用于Redis Enterprise pods。例如,如果节点'n1'和'n2'被标记为“高内存”:

kubectl label nodes n1 memory=high
kubectl label nodes n2 memory=high

Redis Enterprise 集群 CRD 可以请求调度到这些节点上:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: rec
spec:
  nodes: 3
  nodeSelector:
     memory: high

然后,当操作员创建与pod关联的StatefulSet时,nodeSelector部分是pod规范的一部分。当调度程序尝试创建新的pod时,它需要满足节点选择约束。

使用节点池

节点池是Kubernetes集群部署和提供者底层基础设施的常见部分。 通常,节点池是配置相似的节点类别,例如具有相同分配内存和CPU的节点。 实施者通常会用一组一致的标签来标记这些节点。

在Google Kubernetes Engine (GKE)上,所有节点池都有标签cloud.google.com/gke-nodepool,其值为配置期间使用的名称。 在Microsoft Azure Kubernetes System (AKS)上,您可以创建具有特定标签集的节点池。其他托管集群服务可能具有类似的标签方案。

你可以使用nodeSelector部分通过标签值请求特定的节点池。例如,在GKE上:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: rec
spec:
  nodes: 3
  nodeSelector:
     cloud.google.com/gke-nodepool: 'high-memory'

使用节点污点

您可以使用多个节点污点和一组容忍度来控制Redis Enterprise集群节点Pod的调度。 集群规范中的podTolerations属性指定了要使用的Pod容忍度列表。 该值是Kubernetes容忍度的列表。

例如,如果集群有一个单一的节点池,节点污点可以控制节点允许的工作负载。 你可以向节点添加污点,例如节点 n1、n2 和 n3,为 Redis Enterprise 集群保留一组节点:

kubectl taint nodes n1 db=rec:NoSchedule
kubectl taint nodes n2 db=rec:NoSchedule
kubectl taint nodes n3 db=rec:NoSchedule

这防止任何pod被调度到节点上,除非pod能够容忍污点db=rec

然后,您可以将此污点的容忍添加到集群规范中:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: rec
spec:
  nodes: 3
  podTolerations:
  - key: db
    operator: Equal     
    value: rec
    effect: NoSchedule

一组污点也可以处理更复杂的用例。 例如,可以通过pod容忍度使用role=testrole=dev污点来指定节点专门用于测试或开发工作负载。

使用 Pod 反亲和性

默认情况下,Redis Enterprise节点pod不允许放置在同一个集群的同一节点上:

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  - labelSelector:
      matchLabels:
        app: redis-enterprise
        redis.io/cluster: rec
        redis.io/role: node
    topologyKey: kubernetes.io/hostname

每个pod都有上述三个标签,其中redis.io/cluster是集群名称的标签。

您可以更改此规则以限制或包含Redis Enterprise集群节点pod可以运行的节点。 例如,您可以删除redis.io/cluster标签,以便即使来自不同集群的Redis Enterprise节点pod也不能调度到同一个Kubernetes节点上:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: rec
spec:
  nodes: 3
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: redis-enterprise
          redis.io/role: node
      topologyKey: kubernetes.io/hostname

或者你可以防止Redis Enterprise节点与其他工作负载一起调度。 例如,如果所有数据库工作负载都有标签'local/role: database',你可以使用这个标签来避免在同一节点上调度两个数据库:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: rec
spec:
  nodes: 3
  extraLabels:
     local/role: database
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          local/role: database
          app: redis-enterprise
          redis.io/cluster: rec
          redis.io/role: node
      topologyKey: kubernetes.io/hostname

在这种情况下,任何使用标签 local/role: database 部署的 pod 都不能调度到同一个节点上。

使用机架感知

您可以配置Redis Enterprise以实现机架区域感知,以在分区或其他机架(或区域)相关故障期间提高可用性。

注意:
创建您的机架区域ID时,有一些限制需要考虑;有关更多信息,请参阅机架区域感知

Rack-zone awareness 是 Redis Enterprise 集群 CRD 中的一个单一属性,名为 rackAwarenessNodeLabel。 此标签的值通常为 topology.kubernetes.io/zone,如文档 'Running in multiple zones' 中所述。

您可以使用以下命令在节点中检查此标签的值:

$kubectl get nodes -o custom-columns="name:metadata.name","rack\\zone:metadata.labels.failure-domain\.beta\.kubernetes\.io/zone"

name                                            rack\zone
ip-10-0-x-a.eu-central-1.compute.internal    eu-central-1a
ip-10-0-x-b.eu-central-1.compute.internal    eu-central-1a
ip-10-0-x-c.eu-central-1.compute.internal    eu-central-1b
ip-10-0-x-d.eu-central-1.compute.internal    eu-central-1b

启用集群角色

为了让操作员读取集群节点信息,您必须为操作员创建一个集群角色,然后将该角色绑定到服务账户。

这是一个集群角色:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: redis-enterprise-operator
rules:
  # needed for rack awareness
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["list", "get", "watch"]

以下是应用角色的方法:

kubectl apply -f https://raw.githubusercontent.com/RedisLabs/redis-enterprise-k8s-docs/master/rack_awareness/rack_aware_cluster_role.yaml

绑定通常是到redis-enterprise-operator服务账户:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: redis-enterprise-operator
subjects:
- kind: ServiceAccount
  namespace: OPERATOR_NAMESPACE
  name: redis-enterprise-operator
roleRef:
  kind: ClusterRole
  name: redis-enterprise-operator
  apiGroup: rbac.authorization.k8s.io

并且可以通过运行以下命令来应用:

kubectl apply -f https://raw.githubusercontent.com/RedisLabs/redis-enterprise-k8s-docs/master/rack_awareness/rack_aware_cluster_role_binding.yaml

一旦应用了集群角色和绑定,您可以配置Redis Enterprise集群以使用机架感知标签。

配置机架感知

您可以通过设置rackAwarenessNodeLabel属性来配置节点标签以读取机架区域:

apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
  name: example-redisenterprisecluster
spec:
  nodes: 3
  rackAwarenessNodeLabel: topology.kubernetes.io/zone
注意:
当你使用rackAwarenessNodeLabel属性时,操作员会将反亲和规则的topologyKey更改为使用的标签名称,除非你也指定了podAntiAffinity属性。如果你同时使用rackAwarenessNodeLabelpodAntiAffinity,你必须确保你的pod反亲和规则中的topologyKey设置为节点标签名称。
RATE THIS PAGE
Back to top ↑