本文介绍如何在Kubernetes环境中部署SchedulerX,通过SchedulerX可以定时调度您的程序、多语言脚本和HTTP接口,也可以调度原生的K8s Job或者Pod。

前提条件

背景信息

使用SchedulerX调度K8s Job有如下优势:

可在线编辑的脚本Pod

K8s Job常用场景是用来做数据处理和运维,一般以脚本实现居多。原生的使用方式需要把脚本打包到镜像里,在YAML文件中配置脚本命令。如果要修改脚本,就需要重新构建镜像和发布,操作比较复杂。

而使用SchedulerX则无需构建镜像和写YAML脚本,只需要在SchedulerX控制台直接编辑脚本(Shell、Python、PHP和Node.js),即可自动以Pod方式运行脚本。如果要修改脚本,只需要在SchedulerX控制台重新编辑脚本,下次调度自动生效,从而提高了K8s Job的开发效率。同时,使用SchedulerX的K8s任务屏蔽了容器相关的细节,为不熟悉容器服务的用户提供便利。

可视化任务编排

SchedulerX支持通过可视化界面拖拽进行K8s任务的编排,相比于当前主流的通过代码进行工作流编排的解决方案来说,使用更便捷。而且在运行时,可视化的工作流图可以帮助您快速排查任务卡在哪个环节。

123456

报警监控

使用SchedulerX来调度您的Pod或者Job,可以复用SchedulerX的监控报警功能。

  • 支持的报警通道:短信、电话、邮件、Webhook(钉钉/企业微信/飞书)。
  • 支持的报警策略:失败报警、执行超时报警。

日志服务

使用SchedulerX来调度您的Pod或者Job,不需要额外开通日志服务,可以自动采集Pod运行的日志,如果Pod运行失败,可以直接在SchedulerX控制台看到Pod执行失败的原因。16

监控大盘

您可以通过SchedulerX自带的任务监控大盘实时观察您的任务状态。18

离在线混布

SchedulerX支持的Java和K8s任务类型,可以做到离在线定时任务混布调度。一个业务应用通常有很多定时任务,如果调度频率比较高,可以直接和业务应用在一个进程中,但进程内调用会消耗在线应用自身的cpu和内存,无法和在线业务做隔离。所以当一个定时任务非常耗资源,调度频率又不高(比如每小时/每天运行一次)时,可以通过新增一个Pod去运行,这样就和原来的在线应用不在一个进程中了。

步骤一:配置ServiceAccount

SchedulerX K8s任务依赖于ServiceAccount进行验证与授权,而且默认情况下,它使用所在Namespace的SchedulerX ServiceAccount运行K8s任务。

在K8s集群里和对应的Namespace下,运行schedulerx-serviceaccount.yaml(运行一次即可),格式参考如下。

如果每个Namespace做隔离,只能调度自己Namespace下的Pod或者Job,只需要运行如下YAML。

