👌

GitLab Runner and GitLab Pages - シリーズ投稿7/7

2022/12/26に公開

Series Top: Dockerで作るおうちLAN遊び場

この投稿はシリーズ7つ目となります。自由に遊べる自分のGitLabサーバができたので、この投稿では引き続きGitLab RunnerとGitLab Pagesのセットアップと説明をしていきます。

簡単な紹介として、GitLab RunnerはGitLabプロジェクト上に置いた指示書を元にジョブを実行してくれるもので、GitLab PagesはGitLabユーザがウェブサイトをホストするのに利用できる場所です。例えばこれらを使ってできるのは、ウェブサイトのコンテンツをプロジェクトにcommit/pushし、GitLab Runnerにそれらを処理してウェブサイトを構成するファイルを生成させ、成果物をGitLab Pagesに載せるといったことです。

GitLab Runner

https://docs.gitlab.com/runner/

GitLab RunnerはGitLab外で実行しているアプリケーションで、GitLab上になにか仕事がないか定期的にチェックし、実行してくれるものです。

GitLab Runnerもこれまで同様Dockerで実行してきます。

Creating a group and obtaining registration token

GitLab側としても匿名の、どこの誰かもしれぬGitLab Runnerに対して自身がホストしているプロジェクト情報を開示しません。GitLabはトークンを発行し、GitLab Runnerはそれを使ってプロジェクト情報を読みに来ます。

この投稿ではGitLab上でグループを作り、そのグループで有効なGitLab Runner用トークンを取得します。こうすることで、そのRunnerはグループ内で以降作られるどのプロジェクトでも利用できることとなります。

https://docs.gitlab.com/ee/ci/runners/runners_scope.html#group-runners

GitLab上で"pages"という名称のグループを作ります。そしてそのグループを開いて確認できるRunnersというメニューより、Runner用のトークン文字列を取得します。

GitLab Runner Registration Token

GitLab Runner registration

いつものdocker composeではなく、最初は単なるdocker runでGitLab Runnerコンテナを実行してGitLabサーバに対してレジストレーションを完了させます。

なおこのシリーズ通しての特殊な設定として自己署名証明書使っている関係で、一手間・一コマンド足してコンテナに証明書を信用させます。まずはその準備として以下です。

https://docs.gitlab.com/runner/configuration/tls-self-signed.html

# as always, creating a directory for GitLab Runner
mkdir $HOME/mylan/runner
cd $HOME/mylan/runner

# store the certificate in $HOME/mylan/runner/gitlab.mylan.local.crt
openssl s_client -showcerts -connect gitlab.mylan.local:443 -servername gitlab.mylan.local < /dev/null 2>/dev/null | openssl x509 -outform PEM > gitlab.mylan.local.crt

https://docs.gitlab.com/runner/register/index.html#docker

次にdocker runの実行です。以下の通り実行するとレジストレーションができたことを確認できます。

  • コンフィグファイルはホストマシンの$HOME/mylan/runner/configディレクトリにできる
  • 上で取得した証明書をコンテナ内 /tmp/gitlab.mylan.local.crtに配置
  • 宛先GitLabサーバを --url "https://gitlab.mylan.local/"で指定
    • --clone-url の指定もhttpsで接続してもらうために必要
  • 取得したトークン文字列は --registration-token "token_here"で使う
  • --tls-ca-file=/tmp/gitlab.mylan.local.crt で自己署名証明書を信頼させる
$ docker run --rm -v "$(pwd)"/config:/etc/gitlab-runner \
>   -v "$(pwd)"/gitlab.mylan.local.crt:/tmp/gitlab.mylan.local.crt \
>   gitlab/gitlab-runner register \
>   --non-interactive \
>   --executor "docker" \
>   --docker-image alpine:latest \
>   --url "https://gitlab.mylan.local/" \
>   --clone-url "https://gitlab.mylan.local/" \
>   --registration-token "GR1348941H2DxBfrLkMrFDfFizvfk" \
>   --run-untagged="true" \
>   --locked="false" \
>   --access-level="not_protected" \
>   --tls-ca-file=/tmp/gitlab.mylan.local.crt
Runtime platform                                    arch=amd64 os=linux pid=7 revision=7178588d version=15.5.1
Running in system-mode.

