家のraspberry piにgitlab-ceを入れて遊んでいるのだが、こいつにgitlab-runnerをセットアップしようとしてはまったのでメモ。
以下の記事は悪戦苦闘した経緯を記録したものであり、最終的には動いたけど、最適解ではない。
gitlab-runnerの起動
うちのgitlabはdocker composeで起動する。ということで、gitlab-runnerもdocker composeで
gitlab-runner:
image: gitlab/gitlab-runner:latest
restart: always
volumes:
- '/opt/gitlab-runner/config:/etc/gitlab-runner'
- /var/run/docker.sock:/var/run/docker.sock
で、/opt/gitlab-runner/configのディレクトリを用意してからdocker compose up -d。まぁ実際は一つのymlファイルでgitlabとgitlab-runnerと両方立ち上げてるんだけど。
register gitlab-runner
Registering runnersのページを見ると、deprecatedって書いてあるけど、かわりのやりかたがわからんので、そのままやる。
gitlab全体で使えるgitlab-runnerを設定したい場合
要するにShared runnersの設定
gitlabにadminでログインする。メニューからAdminを選択してAdmin Areaを表示。左のリストからCI/CDのRunnersを選択。右上のReginster an instance runnerで、Registration tokenを表示させ、コピーしておく。
プロジェクトごとに独立したgitlab-runnerを設定したい場合
要するにSpecific runnersの設定
gitlab内のCICDしたいプロジェクトを開いてから、左のメニューでSettings -> CI/CDとたどって、ページの中のRunnersを開く。
Specific runnersの中に、Register the runner with this URL:という項目とAnd this registration token:という項目があるのでメモしておく。というかこのページを開いておく。
で、コマンドラインから
$ docker run --rm -t -i -v /opt/gitlab-runner/config:/etc/gitlab-runner --name gitlab-runner-register gitlab/gitlab-runner register
Enter the GitLab instance URL (for example, https://gitlab.com/):には先のRegister the runner with this URL:の内容を、Enter the registration token:には先のAnd this registration token:の内容を入力。
Enter a description for the runner:とEnter tags for the runner (comma-separated):は適当に、Enter optional maintenance note for the runner:は空で入力
と。。。。
certificate has expired
ERROR: Registering runner... failed runner=XXXXXXXXXXXX status=couldn't execute POST against https://potato/api/v4/runners: Post "https://potato/api/v4/runners": x509: certificate has expired or is not yet valid: current time 2023-02-01T23:47:53Z is after 2022-09-11T23:11:46Z
PANIC: Failed to register the runner.
ん?certificatesが切れてる?

Chromeでgitlabにアクセスしたときに、URLの欄が「保護されていない通信」ってなってて、そこをクリックから「証明書が無効です」をクリックすると上を含んだダイアログがでる。確かに切れてるわ。
$ openssl x509 -text < /etc/gitlab/ssl/raspberrypi.crt
コマンドラインで見るならこれ。
実際は、/etc/gitlab/ssl/raspberrypi.crtじゃなくて、Dockerのvolumesの元パスだし、raspberrypiじゃなくてホスト名変えてるけど。
Validity
Not Before: Aug 12 23:11:46 2022 GMT
Not After : Sep 11 23:11:46 2022 GMT
$ openssl s_client -connect raspberrypi:443 -showcerts < /dev/null
これでも見られる。
depth=0 CN = raspberrypi
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = raspberrypi
verify error:num=10:certificate has expired
notAfter=Sep 11 23:11:46 2022 GMT
verify return:1
depth=0 CN = raspberrypi
notAfter=Sep 11 23:11:46 2022 GMT
verify return:1
今日は2023年です。切れてます。
こんなん俺作ったかな。gitlabが起動するときに勝手に作ったのかな。
確かにWebでアクセスするときに、オレオレ証明書のエラーじゃなくて、違うエラーが出てたけど、気にせず使ってたわ。
ということで、証明書を作り直す。
openssl req -new -key /etc/gitlab/ssl/raspberrypi.key > raspberrypi.csr
これで、証明書作成リクエストを作成。
ここで国やら組織やらを聞かれるので適当に入力。
openssl x509 -days 3650 -req -sha256 -signkey /etc/gitlab/ssl/raspberrypi.key < raspberrypi.csr > raspberrypi.crt
これで証明書を作成。期限は3650日、すなわち10年を指定。出来上がったraspberrypi.crtを/etc/gitlab/ssl/raspberrypi.crtとして配置。
$ docker compose restart
で、gitlabを再起動。再起動で時間かかるのでしばらく放置。
$ docker logs -f コンテナID
でgitlabのログから起動状況が見られるので落ち着くまで待つ。

Chromeでgitlabにアクセスすると、相変わらずURL欄は「保護されていない通信」となっているが、証明書を表示すると有効期限は更新されている。
ということで、再度、gitlab-runnerでregister。
certificate is not valid for any names
$ docker run --rm -t -i -v /opt/gitlab-runner/config:/etc/gitlab-runner --name gitlab-runner-register gitlab/gitlab-runner register
で、再びエラー。
ERROR: Registering runner... failed runner=XXXXXXXXXXXX status=couldn't execute POST against https://potato/api/v4/runners: Post "https://potato/api/v4/runners": x509: certificate is not valid for any names, but wanted to match raspberrypi
PANIC: Failed to register the runner.
あ、やってもた。先の「証明書作成リクエストを作成」ステップでいろいろ聞かれたときに、答えが適当過ぎた。「Common Name (e.g. server FQDN or YOUR name)」はちゃんとraspberrypiとホスト名入れなきゃ。
で、「証明書作成リクエストを作成」ステップからやり直し。gitlab-runnerでregister。
certificate relies on legacy Common Name fields, use SANs insted
ERROR: Registering runner... failed runner=XXXXXXXXXXXX status=couldn't execute POST against https://potato/api/v4/runners: Post "https://potato/api/v4/runners": x509: certificate relies on legacy Common Name field, use SANs instead
PANIC: Failed to register the runner.
ん!今度はなんだよ。
「証明書作成リクエストを作成」ステップさきほど修正した、「Common Name」を使うんじゃなくて、SAN(subectAltName)を使えと。そんなもん聞かれないじゃないか。
openssl req -new -key /etc/gitlab/ssl/raspberrypi.key -addext "subjectAltName = DNS:raspberrypi" > raspberrypi.csr
と、-addextで指定する模様。またやり直し。
しかし、証明書作成の後、crtの中身をopenssl x509 -textで確認するも、DNS:raspberrypiは入ってこない。大体、Versionが1のままじゃないか。なんかおかしい。
結局、「証明書作成リクエストを作成」と「証明書を作成」を2ステップにするのではなくて、
$ openssl req -new -x509 /etc/gitlab/ssl/raspberrypi.key -addext "subjectAltName = DNS:raspberrypi" > raspberrypi.crt
と、-x509を指定して、一気にcrtを作成。
そうすればcrtがVersion 3になり、Subject Alternative Nameが入る。
X509v3 Subject Alternative Name:
DNS:raspberrypi
openssl x509 -textで上の行が埋まっていればOK。
certificate signed by unknown authority
ERROR: Registering runner... failed runner=XXXXXXXXXXXX status=couldn't execute POST against https://potato/api/v4/runners: Post "https://potato/api/v4/runners": x509: certificate signed by unknown authority
PANIC: Failed to register the runner.
まだ、気に入らんか。。。。
gitlab-runnerの/etc/gitlab-runner/certsの下にcrtを入れればunknown authorityは解決する模様。
ファイルをコピーしてもいいし
openssl s_client -connect raspberrypi:443 -showcerts < /dev/null | openssl x509 -outform PEM > raspberrypi.crt
で、持ってきてもよし
Registering runner… succeeded
Registering runner... succeeded runner=XXXXXXXXXXXX
Enter an executor: kubernetes, custom, docker-ssh, parallels, ssh, docker-ssh+machine, instance, docker, shell, virtualbox, docker+machine:
あ、通った。
全部のトラップに躓いた気分。
dockerを選択して、イメージ名を入力。
Gitlabのページで、出た出た。長かった。

これはAdmin AreaのCI/CD->Runnersの表示。

これはプロジェクト内のShared runnerの表示。

これはプロジェクト内のspecific runnerの表示。
おまけ
$ gitlab-runner unregister --url='XXX' --token='YYY'
ちなみに、unregisterするには上のようにする。Dockerのときはそれなりに。
なんだけど。。。やっぱりraspberry pi 4Bでは重すぎていつまでたってもデプロイ終わらん。使えねえ。