連接埠
在範本上宣告一個連接埠,Superheat 就會在執行個體啟動時發布它,把容器連接埠對應到你租用的機器上的某個主機連接埠。你的工作負載上任何想從外部連到的接聽位置 —— 推論伺服器、網頁介面、指標端點 —— 都需要在這裡有一列。
宣告連接埠
連接埠 區段中的每一列有五個部分。
| 部分 | 可接受的內容 | 意義 |
|---|---|---|
| 容器連接埠 | 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 模式下不會前置加入任何東西。如果你想以 SSH 連到 args 範本,就得自己負責在映像檔中執行 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,網址中已經帶著存取權杖。請參閱 JupyterLab。存取代理後面的開啟按鈕連接埠,網址裡同樣會帶著權杖。
要求存取權杖
已發布的連接埠,任何找到機器位址和連接埠的人都連得上。每個執行個體都可以帶有一個自己的密鑰,也就是存取權杖,而連接埠的 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,並使釘選的分享連結失效。執行中的執行個體會保有啟動當下的連接埠對應;新的連接埠只會出現在編輯之後才部署的執行個體上。