跳转到内容
开源

部署容器映像檔

從公開或私有 registry 執行映像檔,設定連接埠、環境變數與持久儲存空間。

在專案選擇 新增 → Docker 映像檔,填入映像檔與連接埠,完成 檢查變更 後套用,就能啟動服務。需要保留檔案、登入私有 registry 或調整資源時,展開 更多設定。

  • 已有專案,以及在該專案建立服務的權限。公開網域、機密與磁碟區各有自己的權限,表單會依可用權限顯示選項。
  • 映像檔已推送到節點能存取的 registry,並提供節點架構對應的版本。
  • 知道應用程式實際監聽的連接埠。首次部署可先依第一個專案走完公開映像檔的流程。
  • 要保存資料時,叢集已有可配置磁碟區的預設儲存類別。

開啟 新增 → Docker 映像檔,在 映像檔 填入完整參照,例如 ghcr.io/acme/web:1.4。使用固定 tag 或 digest,方便對照部署版本。沒有指定版本時,registry 會使用 latest。

確認 名稱。名稱最多 40 個字元,使用小寫字母、數字與連字號,以字母開頭,且不能和專案內既有名稱衝突。

Zeabur 會從映像檔讀取它宣告的連接埠。確認 連接埠 和應用程式真正監聽的號碼相同。映像檔宣告多個號碼時,依應用程式用途選擇。

不接受連線的背景服務,把 連接埠 留空。這時只建立 Deployment,沒有私有位址,也不能加公開網域。

要提供 HTTP 網站,開啟 公開網域。管理員設定了應用程式網域時,表單會建議網址。沒有設定時自行填寫,並把 DNS 指向叢集入口。表單也會顯示目前使用的憑證簽發者,或只有 HTTP。詳見加入公開網域。

設定填寫方式與結果
環境變數每行一個 KEY=value。應用程式靠 PORT 決定監聽位置時,在這裡自己加上 PORT。
把值放在 Secret <名稱>-env預設開啟,變數的值存進這個機密。沒有建立機密的權限時,變數會直接寫在 Deployment 裡,也不能使用私有 registry。這時不要在這裡填密碼。
磁碟區開啟後填入 掛載路徑,例如 /data,以及 磁碟區大小,例如 5Gi。建立的是新的空白磁碟區。
規格選擇 小、中 或 大,欄位下方會列出 CPU 保留量、記憶體保留量與上限。
副本數可選 1 到 20,掛載磁碟區時固定為 1。
私有 registry開啟後填入 Registry、帳號、密碼,例如 registry 主機 ghcr.io。Zeabur 會建立映像檔下載用的機密。
安全性Zeabur 讀取映像檔的 User:數字 UID 不是 0(例如 101、1000:1000)時選 嚴格;沒有指定使用者,或指定 root、0、nginx 這類使用者名稱時選 相容。表單會說明原因,建立前仍能切換。

按 檢查變更。核對映像檔、名稱、連接埠與公開網域。新增磁碟區時,也檢查容量與掛載路徑。套用後會進入新服務。

需要表單以外的容器欄位時,按 以 YAML 編輯,表單會把目前設定帶到建立頁。改完 YAML 再 檢查變更,確認所有文件後建立。

在服務 概覽 確認副本就緒,再看 日誌 是否已啟動應用程式。填了連接埠時,Zeabur 會替它加上 TCP 就緒檢查,副本能接受連線後才開始收到流量。

有公開網域時,到 網路 開啟網址,確認應用程式能回應。私有服務可從叢集內其他服務連到 私有網路 顯示的位址。

用 kubectl 查看時,Zeabur 建立的物件都帶有 app.kubernetes.io/name: <服務名稱>:

kubectl -n shop get deploy,svc,ingress,secret,pvc -l app.kubernetes.io/name=web
kubectl -n shop rollout status deployment/web

deployment.apps/web 的 READY 是 1/1,rollout status 印出 successfully rolled out,就表示副本已通過就緒檢查。Ingress 的 HOSTS 是你填的網域,ADDRESS 是叢集入口的位址。

