创建任务

该接口用于创建任务,可以指定任务的运行环境,然后创建和执行任务。

POST

接口路径:http://matpool.com:30100/v1/job

示例:

curl --request POST \
  --url 'http://matpool.com:30100/v1/job' \
  --header 'Authorization: Bearer <YOUR_TOKEN>' \
  --header 'content-type: multipart/form-data' \
  --form 'spec={"diskGB":10}' \
  --form 'envs="FOO=bar;ZZ=qqqqq"' \
  --form 'cmd="<YOUR_CMD>"' \
  --form 'app_name=ubuntu' \
  --form 'app_version=18.04'

准备任务文件

整体流程

任务文件需要先上传到云存储(以下简称'网盘'),再挂载到运行时的容器内

网盘

  • 用户独立的持久化的云存储空间(不同的会员权益限制了大小及用量)
  • 每个用户网盘根目录都为/,但完全隔离
  • 具备用户独有控制权,不会因节点回收而导致数据被移除

由整体流程可知,准备任务文件涉及到两个过程,一个是上传,另一个是挂载,矩池云提供了两种上传任务文件的方式,也提供了灵活的挂载规则

此外,我们有两个目录需要区分,一个是用户的网盘目录(以下简称'网盘目录'),另一个是运行任务容器内的目录(以下简称'容器目录')。

上传文件

  • 上传方式 1: 使用文件存储 API上传和管理需要的任务文件
  • 上传方式 2: 在调用该接口的时候指定上传一个依赖文件的压缩包(*.tar.gz),具体传参方式参见本接口任务文件相关参数

需要注意的是,该压缩包本身不会被保存到网盘,而是在之后会被解压,为了便于理解,可以把上传方式 2 视为压缩包等待被解压(即保存)到网盘中,而解压至哪个目录volumes 参数影响,解压规则在下文中阐述。

挂载

挂载规则由参数 volumes 决定,该参数支持用户把网盘任意目录挂载至容器任意目录,参数形式和默认值参见本接口挂载映射相关参数

挂载和解压规则(步骤)

  1. 默认 volumes 参数的预处理(若指定了 volumes 参数,则跳过这一步)

    • 如果用户调用该接口时上传了文件,那么在用户网盘根目录下会新建一个子目录,目录名为随机字符串,如 /A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D/,此时 volumes 参数相当于被指定为 [{ "src": "/A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D/", "dest": "/mnt" }],进入挂载步骤

    • 如果用户调用该接口时没有上传文件,那么 volumes 参数相当于被指定为 [{ "src": "/", "dest": "/mnt" }],进入挂载步骤

  2. 挂载

    遍历 volumes 参数(数组),根据每一项的映射规则,将 src 字段指定的网盘目录,挂载到 dest 字段指定的容器目录,进入下一步

  3. 解压规则(若未在接口中上传文件,则跳过这一步)

    如果有待解压的文件(即在上传阶段使用了上传方式 2),取 volumes 参数(数组)的第一项,把上传的压缩包文件解压到 src 指定的网盘目录下的 input 目录(input 目录会被自动创建),即对应 dest指定的容器目录下的 input 目录

上传方式和挂载规则组合示例

// 方式 1 上传文件,即不指定上传的任务文件
// 不传 volumes 参数,即采用默认的行为
此时 volumes 参数相当于 [{ "src": "/", "dest": "/mnt" }]

挂载结果:网盘根目录 '/' --> 容器内目录 '/mnt'

---------

// 方式 1 上传文件,即不指定上传的任务文件
// 传 volumes 参数,此时跳过'默认 volumes 参数的预处理'步骤
[
  {"src": "/jobs", "dest": "/myjobs"},
  {"src": "/data", "dest": "/mydata"}
]

挂载结果:
网盘目录 '/jobs' --> 容器内目录 '/myjobs'
网盘目录 '/data' --> 容器内目录 '/mydata'

---------

// 方式 2 上传文件,即指定上传的任务文件,如 task.tar.gz
// 不传 volumes 参数,即采用默认的行为
因为有上传文件,所以会生成随机目录,此时 volumes 参数相当于 [{ "src": "/A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D", "dest": "/mnt" }]

