Nic Lin's Blog

喜歡在地上打滾的 Rails Developer

如何在區域網路用 Docker 架設有 SSL 的 Gitlab

為什麼要自架 Gitlab

經歷過在團隊中使用 Gitea 後發現實在太難用了,除了速度快以外實在感受不到什麼優點,不管是在 CI / Code review 的部分都差強人意,更不用說個單 Repo 關鍵字搜尋都沒有(版本 1.8.3 時,後面不清楚)。

所以決定來換個自架 Gitlab,不過基本上能用 SaaS 雲服務還是比較省事一些,真的覺得資安擺第一或是有更大的客製化需求在來自己搞一套 Git hosting 會是比較建議的作法,不然其實後續維護成本跟備份問題都是隱性成本。

其實這是很簡單的數學問題,如果要自己搞 git hosting,算一下人力架設成本還有機器錢、備份的心力,真的一年下來有省多少嗎?

不過既然要動手架,就一次搞定吧!

目標

  • 架設一台 Gitlab server 搭配 CI runner
  • 輸入內網 IP 例如 33.33.13.10 可以連到帶有自己簽名的 gitlab.cc

這邊的 gitlab.cc 是我自己定義的,你也可以嘗試定義其他例如 git.dev 之類的

也就是說我們期望這個 Gitlab 架設好,就可以馬上在專案內直接透過 yml 來寫我們的 CI 腳本,並且有專屬的自簽域名可以直接連線 https://gitlab.cc,也就是說打開瀏覽器不會被標示為不安全。

這次架設會用 Docker 來做,原因如下

  1. Gitlab 官方對 Docker 支持很好,更新升級都很容易
  2. 只要備份好檔案及 docker-compose 的設定,機器掛掉在開很快
  3. 未來接 K8S 容易

準備機器

準備一台機器架設在內網,並且 RAM 必須至少 4G

本說明可以使用 vagrant 來做練習

如果要架設在實際機器上,可以跳過本步驟

  1. 建立 Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.define :web1 do |web1_config|
    web1_config.vm.box = "ubuntu-16-04"
    web1_config.vm.host_name = "web-1"
    web1_config.vm.network "private_network", ip: "33.33.13.10"
    web1_config.vm.network "forwarded_port", guest: 80, host: 1234
    web1_config.vm.provider "virtualbox" do |v|
      v.memory = 4096
      v.cpus = 2
    end
  end
end
  1. vagrant up
  2. ssh vagrant@33.33.13.10
  3. password = vagrant

安裝 Docker

以 Ubuntu 為例,可以透過以下方式安裝最新版本

sudo apt-get -y remove docker docker-engine docker.io
sudo apt-get update
sudo apt-get -y install \
     apt-transport-https \
     ca-certificates \
     curl \
     software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
     "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
     $(lsb_release -cs) \
     stable"
sudo apt-get update
sudo apt-get install docker-ce

Docker compose

這裡的規劃用 Docker 在機器上運行,所以這台機器理想是跑兩個 Docker

  1. Gitlab 主站
  2. CI runner

先安裝 Docker compose

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

1. Gitlab 主站架設

在機器上建立好一個 docker-compose.yml 的腳本

mkdir gitlab

cd gitlab

vim docker-compose.yml

version: '3.2'
services:

  gitlab:
    image: gitlab/gitlab-ce:latest
    hostname: gitlab.cc
    container_name: gitlab
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url "https://gitlab.cc"
        letsencrypt['enable'] = false
    volumes:
      - /gitlab/config:/etc/gitlab
      - /gitlab/logs:/var/log/gitlab
      - /gitlab/data:/var/opt/gitlab
    ports:
      - 443:443
      - 80:80
    extra_hosts:
      - "gitlab.cc:33.33.13.10"
    networks:
      - devel-net

networks:
  devel-net:

接著輸入 docker-compose up 就可以啟動服務了

大概一陣子啟動過後,會看到 Log 一直出現

cannot load certificate key "/etc/gitlab/ssl/gitlab.cc.key"