Registering runner... succeeded                     runner=GR1348941H2DxBfrL
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"

GitLabサーバのGUIで確認すると、レジストレーションされたことが確認できます。

GitLab Runner registered

Running GitLab Runner using Docker Compose

それではこれまで通りdocker-compose.ymlファイルを用意してそこからコンテナを実行させます。

services:
  runner:
    image: 'gitlab/gitlab-runner:alpine3.15-v15.3.3'
    restart: always
    container_name: mylan-runner
    volumes:
      - type: bind
        source: ./config
        target: /etc/gitlab-runner
      - type: bind
        source: ./gitlab.mylan.local.crt
        target: /tmp/gitlab.mylan.local.crt
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock

https://hub.docker.com/r/gitlab/gitlab-runner

すると先程の画面でRunnerがオンラインになったことが確認できます。

GitLab Runner now online

Testing out GitLab Runner

では公式ドキュメントにあるチュートリアルをそのままなぞってRunnerを試してみましょう。

https://docs.gitlab.com/ee/ci/quick_start/

Create a test project

"pages"グループ配下に"runner test"というプロジェクトを作りましょう。

Creating test project

一台目のサーバマシンでもクライアントマシンでも、この新規作成したプロジェクトをクローンしてきます。

# clone the repository at home dir
cd $HOME
git clone https://gitlab.mylan.local/pages/runner-test.git
cd runner-test

Add .gitlab-ci.yml file

.gitlab-ci.ymlファイルを$HOME/runner-test/.gitlab-ci.ymlに作成し、commit/pushしましょう。

ファイル内容は以下のとおりです。

build-job:
  stage: build
  script:
    - echo "Hello, $GITLAB_USER_LOGIN!"

test-job1:
  stage: test
  script:
    - echo "This job tests something"

test-job2:
  stage: test
  script:
    - echo "This job tests something, but takes more time than test-job1."
    - echo "After the echo commands complete, it runs the sleep command for 20 seconds"
    - echo "which simulates a test that runs 20 seconds longer than test-job1"
    - sleep 20

deploy-prod:
  stage: deploy
  script:
    - echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
  environment: production

手順としては、この新たな.gitlab-ci.ymlファイルを作成すると、git statusを実行することでuntracked fileがあることが表示されます。git add, git commitでこのファイルをレポジトリに載せて、git pushでサーバへアップロードします。

❯ git status
On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitlab-ci.yml

nothing added to commit but untracked files present (use "git add" to track)
❯ git add .gitlab-ci.yml
❯ git commit -m "Add tutorial cicd file"
[main afe0df9] Add tutorial cicd file
 1 file changed, 23 insertions(+)
 create mode 100644 .gitlab-ci.yml
❯ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 583 bytes | 583.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://gitlab.mylan.local/pages/runner-test.git
   3241e74..afe0df9  main -> main

GitLabのGUI上で以下のようにCI/CDメニューを確認すると、ジョブが実行されていることが確認できます。GitLab Runnerは常にGitLabサーバへ何か仕事がないか確認しにきており、上を実行したことによって更新されたプロジェクトレポジトリに.gitlab-ci.ymlファイルという指示書を見つけ、その指示内容を実行したのです。

CI/CD Tutorial - pipeline

こちらは"build-job"の内容です。"Hello, $GITLAB_USER_LOGIN!"を実行しており、結果としては"Hello, ghost!"となっていることが確認できます。

CI/CD Tutorial - build job

GitLab Pages

