雲端計算 | 在ARM64系統上編譯安裝Gitlab Docker映象

PKS生態服務平臺發表於2020-12-29

GitLab 是一個主要由 Ruby on Rails 語言開發的開源應用程式,實現一個自託管的 Git 專案倉庫,可通過 Web 介面進行訪問和管理,簡而言之就是一個可以私有化部署的 github.com

Gitlab 官方實際上已經提供了 N 種安裝和部署的方式,有直接通過作業系統軟體源進行安裝的,也有通過 Docker 方式部署的,甚至有通過原始碼方式自行編譯安裝的(稍複雜)。

那麼為什麼這裡要選擇較複雜的方式呢?因為官方目前構建的軟體包或者 Docker 映象都是基於 X86 架構的,並沒有對 ARM64v8 的支援。而通過搜尋 Docker Hub 是能夠找到構建好的支援 ARM64v8 的 Docker 映象的,但任然存在一些瑕疵:

  1. 該映象只能跑在 Ubuntu 系的 Linux 發行版上,在 CentOS 上跑則會出錯,因為 Gitlab 使用了 redis,redis 預設依賴 jemalloc,jemalloc 在編譯時使用到了作業系統核心 pagesize 引數,Ubuntu 系的 pagesize 是 4K,而 CentOS 則是 64K,在 pagesize 低的系統上編譯的軟體無法在 pagesize 高的系統上執行。
  2. 即使在 Ubuntu 上能夠正常執行,其中個 grafana 元件也會報 Exec format error 錯誤,這是因為映象作者在編譯時沒有注意到其中的 grafana 元件使用的是 X86 的軟體包。

基於以上原因,選擇自行構建能夠在 CentOS 上執行的 Docker 映象。

 

1 準備編譯環境

編譯前需要準備一個編譯環境的,裡面包含編譯過程中所需要用到的工具鏈。這裡選擇通過 Docker 容器方式來構建編譯環境,因為用完即可丟棄,不影響 Host 作業系統的環境。並且官方提供了 Dockerfile,構建起來非常方便:gitlab-omnibus-builder。以 Ubuntu 18.04 為例,官方提供的 Dockerfile 在這裡,需要注意的是其中有兩處地方使用了 X86 架構的軟體包,需要改為 ARM64 版本的,關鍵之處如下:

FROM ubuntu:bionic as builder
     ...
     省略
     ...

# 下面這裡的 go 版本應由 amd64 改為 arm64
RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" \
  | tar -xzC /usr/local \
  && ln -sf /usr/local/go/bin/go /usr/local/go/bin/gofmt /usr/local/go/bin/godoc /usr/local/bin/
     ...
     省略
     ...

# 下面這裡的 node 版本應由 x64 改為 arm64
RUN curl -fsSL "https://nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" \
  | tar --strip-components 1 -xzC /usr/local/ \
  && node --version
     ...
     省略
     ...

 

2 編譯 Gitlab 安裝包

根據 Docker Hub 上第三方 ARM64 版 Gitlab 映象(gitlab-ce-arm64v8)作者提供的構建指令碼,發現他在 Gitlab 官方提供的編譯指令碼上作了幾處針對 ARM64 架構的修改,再整合上面提到的遺漏的 grafana 問題,得出的最終編譯步驟如下:

# 首先執行一個構建環境映象,其中掛載了一個目錄是為了方便將編譯好的包拷貝出來:
docker run -it --name gitlab-build -v /output/:/output/ -d gitlab_builder_arm64

# 進入映象內部並進入 output 目錄:
docker exec -it gitlab-build /bin/bash
cd /output

# 拉取 Gitlab 原始碼,這裡指定了版本 12.9.7+ce.0:
git clone --depth=1 -b 12.9.7+ce.0 https://gitlab.com/gitlab-org/omnibus-gitlab.git

# 進入程式碼目錄並開始安裝 Ruby 的依賴包
cd ./omnibus-gitlab/
ALTERNATIVE_SOURCES=true bundle install --path .bundle --binstubs

