GitLab CI/CD について使い方を把握してみます。
検証用 GitLab の準備
簡単のため docker イメージを利用します。マウントしたディレクトリは、Docker エントリーポイントから実行される Chef によってプロビジョニングされます。
docker run \
--hostname localhost \
--publish 10443:443 --publish 10080:80 --publish 10022:22 \
--name gitlab \
--volume /tmp/gitlab/config:/etc/gitlab \
--volume /tmp/gitlab/logs:/var/log/gitlab \
--volume /tmp/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest
初回起動時は管理ユーザ root のパスワードを設定します。

ユーザに SSH 鍵をします。

22 番以外のポートで clone するためには以下のようにします。
git clone ssh://git@localhost:10022/mygroup/myproject.git
参考 protected branches
レポジトリ内の Settings → Repository → Protected Branches によって、指定したブランチに push できないように設定できます。ワークフローとしてマージリクエストを強制したい場合などに有用です。

API の利用
API 認証の方法の一つにアクセストークンの利用があります。アクセストークンは個人設定ページから発行できます。API リソース一覧のうち Issues リソースを取得する例は以下のようになります。
curl -sS --header 'PRIVATE-TOKEN: xxxx_NUQoNZWhQw1xnjQ' http://localhost:10080/api/v4/issues
.gitlab-ci.yml 設定
こちらのページを参照して Job の内容を設定します。.gitlab-ci.yml ファイルはレポジトリのルートディレクトリに設置します。動作確認のために以下のように設定してみます。Job 実行時にコミット内容を git clone せずに ok を echo します。
variables:
GIT_STRATEGY: none
run-test:
script:
- echo ok
/-/ci/lint を追加した http://localhost:10080/mygroup/myproject/-/ci/lint で設定ファイルを検証できます。

GitLab Runner 設定
GitLab Runner は .gitlab-ci.yml 設定によって生成された Job を処理するワーカです。Go で開発されたバイナリとして配布されています。GitLab Runner の実行方法は複数存在しますが、ここではホストの Docker コンテナとして実行する方法と、kubernetes Pod として実行する方法を試してみます。
Docker コンテナとして GitLab Runner を実行
Docker コンテナ内で Go バイナリ gitlab-runner を実行します。
docker run --rm --name gitlab-runner gitlab/gitlab-runner
docker exec で gitlab-runner の register を実行して GitLab に runner として登録します。--url には runner から GitLab にアクセスするための URL を指定します。
docker exec gitlab-runner gitlab-runner register \
--non-interactive \
--description my-runner \
--url http://172.17.0.1:10080/ \
--registration-token aJBwbSXygCPsEsFZw2s9 \
--executor shell
トークンは事前に GitLab から取得しておきます。GitLab のグループ内のすべてのプロジェクトで利用する場合は、グループの Settings → CI/CD → Runners → Set up a specific Runner manually でトークンを取得できます。プロジェクトの Settings からプロジェクト専用の Runner を登録することもできます。
gitlab runner は Job を処理する際に executor を実行します。executor の一つに shell があります。shell を利用すると、gitlab runner が実行されているホスト上で、runner から shell コマンドとして Job が実行されます。
登録に成功すると以下のような表示になります。

Git コミットを push するなどをトリガーとして Job が実行されます。

kubernetes Pod として GitLab Runner を実行
kubernetes クラスタ内に deployment/pod として GitLab runner docker container を起動します。Job の実行方法として選択できる executor は複数ありますが、毎回クリーンな環境で実行するためには SSH executor や Shell executor は不適です。Docker executor で Pod 内に docker コンテナを起動することもできそうですが、ここでは kubernetes executor を executor として利用します。そのために、以下のように runner の deployment には他の pod を create する権限を付与しておきます。
参考: クラスタ内の API を利用できる role を作成して runner deployment に binding
k8s には Role-based access control (RBAC) という仕組みがあります。default namespace における pod と deployment リソースの操作が可能な role を作成してみます。pod 内プロセスが k8s リソースを利用する際には ServiceAccount を利用します。新規に ServiceAccount を作成して、role を binding できます。
deployment と pods の操作が可能な role を作成して deployment から利用する例は以下のようになります。こちらのページに設定のサンプルがあります。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: gitlab-runner
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: gitlab-runner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gitlab-runner
subjects:
- kind: ServiceAccount
name: gitlab-runner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-runner
簡単のため nginx image を利用してみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
serviceAccountName: gitlab-runner
kubectl コマンドで API リソースが利用できることを確認します。
kubectl exec -it nginx-55c8bc94b4-27zm9 -- /bin/bash
apt update && apt install -y curl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x kubectl
mv kubectl /usr/local/bin/
kubectl get pods
kubectl get deployments
例えば services は role に設定していないため利用できません。
root@nginx-55c8bc94b4-27zm9:/# kubectl get service
Error from server (Forbidden): services is forbidden: User "system:serviceaccount:default:gitlab-runner" cannot list resource "services" in API group "" in the namespace "default"
その他の .gitlab-ci.yml 設定
環境変数の利用
GitLab が組込みでサポートする環境変数、Web UI から設定した環境変数、.gitlab-ci.yml 内で設定した環境変数が利用できます。

script:
- echo $GITLAB_USER_LOGIN
- echo $AAA
出力例
$ echo $GITLAB_USER_LOGIN
root
$ echo $AAA
123
ビルド成果物を artifacts として保存
Job 実行後に、指定した paths にマッチするファイルを runner から GitLab にアップロードして保存できます。Web UI からダウンロードしたり、別の Job から利用することができます。
myjob:
image: python:3.8-alpine
script:
- python --version
artifacts:
paths:
- README.md
expire_in: 1 week
出力例
$ python --version
Python 3.8.0
Uploading artifacts...
README.md: found 1 matching files
Uploading artifacts to coordinator... ok id=11 responseStatus=201 Created token=nAHRxd3i
Job succeeded

ジョブ実行のスケジューリング
パイプラインは、git push をトリガーとした実行の他に、cron のようにスケジュールを設定して実行することもできます。設定したスケジュールは Web UI から手動で任意のタイミングで実行することもできます。

スケジュールによるトリガー時のみ実行したい場合は only で schedules を指定します。
myjob-only-schedules:
image: python:3.8-alpine
only:
- schedules
script:
- echo myjob-only-schedules
myjob:
image: python:3.8-alpine
script:
- echo myjob
Git submodules の利用
git submodule を利用するレポジトリの場合は GIT_SUBMODULE_STRATEGY 環境変数を設定する必要があることに注意します。
variables:
GIT_SUBMODULE_STRATEGY: recursive
GitHub Actions とか CI/CD が好きです。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。