公式ドキュメント内に、GitLab CI/CDを利用して無数のことができることがわかります。その中でも触れられていますが、この投稿で次にカバーしていくのはGitLab Pagesです。冒頭で触れたとおり、公開したいウェブコンテンツをプロジェクトリポジトリとしてアップロードし、GitLab Runnerにアップロードしたものに対してプログラムを走らせウェブコンテンツを生成し、GitLab Pagesに渡してホストさせます。

https://docs.gitlab.com/ee/ci/examples/

https://docs.gitlab.com/ee/user/project/pages/index.html

Setting up GitLab Pages

https://docs.gitlab.com/ee/administration/pages/index.html

GitLab Pagesのセットアップとして、まずは有効化とベースURLの指定をします。GitLabサーバのコンフィグ変更となり、$HOME/mylan/gitlab/config/gitlab.rbを更新してサービス再起動させることでコンフィグ変更できます。

https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html#gitlab-pages-default-domain-names

GitLab PagesのURLについては上のリンクで説明されている通りとなりますが、このフォーマットに従います:

http(s)://groupname.example.io/projectname

今回、グループ名は"pages"としていますが、例えばその中で"runner-test"というプロジェクト用のPagesのURLはこうなります:

https://pages.mylan.local/runner-test/

以下がコンフィグファイルより、GitLab Pagesに関連した一部分のみ抜粋です。変更したのは2行だけで、 pages_external_urlgitlab_pages['enable']です。

################################################################################
## GitLab Pages
##! Docs: https://docs.gitlab.com/ee/administration/pages/
################################################################################

##! Define to enable GitLab Pages
pages_external_url "http://mylan.local/"
gitlab_pages['enable'] = true

コンフィグファイルを編集するだけではサーバに反映されません。ウェブサーバなどで実施した通り、サービスやコンテナの再起動もできますが、GitLabの場合はgitlab-ctl reconfigureを実行することでサーバ設定がコンフィグファイルに則って更新されます。

# this runs in foreground and you will see 
# all the GitLab logs generated while it reconfigures itself
docker exec gitlab gitlab-ctl reconfigure

# or, add "-d" option to let it run in the background
docker exec -d gitlab gitlab-ctl reconfigure

Testing out GitLab Pages with plain html

実際に試してみましょう。まずは1つ目の例として以下のリンクにある公式のものをそのまま使ってみます。

https://gitlab.com/pages/plain-html

GitLab Runnerの時と同様に、"pages"グループ配下に新規プロジェクト"plain-html"を作りましょう。他端末でクローンしても、そのままGitLabのウェブGUIで操作を続けても良いですが、/publicディレクトリ、その中のhtmlやcssファイルの作成、あとは.gitlab-ci.ymlファイルを用意しましょう。

例の通りにファイルを用意すると以下のようになるかと思います。"/public"ディレクトリがあり、その中に"/public/index.html"と"/public/style.css"ファイルがあり、またルートには".gitlab-ci.yml"ファイルができている状態です。

plain-html1

.gitlab-ci.ymlファイルの中身は以下の通りです。

# This file is a template, and might need editing before it works on your project.
# Full project: https://gitlab.com/pages/plain-html
image: busybox
pages:
  stage: deploy
  script:
    - echo "The site will be deployed to $CI_PAGES_URL"
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

こうして何が起こるかというと、GitLab Runnerは指示書を見つけ、レポジトリの中身を公開用としてGitLab Pagesに渡します。アクセス用のURLは先に説明した通りとなりますが、$CI_PAGES_URLでも指している先となります。

plain-html2

Add DNS record

それではGitLab PagesのURLにアクセスする前に、必要なDNSレコードをDockerで実行させているUnbound DNSに追加しましょう。

DNSのコンテナを実行させている一台目のマシンで$HOME/mylan/dns/config/a-records.confファイルを更新します。追加する一行は例に倣ってlocal-data: "pages.mylan.local. IN A 192.168.1.56"となります。