# 修改幾處針對 ARM64 架構的地方:
sed -i "s/\.\/configure/\.\/configure --build=arm-linux/" config/software/ncurses.rb
sed -i "s/\#{arch}/arm64/" config/software/grafana.rb
# grafana 還需要修改對應的檔案 hash,否則會校驗不過,無法編譯:
sed -i "s/0104bfe14444cea2fa3f021b9a75fc78f66434f2ca8f3d0bdd422d108ce682e7/86ead48d7f1f4a5ec04b2d5544425a9d7657c731e66d3722b5a301ddb60f4923/" config/software/grafana.rb

# 正式編譯:
ALTERNATIVE_SOURCES=true COMPILE_ASSETS=true bin/omnibus build --log-level=info gitlab
# 編譯時間較長,並且由於網路等因素,可能會出錯,只能根據報錯資訊應對解決。
# 小提示:如果編譯途中有部分較大的軟體包屢次下載失敗的話,可以從別的地方下好拷進軟體包臨時目錄,位於:/var/cache/omnibus/cache

編譯完成後,在 pkg 目錄下會生成一個 deb 安裝包:gitlab-ce_12.9.7-ce.0_arm64.deb

 

3 通過 Gitlab 安裝包構建映象

同樣,Gitlab 官方在原始碼倉庫的 docker 目錄下提供了 構建 Gitlab docker 映象的 Dockerfile,但是其中有一個檔案 RELEASE 沒有說明清楚,通過查詢資料得知裡面存放了一些用到的變數,具體如下:

PACKAGECLOUD_REPO=gitlab-ce
RELEASE_PACKAGE=gitlab-ce
RELEASE_VERSION=12.9.7-ce.0
DOWNLOAD_URL=https://xxxx:xx/gitlab.deb

DOWNLOAD_URL 是存放 Gitlab 的 deb 安裝包的地方,也就是上面步驟中構建好的。後面構建 Docker 映象時會下載這個包,其實本來打算去掉這個下載步驟,直接將包拷貝到映象容器裡面,安裝完再刪除的,但是這樣會使得映象體積增大,因為增加了一個映象的 layer,因此還是臨時搭了一個 nginx 放包下載。

此外,還需要修改的幾處地方,最終整個構架步驟如下:

git clone --depth=1 -b 12.9.7+ce.0 https://gitlab.com/gitlab-org/omnibus-gitlab.git
cd ./omnibus-gitlab/docker
echo "PACKAGECLOUD_REPO=gitlab-ce" > RELEASE
echo "RELEASE_PACKAGE=gitlab-ce" >> RELEASE
echo "RELEASE_VERSION=12.9.7-ce.0" >> RELEASE
echo "DOWNLOAD_URL=http://https://xxxx:xx/gitlab.deb" >> RELEASE
sed -i "s/16\.04/18\.04/" ./Dockerfile  # 升級為 ubuntu 18.04 版本
sed -i "s/\-\-header\s.*\s.*\s//" assets/download-package  # 去掉 access token,因為 nginx 沒有這方面限制

# 構建 Gitlab Docker 映象:
docker build -t gitlab-ce_ubuntu_18.04_arm64 .

 

4 執行 Gitlab Docker 容器

執行 Gitlab 容器官方也提供了 N 種方案,這裡不再贅述,僅複製一個通過 docker-compose 啟動的最簡單的例子:

web:
  image: 'gitlab-ce_ubuntu_18.04_arm64'
  restart: always
  hostname: 'gitlab.example.com'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'https://gitlab.example.com'
      # Add any other gitlab.rb configuration here, each on its own line
  ports:
    - '80:80'
    - '443:443'
    - '22:22'
  volumes:
    - '/docker-data/gitlab/config:/etc/gitlab'
    - '/docker-data/gitlab/logs:/var/log/gitlab'
    - '/docker-data/gitlab/data:/var/opt/gitlab'

 

 

 

 打賞

相關文章