Docker 版 GitLab 升級 Container registry

| | 0 Comments| 09:10|
Categories:

Heresy 這邊從好幾年前就有在使用一台自己透過 Docker 架設的 GitLab(官網)(最早的紀錄)。後來由於也需要用 Docker 來做 CI/CD 的執行環境,所以也有開啟他的 container registry 的功能、用來存放 Docker image;由於 GitLab 可以自己處認證的問題,所以對於 CI/CD 來說相當方便。

不過由於他內部的管理機制的設計,在刪除 Docker image 後並不會自動釋放磁碟空間,而需要自己進 GitLab 做垃圾清理(garbage collect、參考),在網頁上也會提醒:

實際上的指令,則是:

gitlab-ctl registry-garbage-collect -m

而 GitLab 也在 17.3 的時候,也終於開始正式提供下一代的 container registry:「container registry metadata database」(文件),會以資料庫來管理相關的資訊;除了號稱會有更好的效率外、也開始提供 online 的 garbage collection 功能。

如果到專案的 container registry 的頁面的話,也會看到他有介紹「下一代的 container registry」:

不過或許是因為舊有資料轉移可能會花相當的時間,所以在升級 GitLab 的時候、並不會自動 container registry 轉移成新版、需要手動操作。

只是不知道為什麼,新安裝的 GitLab 似乎也沒有預設使用新的 container registry、而是要自己設定?

總之,這篇就是 Heresy 把自己用 Docker 架設的 GitLab 的 container registry 轉移成新的 metadata database 的記錄了。


這邊比較討厭的,是官方雖然有提供升級的教學文件(連結),但是卻沒有提供 Docker 版的教學…而設定裡面還包含了內部的 PostgreSQL 資料庫,對 Heresy 這種沒在管內部架構的人來說,其實根本不知道要怎麼做對應的修改…

後來是參考《Container registry metadata database: migration on docker installation》這篇的回答,又試了好一陣子、才終於弄完整個升級的流程。

這邊基本上是以官方文件的「One-step migration」(網頁)為主,來進行操作;流程基本上是:

  1. 在 Docker 內部的 PostgreSQL 系統建立 registry 使用的資料庫以及帳號
  2. 修改 gitlab.rb 設定檔、加入新的設定資料、並進入維護模式
  3. 進行 registry 的轉移、並匯入既有資料
  4. 修改 gitlab.rb 設定檔、進入一般運作模式

這邊的操作大部分都是在 GitLab 的 Docker 容器內進行的,如果要進入容器內的話,docker 的指令是:

docker exec -it gitlab bash

其中紅色的「gitlab」是容器的名稱,要視需要修改。

至於操作的細節則如下:


建立資料庫與需要的帳號密碼

新版的 Docker registry 會需要一個 PostgreSQL 的資料庫來儲存 metadata,而 GitLab Docker 內部已經有了一個現成的 PostgreSQL 服務在跑,所以這邊是繼續沿用既有的資料庫系統,要做的事情就是建立一個名為「registry_database」的資料庫給他用。

但是由於在設定尚不知道該怎麼讓他使用本來的內部資料庫帳號,所以這邊還需要另外建立一個 PostgreSQL 的帳號才行。

所以這邊的指令是:

gitlab-psql -c "CREATE USER registry WITH PASSWORD 'registrypassword'"
gitlab-psql -c "CREATE DATABASE registry_database WITH OWNER registry"

第一行是建立一個帳號叫做「registry」,然後給他一個密碼。

第二行則是建立一個名為「registry_database」的資料庫、並把所有者設定為「registry」。

上面紅字的部分都是可以自己修改的,但是要修改的話就是記得要和後面的 gitlab.rb 維持一致。


修改設定檔案

再來就是要修改 gitlab.rb 這個設定檔案,針對新版的 Docker registry 做相關的設定。

這邊總共要新增三個部分,理論上可以加在 gitLab.rb 的任何位置,但是像 Heresy 這邊因為是先讓 GitLab 自動根據範本產生再慢慢修改的,所以個人是習慣去放在本來的範例相關區段(大部分是加上註解、沒有啟用)。

不過如果是像 Heresy 一樣是從早期版本一路升級上來的話,那這邊的範本應該也很舊了、所以這邊這三項設定也很有可能都沒有出現在範本中。

Registry 的資料庫設定:

要加入的區塊內容如下:

registry['database'] = {
   'enabled' => false,
   'host' => '/var/opt/gitlab/postgresql/',
   'user' => 'registry',
   'password' => 'registrypassword',
   'dbname' => 'registry_database',
   'sslmode' => 'require' }

這邊要注意,是這邊要先把「enable」設定為「false」。

再來,綠底的部分,則要和前面一個步驟的資訊一致。

PostgreSQL 額外的連線設定:

這個東西 Heresy 不熟,不過這邊會需要針對 PostgreSQL 設定額外的連線許可:

postgresql['custom_pg_hba_entries'] = {
   registry_db: [
     {
       type: 'local',
       database: 'registry_database',
       user: 'registry',
       method: 'md5'
     }
   ] }

綠底的部分要和前面的資訊一致。

將 registry 設定為唯獨模式:

理論上是要加入下面的設定:

registry['storage'] = {
   'filesystem' => {
     'rootdirectory' => "/var/opt/gitlab/gitlab-rails/shared/registry"
   },
   'maintenance' => {
     'readonly' => {
       'enabled' => true     }
  } }

