<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在 Kubernetes 中使用 Helm Hooks 遷移數(shù)據(jù)庫(kù)

          共 2965字,需瀏覽 6分鐘

           ·

          2020-09-20 20:25

          如果你應(yīng)用程序中使用的是關(guān)系型數(shù)據(jù)庫(kù),隨著時(shí)間的推移你的數(shù)據(jù)庫(kù)結(jié)構(gòu)必然或多或少會(huì)有一些變化。在部署你新版本的應(yīng)用之前,必須確保數(shù)據(jù)庫(kù)的結(jié)構(gòu)是最新的,本文不是關(guān)于如何生成和管理 schema 遷移的,而是如何將其作為 Kubernetes 上應(yīng)用部署過(guò)程的一部分來(lái)完成遷移。

          在應(yīng)用中執(zhí)行遷移

          我們可以將自動(dòng)遷移程序作為服務(wù)啟動(dòng)的一部分而存在,這看上去是可行的,可以保證服務(wù)不會(huì)在遷移之前就啟動(dòng),并消除了在過(guò)時(shí)的 schema 結(jié)構(gòu)上運(yùn)行應(yīng)用的風(fēng)險(xiǎn)。

          但是當(dāng)我們將應(yīng)用程序跑在 Kubernetes 集群上的時(shí)候,這會(huì)帶來(lái)一些其他問(wèn)題。

          • 每次創(chuàng)建或重啟新的 Pod 時(shí)候,它都會(huì)嘗試再次執(zhí)行遷移操作,如果你的遷移腳本寫得足夠優(yōu)秀,是可以規(guī)避這些問(wèn)題,但是這并不是一個(gè)很好的設(shè)計(jì)。
          • 如果遷移需要一段比較長(zhǎng)的時(shí)間(比如在一個(gè)大表上添加一列),你的 Pod 可能會(huì)錯(cuò)過(guò)就緒狀態(tài)的檢查,在遷移完成之前會(huì)殺掉容器重啟。我們當(dāng)然可以增加 Pod 的初始延遲時(shí)間,但是這個(gè)時(shí)間是沒(méi)辦法控制的,而且也會(huì)導(dǎo)致正常運(yùn)行的時(shí)候等待大量的時(shí)間。

          使用 init 容器

          Init 容器[1]是指在你的 Pod 中的常規(guī)容器啟動(dòng)之前將運(yùn)行完成的容器。這對(duì)于在你的應(yīng)用程序啟動(dòng)之前執(zhí)行任何需要的設(shè)置都是非常有用的(例如下載一些配置文件)。使用 init 容器來(lái)運(yùn)行數(shù)據(jù)庫(kù)遷移似乎是一個(gè)更好的方式,但我們將面臨與在應(yīng)用程序中啟動(dòng)的方式相同的問(wèn)題。

          • 如果同時(shí)創(chuàng)建多個(gè) Pods,則可能會(huì)同時(shí)運(yùn)行多個(gè) init 容器。
          • 每次創(chuàng)建新的 Pod 時(shí),init 容器都會(huì)運(yùn)行。

          使用 Helm Hooks 執(zhí)行任務(wù)

          Kubernetes jobs

          首先,我們來(lái)看看 Kubernetes 中的 job 資源對(duì)象。Jobs 允許我們運(yùn)行1個(gè)或多個(gè) Pod 來(lái)完成任務(wù)。和 Deployment 中的 Pod 不同,Job 中的 Pod 在退出時(shí)不會(huì)重新創(chuàng)建(除非它們失敗,并且 Job 被配置為在失敗時(shí)重新啟動(dòng))。

          這對(duì)于運(yùn)行一個(gè)只需要運(yùn)行一次就能完成的任務(wù)來(lái)說(shuō)是非常有用的,而運(yùn)行數(shù)據(jù)庫(kù)遷移顯然就是一個(gè)一次性的任務(wù)。

          現(xiàn)在要做的是在部署應(yīng)用程序的新版本之前自動(dòng)運(yùn)行一個(gè) Job 來(lái)執(zhí)行遷移任務(wù)。

          Helm release 生命周期

          Helm[2] 允許你將你的應(yīng)用程序定義的所有 K8S 資源清單打包在一個(gè)Chart 中一次性部署,并使用模板來(lái)定制每個(gè)部署(例如允許在多個(gè)環(huán)境中用不同的參數(shù)部署同一個(gè) Chart)。

          Helm 還提供了 Hooks[3] 鉤子來(lái)決定部署過(guò)程中何時(shí)創(chuàng)建資源,我們可以利用這一點(diǎn),在創(chuàng)建或更新任何資源之前執(zhí)行遷移任務(wù)。下面是我們的遷移任務(wù)的示例:

          apiVersion:?batch/v1
          kind:?Job
          metadata:
          ??name:?"{{?.Release.Name?}}"
          ??labels:
          ??annotations:
          ????"helm.sh/hook":?pre-install,pre-upgrade
          ????"helm.sh/hook-weight":?"-1"
          ????"helm.sh/hook-delete-policy":?hook-succeeded
          spec:
          ??template:
          ????metadata:
          ??????name:?"{{?.Release.Name?}}"
          ????spec:
          ??????restartPolicy:?Never
          ??????containers:
          ??????-?name:?db-migrations??#?我們需要構(gòu)建一個(gè)專門用于數(shù)據(jù)庫(kù)遷移的docker鏡像
          ????????image:?"database-migrations"

          Hooks 是通過(guò) annotations 來(lái)進(jìn)行配置的:

          • "helm.sh/hook":pre-install,pre-upgrade 是告訴 helm 在安裝之前和升級(jí)應(yīng)用程序之前執(zhí)行這個(gè) Job 任務(wù)
          • "helm.sh/hook-weight": "-1" 是用于定義 helm 應(yīng)該以何種順序創(chuàng)建實(shí)現(xiàn)相同鉤子的資源
          • helm.sh/hook-delete-policy: hook-succeeded 是告訴 helm 在 Job 執(zhí)行成功后刪除該 Job 資源對(duì)象。

          其余部分就是一個(gè)普通的 Job 資源對(duì)象模板。

          問(wèn)題

          Helm hooks 的缺點(diǎn)

          你的遷移任務(wù)很可能需要一些配置和或 Secret 才能運(yùn)行(至少需要db 服務(wù)器地址和憑證),但是這個(gè) Job 資源將在 Chart 中所有其他資源之前創(chuàng)建。這意味著我們的 Job 將無(wú)法掛載 Chart 創(chuàng)建的ConfigMap 資源。要解決這個(gè)問(wèn)題我們可以創(chuàng)建一個(gè)實(shí)現(xiàn)相同鉤子的 ConfigMap,如下所示:

          apiVersion:?v1
          kind:?ConfigMap
          metadata:
          ??name:?db-migrations
          annotations:
          ????"helm.sh/hook":?pre-install,pre-upgrade
          ????"helm.sh/hook-weight":?"-10"?#?使用一個(gè)比遷移任務(wù)更小的權(quán)重?
          ????"helm.sh/hook-delete-policy":?hook-succeeded
          data:
          ??DB_ADDR:?{{?.Values.db.addr?}}
          ??DB_NAME:?{{?.Values.db.name?}}

          我們可以配置這個(gè) hook 的權(quán)重比遷移任務(wù)的權(quán)重更小,這樣就可以在遷移任務(wù)執(zhí)行之前創(chuàng)建這個(gè) ConfigMap 資源,這樣就可以在 Job 中掛載這個(gè) ConfigMap 來(lái)獲取配置信息了。

          部署策略和回滾

          默認(rèn)情況下,Kubernetes Deployment 默認(rèn)更新策略是滾動(dòng)更新。這意味著在部署過(guò)程中,將有 Pod 同時(shí)運(yùn)行應(yīng)用程序的上一個(gè)和新版本。這將要求所有的遷移至少要向后兼容以前的版本。

          如果你需要使用 helm rollback 命令回滾到應(yīng)用程序的以前版本,你重新部署的版本的遷移任務(wù)也會(huì)再次運(yùn)行。在回滾期間試圖向下遷移到以前版本的數(shù)據(jù)庫(kù)結(jié)構(gòu),很可能會(huì)導(dǎo)致現(xiàn)有的 Pods 運(yùn)行失敗。最后,如果你必須回滾到一個(gè)更老的版本,你需要確保當(dāng)前的數(shù)據(jù)庫(kù)結(jié)構(gòu)與你計(jì)劃回滾到的版本向后兼容。

          原文鏈接:https://itnext.io/database-migrations-on-kubernetes-using-helm-hooks-fb80c0d97805

          參考資料

          [1]

          Init 容器: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

          [2]

          Helm: https://helm.sh/

          [3]

          Hooks: https://helm.sh/docs/topics/charts_hooks/




          K8S進(jìn)階訓(xùn)練營(yíng),點(diǎn)擊下方圖片了解詳情


          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  97熟妇| 亚洲欧美一区二区三区在线 | 99在线视频精品 | 图片区视频区小说区 | 一区二区韩国在线 |