点亮 ⭐️ Star · 照亮开源之路
https://github.com/apache/dolphinscheduler
![image.png](https://dev-media.amazoncloud.cn/b34ab3f100d04c75be7a19797bd0f4b2_image.png "image.png")
## 1. 背景介绍
在数仓 ETL、离线及实时计算的场景下,数据任务的依赖调度关系越来越复杂。在AWS平台上提供了托管的 Apache Airflow(MWAA)与 Step function、Glue Workflow 等具有一定调度编排任务的工具,但在可视化一体管理操作上的支持都有一定的限制缺失。Apache DolphinScheduler 旨在解决复杂的大数据任务依赖关系,并为应用程序提供数据和各种 OPS 编排中的关系,以及化解数据研发 ETL 依赖错综复杂,无法监控任务健康状态的问题。
为引入 Apache DolphinScheduler,同时考虑生产的健壮性及维护简易性,本文提供了在 AWS 平台上使用完全[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)的 EKS on Fargate 容器服务及 Aurora Serverless PostgreSQL 数据库进行部署的方案,并给出详细的部署步骤及维护指南。
### 1.1 DolphinScheduler 介绍
Apache DolphinScheduler 是一个分布式和可扩展的开源工作流协调平台,具有强大的 DAG 可视化界面。DolphinScheduler 以 DAG(Directed Acyclic Graph,DAG)流式方式组装任务,可以及时监控任务的执行状态,支持重试、指定节点恢复失败、暂停、恢复、终止任务等操作。
DolphinScheduler 架构主要包含 MasterServer、WorkerServer、AlertServer、ApiServer、ZooKeeper 与 UI。其中 MasterServer 与WorkerServer 采用分布式无中心设计理念分别负责任务切分、任务提交监控及任务的执行和提供日志服务。AlertServer 主要负责处理前端 UI 层的请求。该服务统一提供 RESTful api 向外部提供请求服务。AlertServer 提供告警服务。系统中的 MasterServer 和 WorkerServer 节点都通过 ZooKeeper 来进行集群管理和容错。架构设计图如下:
图片
![image.png](https://dev-media.amazoncloud.cn/90743d32250e47be97fe94278d7d6877_image.png "image.png")
### 1.2 AWS 无服务器容器 EKS on Fargate 介绍
[AWS Fargate](https://aws.amazon.com/cn/fargate/?trk=cndc-detail) 是一种为容器按需提供大小合适的计算容量的技术。使用 [AWS Fargate](https://aws.amazon.com/cn/fargate/?trk=cndc-detail),用户不必再自己预置、配置或扩展虚拟机组即可运行容器。也无需再选择服务器类型、确定扩展节点组的时间和优化集群打包。用户可以控制要在 Fargate 上启动的 pods,以及它们如何利用Fargate 配置文件运行。Fargate 配置文件被定义为 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 集群的一部分。
[Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 使用由 AWS 构建的控制器(使用 Kubernetes 提供的上游可扩展模型)将 Kubernetes 与 [AWS Fargate](https://aws.amazon.com/cn/fargate/?trk=cndc-detail) 集成。这些控制器作为 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 托管 Kubernetes 控制面板的一部分运行,负责将本机 Kubernetes pods 安排到 Fargate 上。除了若干转换和验证准入控制器外,Fargate 控制器还包括一个与默认 Kubernetes 调度器一起运行的新调度器。当您启动满足 Fargate 上的运行条件的 pod 时,集群中运行的 Fargate 控制器会识别、更新 pod 并将其安排到 Fargate 上。
###
### 1.3 AWS 无服务器数据库 Aurora Serverless 介绍
[Amazon Aurora](https://aws.amazon.com/cn/rds/aurora/?trk=cndc-detail) Serverless 是 [Amazon Aurora](https://aws.amazon.com/cn/rds/aurora/?trk=cndc-detail) 的一种按需自动扩展配置版本。[Amazon Aurora](https://aws.amazon.com/cn/rds/aurora/?trk=cndc-detail) Serverless 会根据应用程序的需求自动启动、关闭以及扩展或缩减容量。用户可以在 AWS 上运行数据库,而无需管理数据库容量。借助 Aurora Serverless,用户可以创建数据库,指定所需的数据库容量范围,然后连接到应用程序。只需在数据库处于活动状态期间按照每秒使用的数据库容量进行付费,并且只需在 Amazon Relational Database Service([Amazon RDS](https://aws.amazon.com/cn/rds/?trk=cndc-detail))控制台中执行几个步骤即可在标准配置和[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)配置之间进行迁移。
## 2. 部署说明
### 2.1 整体部署架构
![image.png](https://dev-media.amazoncloud.cn/949c9356f6b54eb7bf4f5d017df66ef6_image.png "image.png")
1. EKS 集群位于两个可用区,部署在私有子网内,使用 ECR 镜像仓库管理 DolphinScheduler 镜像;
2. EKS 使用 fargate 节点,持久化存储挂载在 EFS,资源存储使用 S3 对象存储服务,使用 Aurora Serverless pgsql 提供元数据库;
3. DolphinScheduler api、worker 及 master 节点通过跳板机 kubectl 命令进行扩缩容;
4. 使用 aws load balancer controller 部署 internet-facing 负载均衡,代理api ui 对外提供访问。
### 2.2 准备工作
- 网络规划,以美东 1(us-east-1)为例,创建 vpc 网络:10.9.0.0/16 ,其中公有网段处于两个 AZ,10.9.1.0/24 与 10.9.2.0/24 ,Pod 网段 10.9.10.0/24 与 10.9.11.0/24,Node 网段 10.9.20.0/24 与 10.9.21.0/24,服务网段由EKS集群生成为虚拟网段,不在VPC子网里。在VPC中创建互联网网关,在公有子网中创建NAT网关,并创建一台跳板机服务器进行命令行管理。添加路由表,公有子网关联互联网网关,其它子网默认通过NAT网关访问互联网服务。
- EKS 集群创建
方便地使用 AWS console 创建 EKS 集群,关联上述 VPC 及子网(参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/create-cluster.html),并在跳板机中配置与集群通信。本文使用 EKS 1.24 版本。
- 数据库及存储服务
同样使用 AWS console 在 VPC 私有子网中创建[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)Aurora PostgreSQL 数据库集群(参考:https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.create-cluster.html)。本文使用 aurora-postgresql 14.4 版本。
![image.png](https://dev-media.amazoncloud.cn/17494969a7764c7192575b4f24057be6_image.png "image.png")
- 构建 DolphinScheduler 自定义镜像
为了后续基于官方开源镜像做定制化,使用 AWS ECR 进行镜像管理,分别创建 DolphinScheduler 镜像 ECR 仓库,将官方镜像 push 上去(参考:https://docs.aws.amazon.com/zh_cn/AmazonECR/latest/userguide/docker-push-ecr-image.html)。本文使用 DolphinScheduler 3.1.2版本。
![image.png](https://dev-media.amazoncloud.cn/b136ecc254ae4048b73e4c690f41181a_image.png "image.png")
### 2.3 安装AWS load balancer controller
1. 在 EKS 集群关联 OIDB 身份提供商。[Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 支持使用 OpenID Connect (OIDC) 身份提供商作为对您的集群的用户进行身份验证的方法。EKS 集群具有与其关联的 (OIDC)颁发者 URL。要将 [AWS Identity and Access Management](https://aws.amazon.com/cn/iam/?trk=cndc-detail)(IAM)角色用于服务账户,集群必须存在 IAM OIDC 提供商。使用 eksctl 或 AWS Management Console 为集群创建 OIDC 提供商。(参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)
2. 按官方文档步骤,创建 IAM 角色,在 AWS Load Balancer Controller 的 kube-system 命名空间中创建名为 aws-load-balancer-controller 的 Kubernetes 服务账户,并使用 IAM 角色的名称注释 Kubernetes 服务账户。使用helm 安装AWS Load Balancer Controller。(参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/aws-load-balancer-controller.html)
### 2.4 使用helm部署Dolphinscheduler
1. 下载源码包 apache-dolphinscheduler--src.tar.gz 3.1.2 版本(https://dolphinscheduler.apache.org/zh-cn/download/3.1.2)。解压到跳板机上。
```
\$ tar -zxvf apache-dolphinscheduler-<version>-src.tar.gz
\$ cd apache-dolphinscheduler-<version>-
src/deploy/kubernetes/dolphinscheduler
```
2. 修改配置文件 values.yaml
```
##修改镜像仓库地址为AWS ecr
image:
registry: "xxxxxx.dkr.ecr.us-east-1.amazonaws.com" -- ECR镜像地址
tag: "3.1.2"
##使用外部数据源
postgresql:
enabled: false
mysql:
enabled: false
externalDatabase:
type: "postgresql"
host: "dolphinscheduler.cluster-xxxxx.us-east-1.rds.amazonaws.com"
port: "5432"
username: "postgres"
password: "xxxxxxxx"
database: "dolphinscheduler"
params: "characterEncoding=utf8"
## 使用S3 存储资源文件
conf:
common:
resource.storage.type: S3
resource.aws.access.key.id: xxxxxxx
resource.aws.secret.access.key: xxxxxxxxx
resource.aws.region: us-east-1
resource.aws.s3.bucket.name: dolphinscheduler-resourse
resource.aws.s3.endpoint: https://S3.us-east-1.amazonaws.com
```
3. 设置 alert、api、worker、master 服务资源需求:
```
master:
resources:
limits:
memory: "8Gi"
cpu: "4"
requests:
memory: "2Gi"
cpu: "500m"
worker:
resources:
limits:
memory: "8Gi"
cpu: "4"
requests:
memory: "2Gi"
cpu: "500m"
api:
...
alert:
...
```
4. 创建命名空间 dolphinscheduler
```
\$ kubectl create namespace dolphinscheduler
```
5. 创建 fargate 配置文件,分别定义关联命名空间 dolphinscheduler 与 kube-system 的 Fargate 配置文件,以指定在启动时哪些 pods 使用 Fargate,然后在集群中的 Fargate 上安排 pods。(参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/fargate-profile.html)
6. 将dolphinscheduler发布到dolphinscheduler的命名空间中
```
\$ cd apache-dolphinscheduler-<version>-src/deploy/kubernetes/dolphinscheduler
\$ helm repo add bitnami https://charts.bitnami.com/bitnami
\$ helm dependency update .
\$ helm install dolphinscheduler . --set image.tag=3.1.2 -n dolphinscheduler --set region=us-east-1 --set vpcId=vpc-xxx
```
7. 创建网络负载均衡器,提供外部访问 uri
```
\$ echo "
apiVersion: v1
kind: Service
metadata:
namespace: dolphinscheduler
name: service-dolphinscheduler
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/subnets: subnet-xxx,subnet-xxx
spec:
ports:
- port: 12345
targetPort: 12345
protocol: TCP
type: LoadBalancer
selector:
app.kubernetes.io/name: dolphinscheduler-api
" | kubectl apply -f -
```
获取负载均衡 dns 服务地址
```
\$ kubectl get service service-dolphinscheduler -n dolphinscheduler
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-service LoadBalancer 10.9.240.137 k8s-nlbsampl-nlbsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.region-code.amazonaws.com 12345:32400/TCP 16h
```
访问 dolphinscheduler 地址:http://k8s-nlbsampl-nlbsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.region-code.amazonaws.com:12345/dolphinscheduler/ui
![image.png](https://dev-media.amazoncloud.cn/fcddf8e9a55241e69ed397c86669f426_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/d66ff981c1e04be9903b6535b9016400_image.png "image.png")
### 2.5 连接Amazon Athena 数据源测试
1. 安装 Athena JDBC 驱动到 api server 与 worker server,创建 DockerFile 重新 build 镜像并推送到 ECR 仓库中。
```
##示例worker镜像 DokcerFile
FROM dolphinscheduler.docker.scarf.sh/apache/dolphinscheduler-worker:3.1.2
RUN apt-get update && \\
apt-get install -y --no-install-recommends python3 && \\
apt-get install -y --no-install-recommends python3-pip && \\
rm -rf /var/lib/apt/lists/*
RUN cd /opt/dolphinscheduler/libs/ && \\
wget https://s3.cn-north-1.amazonaws.com.cn/athena-downloads-cn/drivers/JDBC/SimbaAthenaJDBC-2.0.31.1000/AthenaJDBC42.jar
```
2. 更新 dolphinscheduler
```
helm upgrade dolphinscheduler
```
3. 创建 Athena 连接并测试
![image.png](https://dev-media.amazoncloud.cn/b15f5074dd054e5685f597614448104c_image.png "image.png")
4. 执行工作流查看日志
![image.png](https://dev-media.amazoncloud.cn/2cb412b0c60f4fe4ba5b78ad03ec5ea5_image.png "image.png")
## 3. FAQ
### 3.1 如何安装依赖包及插件?
通过重新编辑镜像进行依赖包安装,通常仅需更新 worker server 镜像即可。示例参考本文 2.5 章节。
### 3.2 如何进行节点扩缩容?
在跳板机执行 kubectl 命令进行扩缩容
```
## 扩缩容 api 至3个副本
kubectl scale --replicas=3 deploy dolphinscheduler-api -n dolphinscheduler
## 扩缩容 master 至2个副本
kubectl scale --replicas=2 sts dolphinscheduler-master -n dolphinscheduler
## 扩缩容 worker 至2个副本
kubectl scale --replicas=6 sts dolphinscheduler-worker -n dolphinscheduler
```
###
### 3.3 如何持久化服务存储?
1. 安装EFS CSI 驱动程序(参考:https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/efs-csi.html)
2. 创建 efs 文件系统及接入点(参考:https://docs.aws.amazon.com/zh_cn/efs/latest/ug/creating-using.html)
3. 创建 PersistentVolume
```
echo "
apiVersion: v1
kind: PersistentVolume
metadata:
name: dolphin-efs-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
csi:
driver: efs.csi.aws.com
volumeHandle: fs-xxx::fsap-xxx // fsap
" | kubectl apply -f -
```
4. 修改 values.yaml 及 template/pvc-xx.yaml 文件,开启服务持久化存储并关联 PersistentVolume
```
sharedStoragePersistence: enabled: true mountPath: "/opt/soft" accessModes: - "ReadWriteMany" ## storageClassName must support the access mode: ReadWriteMany storageClassName: "efs-sc" storage: "20Gi"
{{- if .Values.common.sharedStoragePersistence.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "dolphinscheduler.fullname" . }}-shared
labels:
app.kubernetes.io/name: {{ include "dolphinscheduler.fullname" . }}-shared
{{- include "dolphinscheduler.common.labels" . | nindent 4 }}
annotations:
"helm.sh/resource-policy": keep
spec:
accessModes:
{{- range .Values.common.sharedStoragePersistence.accessModes }}
- {{ . | quote }}
{{- end }}
storageClassName: {{ .Values.common.sharedStoragePersistence.storageClassName | quote }}
volumeName: dolphin-efs-pv
resources:
requests:
storage: {{ .Values.common.sharedStoragePersistence.storage | quote }}
{{- end }}
```
5. 使用 helm 部署或更新。
### 3.4 如何寻求支持帮助?
1. 有关 AWS 平台服务通过 AWS Support 寻求专家指导 https://aws.amazon.com/cn/premiumsupport/
2. 有关 DolphinScheduler 通过 GitHub issue 进行交流 https://github.com/apache/dolphinscheduler
### 4. 参考链接
- Dolphinschduler架构设计:https://DolphinScheduler.apache.org/zh-cn/docs/3.1.2/architecture/design
- EKS 子网tag 方案:https://aws.amazon.com/cn/premiumsupport/knowledge-center/eks-load-balancer-controller-subnets/
- Running stateful workloads with [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) on [AWS Fargate](https://aws.amazon.com/cn/fargate/?trk=cndc-detail) using [Amazon EFS](https://aws.amazon.com/cn/efs/?trk=cndc-detail):https://aws.amazon.com/blogs/containers/running-stateful-workloads-with-amazon-eks-on-aws-fargate-using-amazon-efs/
- AWS 上的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail):https://aws.amazon.com/cn/serverless/