這邊在 GitLab 自己產生的 gitlab.rb 裡面,應該是有「registry['storage']」的設定,只是是被註解掉了。

而為了搞清楚「filesystem」到底要設定成什麼,Heresy 也花了一小段時間;不過基本上如果全部都用 GitLab Docker 內部提供的設定的話,預設的路徑應該就是上面的「/var/opt/gitlab/gitlab-rails/shared/registry」。

在加入上面三個設定後,gitlab.rb 的設定就算完成了。

而要套用這個設定,可以在 GitLab 的容器內,執行下面這個指令:

gitlab-ctl reconfigure

等他跑完沒問題的話,就可以進行下一個操作了。


升級、匯入

這邊要在 GitLab 的容器內執行兩個指令:

  1. 套用 schema migration(這邊可能會問是否要關閉 registry 的服務)

    gitlab-ctl registry-database migrate up
  2. 匯入資料庫:

    gitlab-ctl registry-database import

如果都沒有錯誤的話,這邊會花一段時間來進行既有資料的處理。所以如果本來 GitLab 裡面已經放了一堆 Docker image 的話,就得花上一些時間來做匯入。

不過由於 Heresy 這邊量不大,所以轉換的速度還算滿快的。


恢復正常運作

再匯入完成後,則是要正式啟動 Docker registry 的資料庫、並將唯獨模式關閉。

這時候會需要再回去修改 gitlab.rb 這個設定檔案,要改的部分是前面兩個黃底的部分。

在「registry['database']」這邊,是要把「enable」改成「true」,其他內容不動。

registry['database'] = {
   'enabled' => true,
   ... }

在「registry['storage']」這邊,則是要把「readonly」下的「enable」改成「false」,其他不動。

registry['storage'] = {
   ...
   'maintenance' => {
     'readonly' => {
       'enabled' => false     }
   } }

修改完成後,再套用新的設定就可以了。指令一樣是:

gitlab-ctl reconfigure

之後就是等 GitLab 重新啟動了。


理論上,這樣是可以完成 Docker 版 GitLab 內部的 Docker registry 升級;而再升級完成後,在專案的 container registry 的頁面裡,就不會看到上面提醒的「下一代的 container registry」地介紹了。

而理論上,在從 registry 裡面刪除 docker image 後,也不需要再去手動跑 garbage collect 了。

不過,這邊也建議先做一下後續觀察。根據官方「Online garbage collection monitoring」(文件)的說法,是有一些方法可以觀察 gc 是否有正常運作。比如說下面兩個指令可以看到 garbage collect 的工作佇列的數量:

gitlab-psql -d registry_database -c "SELECT COUNT(*) FROM gc_blob_review_queue;"
gitlab-psql -d registry_database -c "SELECT COUNT(*) FROM gc_manifest_review_queue;"

不過,GitLab 預設應該是要一天過後才會進行 review?而到了 review 時間、似乎也不見得會馬上處理這些工作?所以 Heresy 這邊升級完後,這些工作基本上是超過兩天才跑完。

另外,個人是覺得升級後使用的磁碟空間似乎是增加了一些?本來整個 GitLab 使用的磁碟空間大概是 95GB,但是在升級到新的資料庫過後變成 107GB;多出來的這 12GB 就不知道是怎麼一回事了?


最後,GitLab 預設應該是要等一天後才會開始處理 Docker registry 的 garbage collection。那如果想要讓 GitLab 早點跑 gc 的話該怎麼辦呢?

研究了一下,GitLab 似乎是把這部分的時間設定儲存在「gc_review_after_defaults」這張資料表裡面;所以 Heresy 也很暴力地、把裡面的數值全部從一天改成一小時:

gitlab-psql -d registry_database -c "UPDATE gc_review_after_defaults SET value = interval '1 hour';"

實測這樣確實可以加快刪除 docker image 後、儲存空間的釋放速度。但是,這樣會不會讓 GitLab 伺服器的負擔增加就不知道了?

而如果是希望升級後的工作可以快點完成的話,也可以在執行「gitlab-ctl registry-database migrate up」後,就先執行上面的指令去修改資料表,這樣之後產生的 gc 工作就會比較快處理了。


這篇大概就是這樣了。目前看來他應該是有正常在運作,不過效率有沒有變好倒是沒感覺就是了。 XD

然後,這邊其實比較希望 GitLab 官方能提供 Docker 版本的官方轉移教學。因為老實說,單就 PostgreSQL 的部分來說,基本上應該是可以直接使用既有帳號來連線、而不需要另外建立一個新的帳號;這樣一來設定應該是可以再簡化一些,但是這個可能就是要官方出手才行了…


另外,在從 17.8.2 升級到 17.9.0 的時候,出現了 container registry 無法使用的狀況。

在 gitlab 容器內部的 registry 記錄檔(/var/log/gitlab/registry/current)裡面有找到下面的訊息:

creating new registry instance: configuring application: 
there are pending database migrations,
use the 'registry database migrate' CLI command to check and apply them

但是真的執行「registry database migrate up」這類的指令的話,只會出現下列的錯誤:

configuration error: configuration path unspecified 

最後是再去執行一次「gitlab-ctl registry-database migrate up」才解決問題。

現在就不知道這個需要遷移的動作是什麼時候要做了?希望不要每次升級都來一次?

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *