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」(網頁)為主,來進行操作;流程基本上是:
- 在 Docker 內部的 PostgreSQL 系統建立 registry 使用的資料庫以及帳號
- 修改
gitlab.rb
設定檔、加入新的設定資料、並進入維護模式 - 進行 registry 的轉移、並匯入既有資料
- 修改
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 的容器內執行兩個指令:
-
套用 schema migration(這邊可能會問是否要關閉 registry 的服務)
gitlab-ctl registry-database migrate up
-
匯入資料庫:
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
」才解決問題。
現在就不知道這個需要遷移的動作是什麼時候要做了?希望不要每次升級都來一次?