挂载结果:网盘目录 '/A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D' --> 容器内目录 '/mnt'

任务文件 task.tar.gz 被解压到
网盘的 '/A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D/input' 目录,
即对应容器的 '/mnt/input' 目录

---------

// 方式 2 上传文件,即指定上传的任务文件,如 task.tar.gz
// 传 volumes 参数,此时跳过'默认 volumes 参数的预处理'步骤
[
  {"src": "/jobs", "dest": "/myjobs"},
  {"src": "/data", "dest": "/mydata"}
]

挂载结果:
网盘目录 '/jobs' --> 容器内目录 '/myjobs'
网盘目录 '/data' --> 容器内目录 '/mydata'

任务文件 task.tar.gz 被解压到网盘的 '/jobs/input' 目录,
即对应容器的 '/myjobs/input' 目录
Required Name Value Description
✔︎ Authorization Bearer <token> 用户鉴权

Body(formdata)

该 API 的 Request Body 为 formdata 的形式,可以指定以下的内容。

规格和环境变量

Required Name type Example Description
✔︎ spec string {"diskGB":10,"gpus":2} json 字符串,指定任务所需的最小资源要求,当前支持字段:diskGB:使用的磁盘大小,gpus:使用的 GPU 个数。不需要做限制的参数直接不传即可,比如 {"diskGB":10} 表示不需要对使用的 GPU 个数做限制
env string FOO=aa;BAR=bb 注入到容器的环境变量,多个环境变量分号分隔

任务文件

任务文件的准备上面已经进行了详细阐述,如果用户需要在创建任务的时候同时上传任务文件,则需要上传以下两个字段的内容

Required Name type Example Description
file_name string files.tar.gz 指明要上传的文件名,当前仅支持 *.tar.gz 格式
file file - 对应要上传的压缩包文件

挂载映射

该参数支持用户任意网盘目录挂载至容器内任意目录,如需自定义网盘目录挂载至容器目录,则需提供如下字段,该字段为 json 字符串,整体是一个数组形式,每一项是一个对象,指定了网盘目录容器目录映射,如果未指定该参数或指定为空数组[])则采用默认行为。

默认挂载行为:

  • 如果在调用该接口的时候上传了任务文件,用户网盘根目录下会生成一个目录,目录名为随机字符串,如 /A2BF38EE-AB7B-48A3-92E5-FF9AFB26423D,然后把这个目录挂载到容器的 /mnt 目录
  • 如果没有在调用接口的时候上传任务文件,那么就把用户网盘根目录 / 挂载到容器目录 /mnt
Required Name type Example Description
volumes string [{"src":"/data","dest":"/home/data","readOnly":false},{"src":"/doc","dest":"/home/doc","readOnly":true}] 提供自定义挂载映射,若 src 指定的目录在网盘内不存在,则自动创建该目录。readOnlytrue 表示只读挂载,默认为 false

端口导出

该参数支持用户访问容器任意端口,如需访问容器端口,则需提供如下字段,该字段为 json 字符串,整体是一个数组形式,每一项是一个对象,指定了要导出的容器端口访问协议以及拓展信息,如果未指定该参数或指定为空数组[])则不导出任何容器端口。

Required Name type Example Description
ports string [{"port":22,"protocol":1,"extraData":{"pubKey":{"key":"my_public_key"}}},{"port":8888,"protocol":2}] protocol 字段, 1 表示 ssh, 2 表示 http。如果是 ssh 协议,则可以通过 extraData 字段传入公钥,对应的公钥会做为容器中环境变量 PUBLIC_KEY 的值。一个任务只支持导出一个 ssh 访问的端口

指定镜像

用户必须指定需要运行的容器依赖的 Docker 镜像,根据镜像仓库是否为私有,可以分为以下两种:

  • 私有仓库

    假设想使用一个私有仓库的镜像: <YOUR_PRIVATE_DOCKER_REGISTRY>/<PATH>/<IMAGE>:<TAG>,那么需要传入登录镜像仓库的用户名和密码,相关的参数对应如下:

    • app_name: <PATH>/<IMAGE>
    • app_version: <TAG>
    • hostname: <YOUR_PRIVATE_DOCKER_REGISTRY>
    • creds: {"user": "<YOUR_USERNAME>", "psw": "<YOUR_PASSWD>"}
  • 公共仓库

    假设想使用一个公共仓库的镜像: <PUBLIC_DOCKER_REGISTRY>/<PATH>/<IMAGE>:<TAG>,那么不需要传入登录镜像仓库的用户名和密码(即 creds 字段),也不需要传入 hostname 字段,相关的参数对应如下:

    • app_name: <PUBLIC_DOCKER_REGISTRY>/<PATH>/<IMAGE>
    • app_version: <TAG>