這是因為找不到 SSL 憑證的問題

先用 ctrl + C 暫時關閉 server

然後我們就自己簽一個吧!

自簽 SSL 憑證

在目錄下新建檔案 ssl.conf

cd gitlab

touch ssl.conf

[req]
prompt = no
default_md = sha256
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_req

[dn]
[req]
prompt = no
default_md = sha256
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_req

[dn]
C = TW
ST = Taiwan
L = Taipei
O = Duotify Inc.
OU = IT Department
emailAddress = admin@gitlab.cc
CN = gitlab.cc

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = gitlab.cc
DNS.2 = *.gitlab.cc

接著執行指令,進行簽名

openssl req -x509 -new -nodes -sha256 -utf8 -days 3650 -newkey rsa:2048 -keyout server.key -out server.crt -config ssl.conf

接下來我們會看到生成了兩支檔案,分別為公鑰(server.crt)和私鑰(server.key)。

也因為我們剛剛已經使用 docker-compose 來架設 gitlab,這時候伺服器的根目錄 /gitlab 下方已經有資料了。

請將公私鑰複製到資料夾內

  1. sudo cp server.key /gitlab/config/ssl/gitlab.cc.key
  2. sudo cp server.crt /gitlab/config/ssl/gitlab.cc.crt

這時候再次輸入 docker-compose up -d 啟動 server 應該可以看到沒有噴錯誤訊息了。

備註: 加入 -d 指的是跑 daemon 模式,也就是背景運作,這樣一來我們就不用一直開著 terminal 了

本機信任自簽憑證

在自己電腦裡面編輯自訂 host

sudo vim /etc/hosts

加入一條

gitlab.cc 33.33.13.10

然後將機器內的 server.crt 載下來

如果不知道怎麼下載下來,就直接複製內容,然後在自己電腦裡建一個 gitlab.cc.crt

內容大概是這樣

-----BEGIN CERTIFICATE-----
MIIDzjCCAragAwIBAgIJAO7WOlAKgdWBMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJUVzEPMA0GA1UECAwGVGFpd2FuMQ8wDQYDVQQHDAZUYWlwZWkxFTATBgNV
BAoMDER1b3RpZnkgSW5jLjEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDEeMBwGCSqG
SIb3DQEJARYPYWRtaW5AZ2l0bGFiLmNjMRIwEAYDVQQDDAlnaXRsYWIuY2MwHhcN
MjAwMjEwMDgzNzUwWhcNMzAwMjA3MDgzNzUwWjCBkjELMAkGA1UEBhMCVFcxDzAN
BgNVBAgMBlRhaXdhbjEPMA0GA1UEBwwGVGFpcGVpMRUwEwYDVQQKDAxEdW90aWZ5
IEluYy4xFjAUBgNVBAsMDUlUIERlcGFydG1lbnQxHjAcBgkqhkiG9w0BCQEWD2Fk
bWluQGdpdGxhYi5jYzESMBAGA1UEAwwJZ2l0bGFiLmNjMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAzzUycQAoKWsx4nFUTqj9n2HX8b9QHVBmeMN7S03V
EVWzf8hHXU8jpK1lQPoV/eDOiDL/J5K6M9bmHqW37Q2SiYF/logFfnvCca0m9HfG
aKwVf+rpuamLKDLXp5NRiNs3btRRdQbVZFnA+xmeoO+Xbyo8c2isFgzdXLrU4GTh
QFSBBzYtSmmJChBC3gjaAKRmlgkwQS7Adk+nL83+JuJY6X0wr67cPXqKcrkYnx12
Nq8MZXjvRcOSTyh87BZmgKDnUigA7o7gK0JgnaUUsPMokReGMOTIAwJAT1i86own
EFobxFOgOAhL8nVHUSeHz9nj4AyzN4iBTPWMitto+ez2+QIDAQABoyUwIzAhBgNV
HREEGjAYgglnaXRsYWIuY2OCCyouZ2l0bGFiLmNjMA0GCSqGSIb3DQEBCwUAA4IB
AQAdwNzHhNN+ue+HbwK1U2T7SbhuJdv9vCheb3YLuQfTJ5nYbiIKRAXEXu6rPguf
76xLVpd7dvbp3PTv6ZxXvyrz3myBSdJbMsaNSb6PIVJndXM21WqbwyGpfjeudN5L
NR8dZqQ6vQBEk5Ixsei+Xe6w0e0bXTJHq+QCBpKpn+R+hngni2W9j/qDPUiObqhr
Rj4DN5JcmAxCY0n+YorjzNuXQQGZhofBIhBSeghuKtON4bXMNuHvQEya49PDIh6s
a5G0GD15Sn6wh6D9dOBkizICENF8yRFdOJRL4QlLy+STHsgGKBfvcBysP8oCXTNG
UXrOnf1Pjk9v3PTXtSIc8PUn
-----END CERTIFICATE-----

