跳到主要内容

端口

在模板上声明一个端口,Superheat 就会在实例启动时发布它,把容器端口映射到你租用的机器上的一个主机端口。你的工作负载监听的、并且希望从外部访问的任何东西——推理服务、Web 界面、指标端点——都需要在这里有一行。

声明一个端口​

端口部分的每一行有五个部分。

组成部分接受值含义
容器端口1 到 65535你的进程在容器内部监听的端口。
协议tcp、udp、http、https该端口提供什么服务。http 和 https 通过 TCP 发布;这个区分记录了意图,并决定控制台如何呈现该端口。
标签最多 64 个字符一个便于人读的名字,显示在模板详情页。部分取值是保留的——见下文。
公开开关,默认打开记录在端口条目上。
访问控制开放、访问代理或应用校验令牌(即 API 的 auth:不设、proxy 或 app)这个端口是否要求实例访问令牌,以及由谁检查。参见要求访问令牌。

你只声明容器端口。主机端口在启动时从机器已发布的端口范围中分配,你事先不会知道它。在容器内部,每个已发布的 TCP 端口都可以通过 SUPERHEAT_TCP_PORT_<container_port> 读取:

echo "$SUPERHEAT_TCP_PORT_7860"

这个环境变量就是你在工作负载内部读取主机端口的方式。实例页面的连接标签页会给出 SSH 命令,以及在模板有的情况下给出打开或打开 JupyterLab 链接。参见端口与网络。

标签​

标签会被去掉首尾空白并在比较时忽略大小写,其中六个映射到四种保留角色。

标签效果
open、open_button、open-button让该端口成为打开按钮的目标。端口以 open_button 角色发布,其端口号会作为 OPEN_BUTTON_PORT 传给容器。
ssh以 ssh 角色发布。
jupyter以 jupyter 角色发布。
app以 app 角色发布——这是默认值。
其他任意值保留为显示标签;端口以 app 角色发布。

所以标签为 Jupyter、jupyter 或 JUPYTER 的端口含义完全相同,而 Gradio UI 只是一个带友好名字的普通 app 端口。

你不需要声明的端口​

启动模式会前置它们需要的端口。在 ssh 模式下,容器端口 22 会自动加上。在 jupyter 模式下,22 和 8080 都会加上。你自己再声明一遍无害但多余:列表会按容器端口和协议去重,隐式条目胜过普通的 app 条目。

优先级从高到低是 ssh 和 jupyter,然后是 open_button,然后是 app。这正是让模板既能在列表里声明一个端口、又能把打开按钮指向它的机制——保留下来的条目带的是 open_button 角色。

在 args 模式下不会前置任何端口。如果你希望 args 模板能被 SSH 访问,就得自己负责在镜像里运行一个 SSH 服务并自己声明端口,否则应该改用 ssh 模式配一个派生自基础镜像的镜像。

打开按钮的端口​

当模板指定了目标端口时,控制台会在实例上显示一个打开按钮。设置方法是给恰好一个端口打上 open 标签:

{
"ports": [
{ "container_port": 7860, "protocol": "http", "label": "open", "public": true },
{ "container_port": 9090, "protocol": "http", "label": "metrics", "public": true }
]
}

如果给多个端口都打上 open 标签,列表中的最后一个胜出,而这很少是你想要的。只声明一个。

在 jupyter 模式下你根本不需要打开按钮端口——控制台会根据 jupyter 角色渲染出打开 JupyterLab,URL 里已经带好了访问令牌。参见 JupyterLab。访问代理后面的打开按钮端口,URL 里同样会带上令牌。

要求访问令牌​

已发布的端口,任何找到机器地址和端口的人都能访问。每个实例都可以有一个自己的密钥,即访问令牌,端口的 auth 字段决定这个端口怎样要求它:

访问控制(auth)谁来检查令牌模板要做什么
访问代理(proxy)Superheat 基础镜像里的访问代理。它占着已发布的端口,只把带有令牌的请求——打开按钮带的 ?token=、它换成的 cookie,或者 Authorization: Bearer——转给应用使用基于基础镜像的镜像,并让应用在 "${SUPERHEAT_APP_HOST:-0.0.0.0}" 上启动——例如 --listen "${SUPERHEAT_APP_HOST:-0.0.0.0}"。基础镜像运行代理时会把这个变量设为 127.0.0.1。如果应用仍然在受保护的端口上绑定 0.0.0.0,它会启动失败,而不是在不认证的情况下提供服务
应用校验令牌(app)应用自己把令牌接进应用自己的认证:值恰好为 ${SUPERHEAT_ACCESS_TOKEN} 的环境变量会在部署时被替换成令牌,容器里也会为 args_str 和 onstart 设置 $SUPERHEAT_ACCESS_TOKEN。应用的检查必须覆盖每一个路由
开放(不设)没有人什么都不用做。端口照旧发布;除非模板是 jupyter 模式,否则不会生成令牌

在模板编辑器的端口部分,用每个端口的访问控制菜单来设置它,或者通过 API 设置 auth(POST /v1/templates 或 PATCH /v1/templates/{id})。无论哪种方式,保存后的模板都会保留这个值。对于 proxy 端口,打开链接会带上 ?token=;对于 app 端口则不会,因为应用会自己让你登录。

当某个选择起不到它所说的作用时,编辑器会在端口列表下方给出警告。这些警告不会阻止你保存:

警告针对何时出现为什么重要
用在其他镜像上的访问代理端口使用访问代理,但镜像不是 Superheat 镜像:superheat/<name>,前面带不带镜像仓库都算,所以 ACR 上的 superheat-cn-registry.cn-shanghai.cr.aliyuncs.com/superheat/<name> 也算代理位于 Superheat 基础镜像里。在其他任何镜像上,没有任何东西保护这个端口
令牌永远到不了应用的应用校验令牌端口声明由应用校验令牌,但没有任何环境变量的值恰好是 ${SUPERHEAT_ACCESS_TOKEN},启动参数和启动脚本里也都没有用到 $SUPERHEAT_ACCESS_TOKEN应用没有令牌可校验,也就无法要求它
保持开放的公开 Web 端口一个公开的 http 或 https 端口没有任何访问控制任何找到这台机器地址和端口的人都能使用上面的应用

平台的值优先:租用者的环境变量覆盖项无法替换携带令牌的变量。

端口是配方的一部分​

端口列表是启动字段,所以编辑它会重新生成模板的 hash_id,并让固定分享链接失效。运行中的实例保留启动时的端口映射;新端口只会出现在编辑之后部署的实例上。