cd $HOME/mylan/dns
# edit config/a-records.conf to add a new record for pages.mylan.local
docker compose restart

Add web server

https://gitlab.mylan.localへのアクセス用に用意したものと同様に、pages.mylan.localへのhttpsアクセスを処理するサーバを追加します。既存のgitlab.confファイルをコピーしてpages.confとして、server_nameだけ更新すれば十分です。

cd $HOME/mylan/rp/conf.d
cp gitlab.conf pages.conf
# edit pages.conf accordingly
# just changing "server_name" line as below will suffice
### server_name pages.mylan.local;

# once the new file is ready, restart the server
cd $HOME/mylan/rp
docker compose restart rp

Access the Pages site

GitLab Pagesは有効化され、ウェブコンテンツはGitLab Runnerが指示通り処理し、DNSレコードもリバースプロキシサーバも用意でき、ようやく準備完了です。https://pages.mylan.local/plain-html/にアクセスすると以下の通り表示されると思います。

plain-html3

GitLab Pages and Mkdocs

以上1つ目の例はhtmlファイル、cssファイルなどを手動で用意したわけですが、もう一つGitLab Pagesで紹介したいものとして、Mkdocsについて簡単に触れていきます。これはSSG, static site generatorと呼ばれるものの一つで、Mkdocsはmarkdownファイルを元コンテンツファイルとして用意し、Mkdocsに処理させることで、ウェブサイトを構成するファイルあれこれを生成してくれます。

https://www.mkdocs.org/

今度は"pages"グループ配下に"mkdocs"という新規プロジェクトを作ります。

Mkdocsが必要とするファイルはまずmkdocs.ymlという設定ファイルで、あとはdocsディレクトリを用意してその配下にコンテンツをmarkdownファイルで用意します。

例えばこんなものができますという紹介をしたいので、設定ファイルなどは簡単に完成しているものを紹介させてください。

まずは/mkdocs.ymlファイルです。

site_name: Mkdocs and GitLab Pages
site_url: https://pages.mylan.local/mkdocs
site_description:
  "Mkdocs and GitLab Pages"
site_dir: public
theme:
  palette: # https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/
    scheme: default
    primary: green
    accent: blue
  name: material
  features:
    - tabs
    - navigation.top
  font:
    text: Noto Sans
    code: Oxygen Mono
markdown_extensions:
  - toc:
      permalink: true
      toc_depth: 3
plugins:
  - search
  - git-revision-date
  - awesome-pages
  - mermaid2:
      arguments:
        theme: 'forest'
extra_javascript:
    - https://unpkg.com/mermaid/dist/mermaid.min.js

次は/requirements.txtファイルです。これはMkdocs用というよりは、GitLab Runnerに利用させるファイルとなります。RunnerがMkdocsを実行するにあたって、指示書である.gitlab-ci.ymlファイルではpythonで必要なパッケージをインストールするよう記載されることになります。その時に参照するパッケージリストがこのファイルとなります。

# Mkdocs
mkdocs

# Theme
mkdocs-material

# Plugins
mkdocs-git-revision-date-plugin
mkdocs-mermaid2-plugin
mkdocs-awesome-pages-plugin

あとは/docsディレクトリを用意して好きな内容でmarkdownファイルを用意してください。今回お見せする例では最終的に以下のtree出力の通りとなりました。参考までに一つ、markdownファイルの中身もこのあと紹介します。

Markdownファイルの他に、.pagesというファイルもMkdocsが参照するもので、単に一行、そのフォルダをどう名付けて表示させるかが記載してあります。

この例では/docsフォルダ配下のファイル名がナンバリングされているのですが、TOC、目次生成される際の順番を考慮しての結果です。

https://www.mkdocs.org/user-guide/configuration/#markdown_extensions