接著將自簽證書匯入本機

打開「鑰匙圈存取」,如果不知道怎麼打開,在 Mac 右上角的放大鏡打開輸入 keychain 應該就有了

接著將證書檔案用拖曳的方式放到「系統」下

「找到 gitlab.cc」-> 點兩下之後選擇「信任」-> 「使用此憑證時完全相信」

完全關閉瀏覽器後輸入 https://gitlab.cc 應該可以看到自己架好的私人 Git hosting 了,而且帶自簽憑證哦

到這裡應該已經可以直接使用了!

第一個畫面是要你設定 root 的密碼,然後就登入吧

帳號: root 密碼: 第一個畫面讓你輸入兩遍的就是密碼了

2. CI Runner

自動化 CI 是很重要的一環,要能夠直接在專案下寫 CI 腳本就要有 runner 來幫你建造這些事物。

打開我們剛架設好的 gitlab.cc,進到後台 https://gitlab.cc/admin/runners

這裡會看到

  • 在安裝執行器時指定以下 URL: https://gitlab.cc/
  • 在安裝過程中使用此註冊憑證: tVFLiiXQxmNinxzzhyen

這是我們稍後註冊 runner 要的資訊,先記錄下來

先掛載 Runner docker

docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host gitlab.cc:33.33.13.10 \
gitlab/gitlab-runner:latest

接著我們要讓兩個 docker 跑在同一台機器下來自簽 SSL 互相溝通

必須將簽證放在 runner 指定的位置

/srv/gitlab-runner/config/certs/ca.crt

也就是說你必須複製一份過去

sudo cp server.crt /srv/gitlab-runner/config/certs/ca.crt

這樣才會自動去吃,這是預設值的坑

然後接下來不管是跑註冊還是啟動 runner 都一定要記得加上 add-hosts 來啟動 docker

不然之後他會直接吃 DNS 然後找不到自己的 IP

註冊 runner

docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner --add-host gitlab.cc:33.33.13.10 gitlab/gitlab-runner register \
  --docker-privileged \
  --non-interactive \
  --executor "docker" \
  --docker-image alpine:latest \
  --url "https://gitlab.cc" \
  --registration-token "tVFLiiXQxmNinxzzhyen" \
  --tls-ca-file "/etc/gitlab-runner/certs/gitlab.cc.crt" \
  --description "docker-runner" \
  --tag-list "docker" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

回到 https://gitlab.cc/admin/runners 後台查看一下是不是已經註冊了一個 runner 呢?

重啟 runner 吃最新的設定 docker restart gitlab-runner

看 runner Log docker logs gitlab-runner

那就完成了這次的架設了

一開始 runner 只有 concurrency 只有設定 1 而已,如果多專案跑起來肯定會塞車的,可以到 sudo vim /srv/gitlab-runner/config/config.toml 這裡把數值調整大一些

這篇我該踩的應該都踩一輪了,整理了最簡化的指令跟步驟可以快速搞定一台帶簽證帶 Runner 的 Gitlab 了

comments powered by Disqus