展开查看具体代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: schedulerx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: schedulerx-role
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create","delete","get","list","patch","update"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["watch"]
  - apiGroups: ["batch"]
    resources: ["jobs","cronjobs"]
    verbs: ["create","delete","get","list","patch","update","watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: schedulerx-binding
subjects:
  - kind: ServiceAccount
    name: schedulerx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: schedulerx-role

如果有跨Namespace调度的需求,RoleBinding需要配置多个Namespace。

展开查看具体代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: schedulerx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: schedulerx-role
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create","delete","get","list","patch","update"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["watch"]
  - apiGroups: ["batch"]
    resources: ["jobs","cronjobs"]
    verbs: ["create","delete","get","list","patch","update","watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: schedulerx-binding
subjects:
  - kind: ServiceAccount
    name: schedulerx
    namespace: <NAMESPACE1>
  - kind: ServiceAccount
    name: schedulerx
    namespace: <NAMESPACE2>
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: schedulerx-role

步骤二:接入SchedulerX

通过Deployment部署

如果您是非Java应用,可以通过Deployment部署一个schedulerx-agent.yaml,这样SchedulerX会以单独的Pod启动,原理图如下:2
展开查看schedulerx-agent.yaml配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: schedulerx-agent
  labels:
    app: schedulerx-agent
spec:
  replicas: 1
  selector:
    matchLabels:
      app: schedulerx-agent
  template:
    metadata:
      labels:
        app: schedulerx-agent
    spec:
      serviceAccountName: schedulerx
      containers:
      - name: schedulerx-agent
        image: registry.cn-huhehaote.aliyuncs.com/schedulerx/agent:1.6.0-amd64
        imagePullPolicy: Always
        resources:
          limits:
            cpu: 200m
          requests:
            cpu: 200m
        env:
          - name: "SCHEDULERX_ENDPOINT"
            value: "${SCHEDULERX_ENDPOINT}"
          - name: "SCHEDULERX_NAMESPACE"
            value: "${SCHEDULERX_NAMESPACE}"
          - name: "SCHEDULERX_GROUPID"
            value: "${SCHEDULERX_GROUPID}"
          - name: "SCHEDULERX_APPKEY"
            value: "${SCHEDULERX_APPKEY}"
          - name: "SCHEDULERX_STARTER_MODE"
            value: "pod"
        livenessProbe:
          exec:
            command: ["/bin/bash","/root/health.sh"]
          timeoutSeconds: 30
          initialDelaySeconds: 30
SchedulerX agent image变量说明:
芯片架构 区域 说明
x86_64 公网 registry.cn-hangzhou.aliyuncs.com/schedulerx/agent:1.6.0-amd64
阿里云VPC registry-vpc.{regionId}.aliyuncs.com/schedulerx/agent:1.6.0-amd64
arm64 公网 registry.cn-hangzhou.aliyuncs.com/schedulerx/agent:1.6.0-arm64
阿里云VPC registry-vpc.{regionId}.aliyuncs.com/schedulerx/agent:1.6.0-arm64
SchedulerX agent env变量说明:
变量 说明
${SCHEDULERX_ENDPOINT} 您部署应用的地域(Region)和对应的Endpoint。比如addr-sh-internal.edas.aliyun.com。详情请参见Endpoint列表
${SCHEDULERX_NAMESPACE} Namespace为命名空间ID,可以在SchedulerX控制台的命名空间页面获取。7
${SCHEDULERX_GROUPID} GroupId为应用ID,可以在SchedulerX控制台应用管理页面获取。8
${SCHEDULERX_APPKEY} AppKey为应用Key,可以在SchedulerX控制台应用管理页面获取。9
如果部署Deployment完成,可以在SchedulerX控制台应用管理页面查看实例,代表接入成功。9

通过Java SDK部署

如果您是Java应用,除了想调度K8s任务,还想调度您的Java程序,可以依赖Java SDK。与使用MQ相同,SchedulerX和您的在线业务在一个进程中,原理如下:66

关于SDK接入,请参见Spring Boot应用接入SchedulerX

使用K8s任务还需要依赖一个schedulerx-plugin-kubernetes,比如:
    <dependency>
            <groupId>com.alibaba.schedulerx</groupId>
            <artifactId>schedulerx2-spring-boot-starter</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.schedulerx</groupId>
            <artifactId>schedulerx-plugin-kubernetes</artifactId>
            <version>1.0.1</version>
        </dependency>

部署您应用的Deployment文件,还需要配置serviceAccountName: schedulerx(参考上文非Java应用部署的schedulerx-agent.yaml)。

步骤三:创建K8s任务

Shell脚本

如果想通过Pod运行Shell脚本,不需要自己构建镜像,只需要在任务管理创建一个K8s任务,资源类型选择Shell-Script,镜像默认是busybox(也可以替换为自己的镜像)。a1
单击运行一次,在Kubernetes集群中可以看到Pod启动,Pod名称为schedulerx-shell-{JobId}。7
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志。7

Python脚本

如果想通过Pod运行Python脚本,不需要自己构建镜像,只需要在任务管理创建一个K8s任务,资源类型选择Python-Script,镜像默认是Python(也可以替换为自己的镜像)。a2
单击运行一次,在Kubernetes集群中可以看到Pod启动,Pod名称为schedulerx-python-{JobId}。7
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志。8

PHP脚本

如果想通过Pod运行PHP脚本,不需要自己构建镜像,只需要在任务管理创建一个K8s任务,资源类型选择Php-Script,镜像默认是php:7.4-cli(也可以替换自己的镜像)。a3
单击运行一次,在Kubernetes集群中可以看到Pod启动,Pod名称为schedulerx-php-{JobId}。12
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志8

Node.js脚本

如果想通过Pod运行Node.js脚本,不需要自己构建镜像,只需要在任务管理创建一个K8s任务,资源类型选择Nodejs-Script,镜像默认是node:16(也可以替换自己的镜像)。a4
单击运行一次,在Kubernetes集群中可以看到Pod启动,Pod名称为schedulerx-node-{JobId}。8
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志。8

Job-YAML

通过SchedulerX也可以运行K8s原生的Job,任务类型选择K8s,资源类型选择Job-YAML。a5
单击运行一次,在Kubernetes集群中可以看到Job和Pod启动成功。8
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志。8
注意 通过SchedulerX运行K8s Job,不建议使用CronJob,定时调度需要使用SchedulerX来配置,否则无法收集每次Pod的执行历史和日志。

Pod-YAML

通过SchedulerX也可以运行K8s原生的Pod,任务类型选择K8s,资源类型选择Pod-YAML。a6
单击运行一次,在Kubernetes集群中可以看到Pod启动成功。9
在SchedulerX控制台任务管理页面可以查询历史执行记录,也可以看到Pod运行的日志。9
注意 通过SchedulerX运行K8s Pod,建议不要运行长周期的Pod(比如Web应用,一旦启动永远不会结束),重启策略需要设置成Never(否则Pod会不断重启)。