Required Name type Example Description
✔︎ app_name string ubuntu 所用的镜像名,取决于镜像
✔︎ app_version string 18.04 所用的镜像的版本号
hostname string somewhere.registry.com 私有仓库需要指定的镜像仓库地址
creds string {"user": "uu", "psw": "123"} json 字符串,登录私有仓库的用户名和密码
cmd string echo 'hello' 要在容器中运行的命令,如果没有指定,则运行指定的镜像内默认的命令

Response

Normal

job.status 的含义:

  • 1:排队中
  • 2:已调度
  • 3:运行中
  • 4:已完成
  • 5:已取消
  • 6:初始化中

code = 0

示例:

{
    "code":0,
    "msg":"",
    "job":{
        "id":525,
        "ctx":{
            "ownerId":1,
            "nodeId":-1
        },
        "state":{
            "status":1, // 当前状态
            "log":[ // 状态变更记录,以及发生变更时的时间戳
                {
                    "id":2574,
                    "status":6,
                    "ts":{
                        "seconds":1562317937
                    },
                    "sourceId":525
                },
                {
                    "id":2575,
                    "status":1,
                    "ts":{
                        "seconds":1562317937
                    },
                    "sourceId":525
                }
            ]
        },
        "status":1, // 当前状态
        "app":{ // 调用接口时传入的镜像信息
            "name":"ubuntu",
            "ver":"18.04",
            "envs":"FOO=aa;BAR=bb",
            "format":2,
            "files":{
                "mnt":"/mnt",
                "input":"",
                "output":"",
                "stdout":"",
                "stderr":""
            },
            "cmd":"echo 'hello'",
            "hostname":"",
            "creds":"",
            "ports": [ // 调用接口时传入的端口导出信息
                {
                    "port": 22,
                    "protocol": 1,
                    "extraData": {
                        "pubKey": {
                            "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDmWeBdQxb4YJcus4VPmqPz254lvHeuMEMeJbTDl2ZD6DXdxB+UytLWTJEjt/uiDDI1RusAf3PnURvNW/f3Juu3U3ghFFqLhRCsKat4XZL1xxyp1T2BHj4IPxhqRMAMBye5EAxxGzm2BOqAOGNV986NipppMLPTNaAfgRpDUw7n8sPWtxMoHsHiu+BDAfmEM6153b/HywcpLURuc006ZC346tkARKPXcTeD8/9mQJn5sJwuLl6VW+k/lhYabWztatI1vfOe3ce6HkomUKWUsP7xKxkDstEwT4u0qPYyX0vTJtUWWJ1nLnCISdA4ctvpY0RvMtxYkOTymNkpV/++aYJ1 huangzhiran@huangzhiran"
                        }
                    }
                },
                {
                    "port": 8888,
                    "protocol": 2,
                    "extraData": null
                }
            ],
            "urls": { // 导出的端口所对应的URL,访问该URL即可访问到容器对应的端口。key 为端口号加 port_ 前缀拼接成的字符串
                "port_22": {
                    "urls": [
                        "ssh://matpool.com:34707"
                    ]
                },
                "port_8888": {
                    "urls": [
                        "https://matpool.com:40977?token=4WZwUTNLy4"
                    ]
                }
            }
        },
        "res":{ // 镜像运行需要的资源信息
            "cpus":0,
            "gpus":0,
            "diskGB":10
        },
        "createTime":{ // 创建时间
            "seconds":1562317937
        },
        "vols": [
            {
                "src": "/",
                "dest": "/mnt",
                "readOnly": false
            }
        ],
        "queueLen": 0
    }
}

Exception

code = 1 || 7

参见 全局错误码

上次修改: 2019-11-11 21:16