> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 在 Kubernetes 上升級

> 升級 Ayakaleaf Pro 的 Kubernetes 部署，無論是單一副本或多個副本。

升級會取代映像檔標籤。新版本會在啟動時遷移資料庫，而這些遷移必須**只執行一次、由單一 Pod 執行，且執行時沒有任何舊版 Pod 在運作**。在 Kubernetes 上，這表示不能對已擴展的 StatefulSet 直接進行滾動更新。

> [!CAUTION]
>
> 每次升級前，請在 Ayakaleaf Pro 停止的狀態下進行[一致性備份](https://ayakaleaf-pro.mintlify.site/zh-TW/on-premises/maintenance/data-and-backups#performing-a-consistent-backup)。請閱讀[版本資訊](https://ayakaleaf-pro.mintlify.site/zh-TW/on-premises/release-notes)，了解您要升級的目標版本所需的步驟。

開始之前，請在每個執行 Ayakaleaf Pro 的節點上，以 `sudo docker pull` 拉取新版本或新設定中列出的任何 TeX Live 映像檔。

> [tab] 單一副本
>
> **1. 停止 Ayakaleaf Pro**
>
> ```bash theme={null}
> kubectl -n overleaf scale deployment/overleaf --replicas=0
> kubectl -n overleaf wait --for=delete pod -l app=overleaf --timeout=5m
> ```
>
> **2. 備份**
>
> MongoDB，可從任一成員執行：
>
> ```bash wrap theme={null}
> kubectl -n overleaf exec mongo-0 -- mongodump --quiet --archive --gzip \
>   --uri 'mongodb://mongo-0.mongo:27017,mongo-1.mongo:27017,mongo-2.mongo:27017/sharelatex?replicaSet=overleaf' \
>   > sharelatex-$(date +%F).archive.gz
> ```
>
> 資料磁碟區，透過一個掛載該磁碟區的短期 Pod（它會被排程到磁碟區所在的節點）：
>
> ```bash wrap theme={null}
> kubectl -n overleaf run backup --image=busybox --restart=Never --overrides='
> {"spec":{"containers":[{"name":"backup","image":"busybox","command":["sleep","3600"],
>  "volumeMounts":[{"name":"d","mountPath":"/data"}]}],
>  "volumes":[{"name":"d","persistentVolumeClaim":{"claimName":"overleaf-data"}}]}}'
> kubectl -n overleaf wait --for=condition=Ready pod/backup
> kubectl -n overleaf exec backup -- tar czf - -C /data . > overleaf-data-$(date +%F).tar.gz
> kubectl -n overleaf delete pod backup
> ```
>
> 對 git-bridge 的磁碟區（`data-git-bridge-0`）也執行相同操作，並保留一份 Secret `overleaf-secrets` 的副本。如果您的儲存空間支援 [VolumeSnapshots](https://kubernetes.io/docs/concepts/storage/volume-snapshots/)，對磁碟區建立快照也能達到相同效果。
>
> **3. 變更版本並啟動**
>
> 在 `40-overleaf.yaml`（以及必須使用相同標籤的 `45-git-bridge.yaml`）中設定新標籤，然後：
>
> ```bash theme={null}
> kubectl apply -f 40-overleaf.yaml -f 45-git-bridge.yaml
> kubectl -n overleaf scale deployment/overleaf --replicas=1
> kubectl -n overleaf rollout status deployment/overleaf --timeout=20m
> kubectl -n overleaf logs deployment/overleaf | grep 'Finished migrations'
> ```
>
> 此 Deployment 使用 `strategy: Recreate`，因此即使變更了標籤，也絕不會同時執行兩個版本。

> [tab] 多個副本
>
> 適用於[水平擴展](https://ayakaleaf-pro.mintlify.site/zh-TW/on-premises/configuration/kubernetes/horizontal-scaling.md)中的設定。
>
> **1. 停止所有副本**
>
> ```bash theme={null}
> kubectl -n overleaf scale statefulset/overleaf --replicas=0
> kubectl -n overleaf wait --for=delete pod -l app=overleaf-ha --timeout=10m
> ```
>
> **2. 備份**
>
> 依照單一副本分頁的方式備份 MongoDB，使用您供應商的工具備份 S3 儲存貯體，並備份 git-bridge 的磁碟區（`data-git-bridge-0`）與各個 Secret。副本的 `/srv/overleaf-ha` 只保存編譯輸出，不需要備份。
>
> **3. 以新版本啟動一個副本**
>
> 在 `70-overleaf.yaml` 與 `75-git-bridge.yaml` 中設定新標籤，並設定 `replicas: 1`：
>
> ```bash theme={null}
> kubectl apply -f 70-overleaf.yaml -f 75-git-bridge.yaml
> kubectl -n overleaf rollout status statefulset/overleaf --timeout=20m
> kubectl -n overleaf logs overleaf-0 | grep 'Finished migrations'
> ```
>
> 確認您可以登入、開啟專案並進行編譯。
>
> **4. 啟動其他副本**
>
> 再次設定 `replicas: 3` 並套用。`OrderedReady` 會依序逐一啟動它們。
>
> ```bash theme={null}
> kubectl apply -f 70-overleaf.yaml
> kubectl -n overleaf rollout status statefulset/overleaf --timeout=20m
> ```
>
> > [!WARNING]
> >
> > 請勿以 `kubectl set image` 或 `kubectl apply` 變更執行中已擴展 StatefulSet 的映像檔：滾動更新會在舊副本仍在服務使用者時，啟動新版本及其遷移。不涉及新版本的設定變更，則可以用滾動重新啟動進行：`kubectl -n overleaf rollout restart statefulset/overleaf`。

### MongoDB 與 Redis

請與 Ayakaleaf Pro 分開升級。MongoDB 請依照[更新 MongoDB](https://ayakaleaf-pro.mintlify.site/zh-TW/on-premises/maintenance/updating-mongodb.md) 進行（一次升級一個主要版本，每個步驟後設定 `featureCompatibilityVersion`）；當您在 `10-mongo.yaml` 中變更映像檔時，複本集會一次一個成員地套用新映像檔，因為 StatefulSet 會依序取代 `mongo-2`、`mongo-1` 與 `mongo-0`。

### 回復

依上述方式停止 Ayakaleaf Pro，從封存檔還原 MongoDB（`mongorestore --drop --archive --gzip`），並從備份還原磁碟區或儲存貯體，設定舊標籤後再次啟動。除此之外，新版本的遷移無法復原。

### Q\&A

> [accordion] 某個副本一直未就緒，其他副本也始終無法啟動
>
> \*\*回答：\*\*在 `podManagementPolicy: OrderedReady` 下，`overleaf-1` 只有在 `overleaf-0` 就緒後才會啟動，而滾動更新不會取代從未就緒的 Pod。修正原因後（例如 ConfigMap 中的錯誤設定），請刪除卡住的 Pod，讓 StatefulSet 依目前的範本重新建立它：
>
> ```bash theme={null}
> kubectl -n overleaf delete pod overleaf-0
> kubectl -n overleaf rollout status statefulset/overleaf --timeout=20m
> ```
>
> 我們在測試叢集上曾因某項設定使 `overleaf-0` 無法就緒而遇到這個問題；刪除該 Pod 後，三個副本便全部順利啟動。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.