# 高可用组件分类调度
# 资源需求总量说明
下表为 Erda 高可用部署时依赖及组件 CPU、Memory、Storage 资源的需求说明。
提示
表中的资源数据对应生产环境高可用部署时各组件资源的
request
值。 因此在实际部署中,应将表中的资源数据理解为最小资源需求量,而非最大资源需求量。表中前 13 行(共 11 个组件)称为 Erda 的依赖组件,Erda 的核心组件(目前包含 30+ 组件)称为 Erda 组件。
组件 | CPU Request/Pod | Memory Request/Pod | Storage Capacity/Pod | 副本 | Anti-affinity |
---|---|---|---|---|---|
Cassandra | 2 | 4 GB | 1000 GB | 3 | hard |
Elasticsearch | 2 | 4 GB | 1000 GB | 3 | hard |
etcd | 1 | 2 GB | 32 GB | 3 | hard |
Zookeeper | 0.1 | 256 MB | - | 3 | hard |
Kafka | 2 | 4 GB | 100 GB | 3 | hard |
KMS | 0.5 | 1 GB | - | 2 | soft |
MySQL | 0.5 | 0.5 GB | 100 GB | 1 | - |
Registry | 0.5 | 0.5 GB | 1000 GB | 1 | - |
Sonar | 0.75 | 1.5 GB | - | 1 | - |
redis-operator | 0.1 | 10 MB | - | 1 | - |
redis-sentinel | 0.05 | 64 MB | - | 3 | soft |
redis-redis | 0.15 | 1 GB | - | 2 | soft |
volume-provisioner | 0.01 | 100 MB | - | DaemonSet | - |
Erda 核心组件 | 8 | 16 GB | - | 1~2 | soft |
# 节点需求说明
根据上表,可计算出高可用部署默认配置下 request
的资源总量约为:
- CPU:36
- Memory:72 GB
- Storage: 8000 GB
根据资源需求总量,高可用部署 Erda 时建议节点配置如下(最小资源需求量):
节点 规模 | CPU 最低配置 | Memory最低配置 | 存储最低配置 | 备注说明 |
---|---|---|---|---|
3 | 12 | 24 GB | 3000 GB | 设为单节点配置 |
4 | 10 | 20 GB | 2000 GB | Cassandra、Elasticsearch、Registry 共 7 个 Pod(单个需求 1000 GB),单节点至少 2000 GB |
5 | 8 | 16 GB | 2000 GB | 同上 |
6 | 8 | 16 GB | 2000 GB | 1. Cassandra、Elasticsearch、Registry 共 7 个 Pod(单个需求 1000 GB),单节点至少 2000 GB 2. Erda 组件可与依赖组件分离部署,4 个节点用于依赖组件,2 个节点用于 Erda 组件部署 |
请注意如下事项:
- Cassandra、Elasticsearch、etcd、Kafka、Zookeeper 等组件(目前均为 3 节点的集群)及 Pod Anti-affinity 为硬约束,因此需要至少 3 个节点。
- 对 3 节点规模而言,至少有 1 节点 Cassandra、Elasticsearch、Registry 共存,因此单节点需要至少 3000 GB 存储。
- 若存储使用 Erda 的 volume-provisioner 提供的 Local Volume,建议 /data 目录所在的文件系统(3 节点规模下单节点需满足 3000 GB 存储空间)采用多个单独的物理磁盘构成 RAID (opens new window) 条带或者 LVM (opens new window),避免单个硬盘情况下 Cassandra、Elasticsearch、etcd 等组件之间存在 IO 竞争。
# 分类调度说明及操作
# 分类调度说明
Erda 组件高可用分类调度部署的主要目标是实现如下调度结果:
- 以 deployment/statefulSet 方式部署的多个 Pod 副本,对于 Erda 依赖组件满足反亲和性硬约束,对于 Erda 组件满足反亲和性软约束。
- Erda 组件及 Erda 依赖组件需通过节点标签实现 nodeAffinity 调度,此外 Cassandra、Elasticsearch、etcd、Zookeeper、Kafka 等组件之间也可通过节点标签实现部署的节点隔离(包括存储容量隔离及 IO 竞争隔离)。
- 通过节点标签选择部署 Erda 组件、Erda 依赖组件的节点范围。
- 通过节点标签尽可能避免 Erda 组件、Erda 依赖组件部署至 Kubernetes 集群的 Master 节点及 LoadBalancer 节点。
# 操作方式
部署 Erda 前,请执行如下操作以确定 Erda 组件及 Erda 依赖组件的部署节点范围。
提示
请参见 节点需求说明 为各组件选择合适的节点。
第一步:请勿将 Erda 组件及 Erda 依赖组件部署至 Kubernetes 的 Master 节点及集群的 LoadBalancer 绑定的节点。建议为 Kubernetes 的 Master 节点及集群的 LoadBalancer 绑定的节点设置合适的标签:
# 对于 Kubernetes 的 Master 节点打上标签 kubectl label node <node_name> dice/master="" --overwrite # 对于 Kubernetes 的 Master 节点打上标签 kubectl label node <node_name> dice/lb="" --overwrite
第二步:通过节点标签选定部署 Erda 组件及 Erda 依赖组件的节点范围,对各节点执行如下命令以设置标签
dice/platform
:kubectl label node <node_name> dice/platform="" --overwrite
第三步:在第二步选中的节点内,选择用于部署 Cassandra 的节点,设置标签
dice/cassandra
:kubectl label node <node_name> dice/cassandra="" --overwrite
第四步:在第二步选中的节点内,选择用于部署 Elasticsearch 的节点,设置标签
dice/elasticsearch
:kubectl label node <node_name> dice/elasticsearch="" --overwrite
第五步:在第二步选中的节点内,选择用于部署 etcd 的节点,设置标签
dice/etcd
:kubectl label node <node_name> dice/etcd="" --overwrite
第六步:在第二步选中的节点内,选择用于部署 Zookeeper 的节点,设置标签
dice/zookeeper
:kubectl label node <node_name> dice/zookeeper="" --overwrite
第七步:在第二步选中的节点内,选择用于部署 Kafka 的节点,设置标签
dice/kafka
:kubectl label node <node_name> dice/kafka="" --overwrite
# 合理使用存储避免 IO 竞争
当前部署 Erda 时,有状态服务(例如依赖组件及 Erda Pipeline 中的有状态服务)存储卷默认采用 Erda 依赖组件 volume-provisioner 提供的名为 dice-local-volume 的 StorageClass,volume-provisioner 基于特定目录(例如 /data)下的文件系统,通过 dice-local-volume 在该文件系统上以类似 稀疏文件 (opens new window) 的方式创建 PV(例如 /data/pvc-6a7bf08c-00cd-4464-899e-3a82beca8ca8)以使用存储空间。
这类方式并非专为高并发海量 IO 场景设计,若 /data 目录所在的文件系统底层均来自同一硬盘设备(或同一硬盘不同分区构建的设备),则使用 /data 目录所在文件系统的 Pods 将存在 IO 竞争,进而影响 Erda 组件的稳定性以及 QoS。
对于使用外接分布式存储(例如 Ceph)的场景,其 IO 竞争问题不及 Local Volume 方式明显,解决方法也主要针对 Ceph 存储端和网络带宽端,而非 Erda 组件的部署节点。若使用 Local Volume,则 IO 竞争问题的解决与 Erda 组件的部署强相关。因此,可通过如下三种方法解决该问题:
- 通过 StorageClass 实现 IO 隔离
- 通过 RAID 或 LVM 提高 IO 性能、带宽
- 使用高性能存储,如 SATA SSD、PCIe SSD
# 通过不同的 StorageClass 隔离 IO
由各 StorageClass 分别处理不同的磁盘设备,实现 IO 隔离,具体步骤如下:
根据物理磁盘合理构建 StorageClass(此处指用户通过自建 Local PV 的方式构建 Local Volume),可参照下表构建 Local Volume 对应的 StorageClass 对象。
磁盘 节点 1 节点 2 节点 3 对应 StorageClass 名称 备注说明 磁盘设备 /dev/sdb /dev/sdb /dev/sdb sc1 将各节点上的 /dev/sdb 做为资源池,构建 Local Volume 对应的 StorageClass 对象 sc1 磁盘设备 /dev/sdc /dev/sdc /dev/sdc sc2 将各节点上的 /dev/sdc 做为资源池,构建 Local Volume 对应的 StorageClass 对象 sc2 磁盘设备 /dev/sdd /dev/sdd /dev/sdd sc3 将各节点上的 /dev/sdd 做为资源池,构建 Local Volume 对应的 StorageClass 对象 sc3 部署时,通过
helm install
命令为各组件设置不同的 StorageClass。示例如下,为 Cassandra、Elasticsearch、Kafka 设置不同的 StorageClass,通过使用不同的物理存储介质,实现 IO 隔离,避免 IO 竞争。helm install erda erda/erda --set global.domain="erda.io",global.size="prod",erda.clusterName="local-cluster",elasticsearch.StorageClassName="sc1",cacassandra.StorageClassName="sc2",kafka.StorageClassName="sc3" -n erda-system --create-namespace
# 通过 RAID 0 或 LVM 配置底层存储
将底层多个物理磁盘构建为单个逻辑设备(RAID 0 或者 LVM),通过逻辑设备的条带化功能提升 IO 带宽/性能,减少 IO 竞争。
# 使用高性能存储
对于高并发低延迟要求的 IO 场景(例如 etcd)以及高并发高吞吐量(例如 Elasticsearch、Cassandra、Kafka)场景,IO 存储可使用高性能的 SSD 存储,从根本上满足 IO 的高并发、低延迟、高带宽需求。