简介
K8s Job是Kubernetes中的一种资源,用来处理短周期的Pod,相当于一次性任务,跑完就会把Pod销毁,不会一直占用资源,可以节省成本,提高资源利用率。
阿里任务调度SchedulerX和云原生结合,重磅推出可视化k8s任务,针对脚本使用者,屏蔽了容器服务的细节,不用构建镜像就可以让不熟悉容器的同学(比如运维和运营同学)玩转k8s Job,受益容器服务带来的降本增效福利。针对容器使用者,SchedulerX不但完全兼容原生的k8s Job,还能支持历史执行记录、日志服务、重跑任务、报警监控、可视化任务编排等能力,为企业级应用保驾护航。架构图如下:
特性一:快速开发k8s可视化脚本任务
Kubernetes的Job,常见用来做离线数据处理和运维工作(比如每天凌晨2点把mysql数据同步到大数据平台,每隔1小时更新一次redis缓存等),一般以脚本实现居多。这里以一个简单的场景举例子,来对比两种方案的差异。
Kubernetes原生解决方案
K8s调度的最小单位是Pod,想跑脚本任务,需要提前把脚本打包到镜像里,然后在YAML文件中配置脚本命令,下面以通过python脚本查询数据库为例子:
- 编写python脚本demo.py
#!/usr/bin/python# -*- coding: UTF-8 -*-importMySQLdb# 打开数据库连接db=MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) # 使用cursor()方法获取操作游标 cursor=db.cursor() # SQL 查询语句sql="SELECT * FROM EMPLOYEE \WHERE INCOME > %s"% (1000) try: # 执行SQL语句cursor.execute(sql) # 获取所有记录列表results=cursor.fetchall() forrowinresults: fname=row[0] lname=row[1] age=row[2] sex=row[3] income=row[4] # 打印结果print"fname=%s,lname=%s,age=%s,sex=%s,income=%s"% \ (fname, lname, age, sex, income ) except: print"Error: unable to fetch data"# 关闭数据库连接db.close()
- 编写Dockerfile
FROM python:3 WORKDIR /usr/src/app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY demo.py /root/demo.py CMD [ "python", "/root/demo.py" ]
- 制作docker镜像,推到镜像仓库中
docker build -t registry.cn-beijing.aliyuncs.com/demo/python:1.0.0 . docker push registry.cn-beijing.aliyuncs.com/demo/python:1.0.0
- 编写k8s Job的YAML文件,image选择第3步制作的镜像,command的命令为执行脚本
apiVersion batch/v1 kind Job metadata name demo-python spec template spec containersname demo-python image registry.cn-beijing.aliyuncs.com/demo/python1.0.0 command"python""/root/demo.py" restartPolicy Never backoffLimit4
我们看到要在容器服务中跑脚本,需要这么多步骤,如果要修改脚本,还需要重新构建镜像和重新发布k8s Job,非常麻烦。
阿里云解决方案
阿里任务调度SchedulerX结合云原生技术,提出了一套可视化的脚本任务解决方案,通过任务调度系统来管理脚本,直接在线编写脚本,不需要构建镜像,就可以将脚本以Pod的方式在用户的k8s集群当中运行起来,使用非常方便,如下图:
- 在SchedulerX任务管理新建一个k8s任务,资源类型选择Python-Script(当前支持shell/python/php/nodejs四种脚本类型)
- 点击运行一次,在kubernetes集群中可以看到pod启动,pod名称为schedulerx-python-{JobId}
- 在SchedulerX控制台也可以看到历史执行记录
- 在SchedulerX控制台可以看到Pod运行的日志
下面通过一个表格更方便的看到两个方案的差异
Kubernetes原生解决方案 |
阿里云解决方案 |
|
脚本管理 |
不支持 |
支持,通过SchedulerX控制台可以进行脚本管理 |
开发效率 |
慢,每次修改脚本都需要重新构建镜像 |
快,在线修改脚本,不需要构建镜像,自动部署 |
学习成本 |
高,需要学习docker和kubernetes等容器相关知识 |
低,不需要容器相关知识,会写脚本就行 |
历史记录 |
最近3次 |
最近100次 |
日志 |
最近3次 |
最近2周 |
报警 |
不支持 |
支持
|
特性二:完全兼容原生K8s Job
SchedulerX不但能够快速开发k8s脚本任务,屏蔽容器服务的细节,给不熟悉容器服务的同学带来福音,同时还能托管原生k8s Job。
原生自带的Job方案
Job
以官方提供的Job为例
- 编写YAML文件pi.yaml,故意写一个错误,bpi(-1)是非法的
apiVersion batch/v1 kind Job metadata name pi spec template spec containersname pi image perl5.34 command"perl""-Mbignum=bpi""-wle""print bpi(-1)" restartPolicy Never backoffLimit4
- 在k8s集群中运行该Job,并查看Pod的状态和日志
K8s原生的Job不支持重跑,修改完Job后想要重跑,需要先删除,再重新apply,非常麻烦。
CronJob
以官方提供的CronJob为例
- 编写hello.yaml
apiVersion batch/v1 kind CronJob metadata name hello spec schedule"* * * * *" jobTemplate spec template spec containersname hello image perl5.34 command"perl""-Mbignum=bpi""-wle""print bpi(100)" restartPolicy OnFailure
- 在k8s集群中运行该CronJob,查看pod历史记录和日志
发现原生的CronJob只能查看最近3次执行记录,想要查看更久之前的记录无法看到,这在业务出现问题想排查的时候就变得尤为困难。
阿里云解决方案
阿里任务调度SchedulerX可以托管原生k8s任务,方便移植,使用SchedulerX托管,可以享有任务调度的特性,比如任务重跑、历史记录、日志服务、报警监控等。
- 新建k8s任务,任务类型选择k8s,资源类型选择Job-YAML,打印bpi(-1)
- 通过工具来生成cron表达式,比如每小时第8分钟跑
- 调度时间还没到,也可以手动点击“运行一次”来进行测试
- 在k8s集群中可以看到Job和Pod启动成功
- 在SchedulerX控制台也可以看到历史执行记录
- 在SchedulerX控制台可以看到任务运行日志
- 在线修改任务的YAML,打印bpi(100)
- 不需要删除Job,通过控制台来重跑任务
- 任务重跑成功,且能看到新的日志
下面通过一个表格来对比两个方案的差异
原生自带的Job方案 |
阿里云解决方案 |
|
测试开发(运行一次) |
不支持 |
支持 |
重跑任务 |
不支持 |
支持 |
Cron定时调度 |
支持,YAML配置 |
支持,控制台通过工具生成,可动态修改 |
历史记录 |
最近3次 |
最近100次 |
日志 |
最近3次 |
最近2周 |
报警 |
不支持 |
支持
|
特性三:增强原生Job,支持可视化任务编排
在数据处理场景下,任务之间往往有依赖关系,比如A任务依赖B任务的完成才能开始执行。
Kubernetes原生解决方案
当前k8s中主流的解决方案是使用argo进行工作流编排,比如定义一个DAG如下:
# The following workflow executes a diamond workflow# # A# / \# B C# \ /# DapiVersion argoproj.io/v1alpha1 kind Workflow metadata generateName dag-diamond spec entrypoint diamond templatesname diamond dag tasksname A template echo arguments parameters name message value Aname B depends"A" template echo arguments parameters name message value Bname C depends"A" template echo arguments parameters name message value Cname D depends"B && C" template echo arguments parameters name message value Dname echo inputs parametersname message container image alpine3.7 command echo"{{inputs.parameters.message}}"
我们看到构建这么简单的一个DAG,就需要写这么多YAML,如果依赖关系复杂,则YAML就变得非常难维护。
阿里云解决方案
阿里任务调度SchedulerX支持通过可视化的工作流进行任务编排
- 创建一个工作流,可以导入任务,也可以在当前画布新建任务,通过拖拽构建一个工作流
- 点击运行一次,可以实时看到工作流的运行情况,方便排查任务卡在哪个环节:
- 如果有任务失败了,通过控制台查看日志
- 把任务修改正确,在工作流实例图上,原地重跑失败的节点
- 失败的任务会重新按照最新的内容执行
- 当上游都执行成功,下游就可以继续执行了
总结
通过任务调度SchedulerX来调度你的k8s任务,能够降低学习成本,加快开发效率,让你的任务失败可报警,出问题可排查,打造云原生可观测体系下的可视化k8s任务。