❯ tree
.
 |-requirements.txt
 |-.git
 |-docs
 | |-index.md
 | |-20_placeholder
 | | |-.pages
 | | |-100.md
 | |-10_blog
 | | |-.pages
 | | |-105_posts.md
 | | |-100_posts.md
 |-README.md
 |-mkdocs.yml

では最後に.gitlab-ci.ymlファイルを用意します。GitLab公式にMkdocsの例もあり、そこのファイルをそのまま利用できます。この記事を書いている時点での話ですが、pythonイメージのタグは私が使うときには省きました。タグがないとRunnerは指定されたイメージの最新バージョンを利用します。

https://gitlab.com/pages/mkdocs

image: python

before_script:
  - pip install -r requirements.txt

test:
  stage: test
  script:
  - mkdocs build --strict --verbose --site-dir test
  artifacts:
    paths:
    - test
  rules:
    - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH

pages:
  stage: deploy
  script:
  - mkdocs build --strict --verbose
  artifacts:
    paths:
    - public
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

この指示書に従ってジョブが実行されると、https://pages.mylan.local/mkdocs/にアクセスすることでMkdocsが生成したウェブサイトが表示されます。

Mkdocsで例えば以下のようなウェブサイトが出来上がります。左ペインには目次があり、ページタイトルはmarkdownファイル内最初のh1の文字列が使われているようです。サブフォルダを設けて今回の例を作りましたが、.pagesファイルで指定した通りの名称で展開メニューが用意されています。また外部プラグインとして設定ファイルやパッケージリストに追加した、Mermaidという文字列から図を生成してくれるものも機能していることがわかります。

mkdocs

最後に、.pagesファイルと上に表示したページのmarkdownファイルの中身を参考までに紹介します。

まずは.pagesファイルです。

❯ cat docs/10_blog/.pages
title: Blog
❯ cat docs/20_placeholder/.pages
title: Another section - placeholder

次にmarkdownファイルの中身です。

❯ cat docs/10_blog/105_posts.md
# Second file

This is the second file.

# Another h1

Hello there.

## Mermaid

> https://mermaid-js.github.io/mermaid/

```mermaid
graph LR

    user -- http --> jupyter(jupyter.mylan.net:8888)

```

Closing

以上でこのシリーズは終了となります。実は他にもpythonではなくRustで動くmdBooksや、スライドショーを生成してウェブサイトとしてサーブさせられるmarpも紹介したいと思っているので、後日短いポストを追加するかもしれません。

私はネットワークエンジニアとして7年間仕事してきています。その中でいろいろなロールに携わって、バラエティ豊かなテクノロジーや製品に触れることができました。単にルータやスイッチだけでなく、DDI (DNS, DHCP, IPAM)、ロードバランサ、GSLB、ファイアウォール、インターネットプロキシなどなど扱うことができ、同時にプライベートではDockerで遊ぶことで様々な種類のサービスのセットアップや管理ができるようになりました。

ネットワーク・セキュリティインフラの製品を扱う他に、スクリプトを書いてタスクの自動処理、データ分析、レポート生成などする機会がありました。スクリプトを書いていると次第にgitの勉強もしたいと思い始め、そこがもともと自分のGitLabサーバを立ち上げる目的だったのですが、Gitlabで遊び始めるとそこからさらにスクリプト以外の書物もはかどっていき、CI/CD、GitLab Pages、多様なSSGなどでも遊び始めることができ、とても楽しくなりました。

おうちにこういった遊び場があるのはエンジニアにとって非常に大きなプラスだと思います。Docker自体の勉強にもなりますし、簡単にいろいろなサービスを試して遊び、勉強することができます。こういったところからぜひおうちの遊び場を作ることを薦めたいと思い、このシリーズを投稿しました。Docker試したい、GitLabで遊んでみたいといった方の参考になれば嬉しいです。

*その後、Kubernetesクラスタを構築しGitLabと連動させてGitopsなどでも遊んでいるので、シリーズで投稿するようなものがまとまればシリーズ第二弾として投稿したいと考えています

Discussion