1. はじめに
- ソフトウェア開発メンバへの勉強会資料をローカルweb公開するにあたり、文書作成をsphinxを用いて作成することにしたのですが、文書の構成管理、ビルド、デプロイなど勉強会資料を効率的に運用しないと、後々手間だなぁ、と感じていました。
- もともと、構成管理にはGitLabを利用していたので、いっそのことビルドやデプロイもGitLabおよびその関連機能で効率化したいと思い、GitLab CI環境とGitLab Pages環境を構築し、sphinx文書をmasterブランチにMergeすればPagesに自動デプロイする環境を整備しました。
- 本文を執筆するにあたり、文中にローカルのGitLabにアクセスするアドレスが「https://~~~」と書かれている箇所がありますが、変なリンクにならないようにhを「h(全角)」にしています。
2. 参考ページ
-
GitLabの継続的インテグレーション(CI)と継続的デリバリー(CD)
- GitLabに組み込まれているCICDの仕組みの紹介
-
GitLab CE on Docker Compose (HTTPS + Container Registry + Runner)でSSH設定してなかったので追加
- GitLab + runner環境をdockerで構築する方式はこちらのページを参考に作成しております。
-
GitLab 10.1 に GitLab CI + GitLab Pages + Sphinx でドキュメントビルド環境を整える
- 今回のCIパイプラインの構築はこちらのページを参考に作成しております。
-
docker-composeを使って最速で社内DNSを構築してみた
- corednsの設定はこちらのページを参考に作成しております。
-
Draw.io
- こちらのページの図はDraw.ioで作図しています。
3. 全体像
- Ubuntuサーバ上に、以下の図のようにGitLabコンテナ、runnerコンテナ、DNS(coredns)コンテナを構築します。
- br-xxxxはdocker-networkと紐づくブリッチで、docker-network構築時に生成されます。
- 各コンテナ間はdocker-networkのmynetで接続します。
- 利用するGitLabはgitlab-ce 13.12を用います。
- develop envは個人の開発環境コンテナを想定していますが、ここでは他のコンテナを操作できようようdoodコンテナを構築します。
4. 構築
4.1. ディレクトリ構成
─── DevOps
├── coredns # corednsマウント領域
├── docker-compose.yml # コンテナ構成
├── gitlab # gitlabマウント領域
├── gitlab-runner # gitlab-runnerマウント領域
4.2. docker-compose.ymlの構成
- あれこれ試行錯誤した結果となっております。
version: '3.7'
services:
gitlab-ce.com:
image: gitlab/gitlab-ce:13.12.7-ce.0
hostname: gitlab-ce.com
ports:
- "8443:8443"
- "25000:25000"
volumes:
- ${PWD}/gitlab/config:/etc/gitlab:Z
- ${PWD}/gitlab/logs:/var/log/gitlab:Z
- ${PWD}/gitlab/data:/var/opt/gitlab:Z
- ${PWD}/gitlab/registry:/var/opt/gitlab/gitlab-rails/shared/registry:Z
- ${PWD}/gitlab/gitlab-cert:/etc/gitlab/ssl
networks:
mynet:
ipv4_address: 192.168.10.10
dns: 192.168.10.253
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab-ce.com:8443'
nginx['listen_port'] = 8443
gitlab_rails['time_zone'] = 'Asia/Tokyo'
registry_external_url 'https://gitlab-ce.com:25000'
gitlab_rails['registry_enabled'] = true
pages_external_url "https://gitlab-ce.io:8443"
gitlab_pages['enable'] = true
gitlab_pages['inplace_chroot'] = true
pages_nginx['redirect_http'] = true
pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab-ce.com.crt"
pages_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab-ce.com.key"
gitlab-runner:
image: gitlab/gitlab-runner:alpine-v13.12.0
hostname: runner
volumes:
- ${PWD}/gitlab-runner/config:/etc/gitlab-runner
- ${PWD}/gitlab/gitlab-cert:/etc/gitlab-runner/certs
- /var/run/docker.sock:/var/run/docker.sock
dns: 192.168.10.253
networks:
mynet:
ipv4_address: 192.168.10.11
depends_on:
- gitlab-ce.com
coredns:
image: coredns/coredns:1.8.4
container_name: coredns
expose:
- '53'
- '53/udp'
volumes:
- ${PWD}/coredns/config:/etc/coredns
entrypoint: "/coredns -conf /etc/coredns/Corefile"
networks:
mynet:
ipv4_address: 192.168.10.253
kensho:
image: docker:dind
hostname: kensho
environment:
- DOCKER_TLS_CERTDIR=/certs
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${PWD}/gitlab/gitlab-cert:/certs
dns: 192.168.10.253
networks:
mynet:
ipv4_address: 192.168.10.100
entrypoint: "/bin/sh -c 'sleep 100000'"
networks:
mynet:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.10.0/24
4.3. 準備
4.3.1. 簡易にオレオレ証明書を発行
- gitlab/gitlab-cert以下に移動し、以下のコマンドを実行します。
$ sudo openssl req -newkey rsa:4096 -nodes -sha256 -keyout ./gitlab-ce.com.key -x509 -days 3650 -out ./gitlab-ce.com.crt -subj '/CN=gitlab-ce.com/'
$ ln -s gitlab-ce.com.crt gitlab-ce.com.cert
4.3.2. ホストOSにて:GitLabアクセス向けにhosts設定
- GitLabのUIにアクセスするときに、ホスト名でのアクセスが必要になるので、/etc/hostsに追記します。
- なお、コンテナ間のアクセスはcorednsで名前解決させます。
- ただし、今回の構成の場合、同一サーバ内でcomposeで構築しているため、compose内で名前解決できてしまうので恩恵が少ないです。
# /etc/hostsに以下を追加する
192.168.10.10 gitlab-ce.com
4.3.3. ホストOSにて:dockerdにオレオレ証明書の設定
- /etc/docker/certs.dに先程のオレオレ証明書を設定しておきます。
- docker-compose.ymlの設定では、GitLabコンテナレジストリをport 25000で構築するので、ホスト名:25000の名称でシンボリックリンクを張ります。
$ cd /etc/docker/certs.d
$ ln -s (ルートディレクトリ)/DevOps/gitlab/gitlab-cert gitlab-ce.com:25000
4.3.4. corednsの設定ファイル
- coredns/config以下に、以下の内容が記述されたCorefileとhostsを用意してください。
# Corefile -----------------------------------------
. {
whoami
errors
log . "{proto} {remote} is Request: {name} {type} {>id}"
hosts /etc/coredns/hosts {
fallthrough
}
reload
}
# hosts --------------------------------------------
192.168.10.10 gitlab-ce.com
4.4. 起動
- docker-compose up -dで起動します。
- gitlabは起動に時間がかかるので気長に待ってください。statusがhealthyになったらアクセスできます。
$ cd (ルートディレクトリ)/DevOps
$ docker-compose up -d
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------------------------------------------------
coredns /coredns -conf /etc/coredn ... Up 53/tcp, 53/udp
devops_gitlab-ce.com_1 /assets/wrapper Up (healthy) 22/tcp, 0.0.0.0:25000->25000/tcp, 443/tcp, 80/tcp, 0.0.0.0:8443->8443/tcp
devops_gitlab-runner_1 /usr/bin/dumb-init /entryp ... Up
devops_kensho_1 /bin/sh -c sleep 100000 Up 2375/tcp, 2376/tcp
4.5. GitLabの設定
4.5.1. 初回アクセス&グループ・ユーザ作成
- GitLabコンテナが起動したら、ブラウザで「https://gitlab-ce.com:8443/」にアクセスします。
- オレオレ証明書なので、以下のような警告が出るのですが、アクセスしてください。
- はじめに、rootユーザのパスワード登録がでるので、好みのパスワードを設定してください。
- gitlabのログイン画面となるので、rootユーザでログインする。
- 設定の詳細は省くが、管理者エリアから以下のようなグループとユーザを作成する。以降の操作は、tomotenユーザで実施する。
- 公開グループ:public-group
- プライベートグループ:developer
- 個人ユーザ:tomoten (public-groupとdeveloperのmaintainer)
4.5.2. パブリックなコンテナレジストリの作成
- tomotenユーザでログインし、public-groupグループ内で公開プロジェクト「docker-registry」を作成します。特に何もコミット予定がないので、テキトーなREADMEを作成しておきます。
- 「docker-registry」プロジェクトの「Packages & Registries」→「Container Registry」を選択する。
- コンテナレジストリへのアクセス方法が記載されているので、ホストOS側からdocker loginを実施する。
$ docker login gitlab-ce.com:25000
Authenticating with existing credentials...
Login did not succeed, error: Error response from daemon: Get https://gitlab-ce.com:25000/v2/: unauthorized: HTTP Basic: Access denied
Username: tomoten
Password:
WARNING! Your password will be stored unencrypted in /home/tomoten/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
- コンテナイメージの登録として、この後sphinxのビルドを実施するため、Docker hubにある「tomoten/sphinx-rtd-container:latest」をGitLabコンテナレジストリに登録する。
$ docker pull tomoten/sphinx-rtd-container:latest
$ docker image tag tomoten/sphinx-rtd-container:latest gitlab-ce.com:25000/public-group/docker-registry/sphinx-rtd-container:1.0
$ docker push gitlab-ce.com:25000/public-group/docker-registry/sphinx-rtd-container:1.0
4.5.3. sphinx文書の管理プロジェクトの作成&runner登録
-
引き続きtomotenユーザで、developerグループ内でプライベートプロジェクトstudy-pageを作成します。
-
「Settings」→「CI/CD」→「Runners」を選択すると、gitlab-runnerを登録するために必要な情報が載っています。
-
ターミナルからgitlab-runnerコンテナ内に入り、登録処理を実施します。
$ cd (ルートディレクトリ)/DevOps
$ docker-compose exec gitlab-runner /bin/sh
(gitlab-runnerコンテナ内)
$ gitlab-runner register
Runtime platform arch=amd64 os=linux pid=24 revision=7a6612da version=13.12.0
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab-ce.com:8443/ # ユーザ入力
Enter the registration token:
th36JjU1Fxs-o8k9UcpY # ユーザ入力
Enter a description for the runner:
[runner]: sphinx builder # ユーザ入力
Enter tags for the runner (comma-separated):
sphinx # ユーザ入力
Registering runner... succeeded runner=th36JjU1
Enter an executor: virtualbox, docker-ssh+machine, kubernetes, docker-ssh, parallels, shell, ssh, custom, docker, docker+machine:
docker # ユーザ入力
Enter the default Docker image (for example, ruby:2.6):
centos:7.6.1810 # ユーザ入力(テキトーに入れた)
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
$ exit
4.5.4. runnerの動作確認(はじめは失敗します)
- 「study-page」直下の.gitlab-ci.ymlはデフォルトでは以下のようになっています。
image: alpine:latest
pages:
stage: deploy
script:
- echo 'Nothing to do...'
artifacts:
paths:
- public
only:
- master
-
ブラウザ上でいいので、テキトーにREADME.mdを微修正して、masterにMergeします。
-
masterにMergeされるとCIパイプラインが稼働を始める。
-
「CI/CD」→「Pipelines」を表示するとパイプラインが表示されるが、pendingのままとなります。
-
パイプラインをCancelで停止します。
-
「CI/CD」→「Editer」から先ほどの.gitlab-ci.ymlを開き、以下のように修正して保存します。
image: alpine:latest
pages:
stage: deploy
tags:
- sphinx
script:
- echo 'Nothing to do...'
artifacts:
paths:
- public
only:
- master
-
masterにMergeされるので、再度パイプラインが稼働します。今度は、runningとなります。ただし、最終的にfailとなり、失敗します。
-
「failed」→「pages」と押下して、jobのログを確認すると、以下のようになります。
Running with gitlab-runner 13.12.0 (7a6612da)
on sphinx builder UgtRMDK9
Preparing the "docker" executor
01:05
Using Docker executor with image alpine:latest ...
WARNING: Pulling GitLab Runner helper image from Docker Hub. Helper image is migrating to registry.gitlab.com, for more information see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#migrate-helper-image-to-registrygitlabcom
Pulling docker image gitlab/gitlab-runner-helper:x86_64-7a6612da ...
Using docker image sha256:3e2ebd33de6df91fd9e89c4f814f1e5fa357982aabcc4311ea2616d556f448d1 for gitlab/gitlab-runner-helper:x86_64-7a6612da with digest gitlab/gitlab-runner-helper@sha256:c96ecb7474c62872b7675915daaa216208ec98b5bae45dc9841607d6a2cc2e25 ...
Pulling docker image alpine:latest ...
Using docker image sha256:d4ff818577bc193b309b355b02ebc9220427090057b54a59e73b79bdfe139b83 for alpine:latest with digest alpine@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0 ...
Preparing environment
00:10
Running on runner-ugtrmdk9-project-4-concurrent-0 via runner...
Getting source from Git repository
00:06
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/developer/study-page/.git/
Created fresh repository.
fatal: unable to access 'https://gitlab-ce.com:8443/developer/study-page.git/': Could not resolve host: gitlab-ce.com
Cleaning up file based variables
00:03
ERROR: Job failed: exit code 1
- ログを確認すると、以下のことがわかります。
- executorに「docker」を指定しているため、追加で「GitLab Runner helper」のイメージをpullしています。もし、オフライン環境でgitlab runner環境を構築する場合は、事前に「gitlab/gitlab-runner-helper:x86_64-7a6612da」イメージをDocker hubから取得しておく必要がありあます。
- 今回問題となっているのは、「fatal: unable to access ...」であり、gitlab runner内部でgitlab-ce.comの名前解決ができていないのが問題のようです。
- ホストOS側にて、gitlab-runner/config以下にあるconfig.tomlを以下のように修正します。
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "sphinx builder"
url = "https://gitlab-ce.com:8443/"
dns = "192.168.10.253" # 追加
token = "UgtRMDK9pgJN4cBzamLy"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "centos:7.6.1810"
privileged = true # 修正
network_mode = "devops_mynet" # 追加
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
- 修正後、gitlab-runnerコンテナを再起動します。
$ cd (ルートディレクトリ)/DevOps
$ docker container ls | grep runner
443dc89510e0 gitlab/gitlab-runner:alpine-v13.12.0 ... devops_gitlab-runner_1
$ docker container stop devops_gitlab-runner_1
$ docker container rm devops_gitlab-runner_1
$ docker-compose up -d gitlab-runner
- GitLabの「study-page」の「CI/CD」→「Pipelines」を再度表示し、「Run pipeline」からパイプラインを稼働させます。
- 無事成功します(成功するはずです)。
4.5.5. GitLab Pagesの有効化
-
「Settings」→「Pages」を選択すると、Pagesへアクセスするためのアドレス「https://developer.gitlab-ce.io:8443/study-page」 が表示されています。
-
ホストOS側の/etc/hostsとcoredns/config/hostsにdeveloper.gitlab-ce.ioを追加します。
# hosts
192.168.10.10 gitlab-ce.com developer.gitlab-ce.com
4.6. sphinx文書をGitLab CIでビルド→Pagesへのデプロイ
- sphinx文書は、ここではテンプレートとしてGithubに公開しているmy-sphinx-templateの中身を利用します。
- my-sphinx-templateの中身をstudy-pageにコピーして、masterにMergeします。
- githubのプロジェクトをローカルのGitLabにpushし直せばいいのですが、gitlab-runnerの再登録が面倒なので、コピーして登録しています。
- このとき、publicの中身を空(.gitignoreのみ)にしておいてください。
- GitLabの「study-page」プロジェクトにて、「CI/CD」→「Editer」から.gitlab-ci.ymlを開き、以下のように修正して保存します。
- imageとして、GitLabのdocker-registryに登録したsphinx-rtd-container:1.0を指定します。
- artifactsとしてpublicディレクトリを指定し、ビルドしたsphinx文書を格納すると、GitLab Pagesにデプロイできます。
image: gitlab-ce.com:25000/public-group/docker-registry/sphinx-rtd-container:1.0
stages:
- deploy
pages:
stage: deploy
tags:
- sphinx
script:
- make html
- mv build/html/* public/
artifacts:
paths:
- public
only:
- master
- GitLabの「study-page」プロジェクトにて、「CI/CD」→「Pipelines」からpipelineのステータスがpassedとなるか確認してください。(passedになるはずです)
- このプロジェクトのGitLab Pages「https://developer.gitlab-ce.io:8443/study-page」にアクセスすると、sphinx文書で作成されたページになっていることを確認できます。
5. おわりに
- 今回は、サーバ1台上での簡易的な構成となりました。できれば複数サーバでgitlab runnerを運用したいところです。
- 改めて、gitlab runnerの基本的な使い方やexecutorにdockerを指定したときの挙動がわかったのは良かったです。
- オレオレ証明書の作り方は、本当に手抜きしているので参考にしないでください。ちゃんと公開鍵を作らないとダメです。