部署後要調整變數或磁碟區,前往環境變數與磁碟區。

表單建立的是一般的 Kubernetes 物件,沒有 Zeabur 專屬的欄位。把下面的 YAML 存成 web.yaml,用 kubectl -n shop apply -f web.yaml 套用,結果和表單選 嚴格、小 規格、開啟公開網域相同:

apiVersion: v1
kind: Secret
metadata:
name: web-env
labels:
app.kubernetes.io/name: web
type: Opaque
stringData:
APP_ENV: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app.kubernetes.io/name: web
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: web
template:
metadata:
labels:
app.kubernetes.io/name: web
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: web
image: ghcr.io/acme/web:1.4
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: web-env
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
readinessProbe:
tcpSocket:
port: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
---
apiVersion: v1
kind: Service
metadata:
name: web
labels:
app.kubernetes.io/name: web
spec:
selector:
app.kubernetes.io/name: web
ports:
- name: http
port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
labels:
app.kubernetes.io/name: web
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts: [web.example.com]
secretName: web-tls
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080

和表單選項的對應:

  • 相容:Pod 的 securityContext 只留 seccompProfile,容器的 securityContext 只留 allowPrivilegeEscalation: false。
  • 中、大 規格:CPU 和記憶體保留量分別是 250m/256Mi(上限 512Mi)和 500m/512Mi(上限 1Gi)。
  • 沒有憑證簽發者時,Ingress 不帶 annotation 和 tls。letsencrypt 換成叢集實際的 ClusterIssuer 名稱,用 kubectl get clusterissuer 查看。
  • 多個連接埠:Service 的第一個連接埠叫 http,其他叫 port-<號碼>。
  • 把值放在 Secret 關閉時,變數改寫在容器的 env,不建立 web-env。

私有 registry 的帳密放在 kubernetes.io/dockerconfigjson 類型的機密,名稱是 <服務名稱>-registry,Deployment 用 imagePullSecrets 指向它:

kubectl -n shop create secret docker-registry web-registry \
--docker-server=ghcr.io --docker-username=acme --docker-password=<權杖>
kubectl -n shop label secret web-registry app.kubernetes.io/name=web
kubectl -n shop patch deployment web -p '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"web-registry"}]}}}}'

磁碟區是一個 PVC,名稱是 <服務名稱>-<磁碟區名稱>:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: web-data
labels:
app.kubernetes.io/name: web
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 5Gi

掛載它時,Deployment 的 spec.replicas 固定為 1,並加上 strategy: {type: Recreate},Pod 的 volumes 寫 persistentVolumeClaim: {claimName: web-data},容器的 volumeMounts 寫 mountPath: /data。已經建立的服務,到磁碟區用表單加比較簡單。

情況處理方式
讀不到映像檔的連接埠依提示檢查映像檔名稱、tag 與 registry 帳密。知道實際連接埠時可直接填寫。
映像檔只有其他架構版本改用支援節點架構的 tag,或重新建置對應架構的映像檔。
無法下載映像檔在 概覽 或 部署紀錄 查看原因,確認節點可連到 registry,並核對私有 registry 的認證資訊。
容器因 root 或權限問題無法啟動檢查映像檔的使用者、目錄權限與安全性設定。需要 root 的映像檔選 相容。要維持嚴格,就改用以非 root 數字 UID 執行的映像檔。專案仍強制 restricted 時,請管理員把專案的 Pod Security 等級改為 baseline。
副本一直未就緒查看 日誌,確認應用程式已監聽表單指定的連接埠,再到 設定 調整健康檢查。
磁碟區一直沒有準備好查看儲存空間相關事件,確認預設儲存類別、可用空間與可排程的節點。
服務就緒但網址無法開啟到 網路 沿著 DNS、入口與服務的連線檢查處理,見公開網域。

在服務右上角的 更多 選 刪除服務。刪除流程會列出服務建立、且沒有其他服務使用的網路、機密與磁碟區。其他服務還在使用的物件會保留。