控制节点选择
本节提供有关如何将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=test
或role=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以实现机架区域感知,以在分区或其他机架(或区域)相关故障期间提高可用性。
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
属性。如果你同时使用rackAwarenessNodeLabel
和podAntiAffinity
,你必须确保你的pod反亲和规则中的topologyKey
设置为节点标签名称。