GitLab CI/CD Runner および .gitlab-ci.yml の設定例
[History] [Last Modified] (2019/10/17 15:43:36)
ここは
趣味のプログラミングを楽しむための情報共有サービス。記事の一部は有料設定にして公開できます。 詳しくはこちらをクリック📝
Recent posts
Popular pages

概要

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 のパスワードを設定します。

Uploaded Image

ユーザに SSH 鍵をします。

Uploaded Image

22 番以外のポートで clone するためには以下のようにします。

git clone ssh://git@localhost:10022/mygroup/myproject.git

参考 protected branches

レポジトリ内の Settings → Repository → Protected Branches によって、指定したブランチに push できないように設定できます。ワークフローとしてマージリクエストを強制したい場合などに有用です。

Uploaded Image

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 で設定ファイルを検証できます。

Uploaded Image

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-runnerregister を実行して 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 が実行されます。

登録に成功すると以下のような表示になります。

Uploaded Image

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

Uploaded Image

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 する権限を付与しておきます。

GitLab および GitLab Runner を k8s クラスタ内で起動して、GitLab Runner に他の Pod を起動する権限を role binding しておき、Kubernetes executor で Job を処理する設定はこちらです。

参考: クラスタ内の 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 内で設定した環境変数が利用できます。

Uploaded Image

  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

Uploaded Image

ジョブ実行のスケジューリング

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

Uploaded Image

スケジュールによるトリガー時のみ実行したい場合は onlyschedules を指定します。

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
Related pages
    概要 GitLab CI/CD 設定について、GitLab および GitLab Runner すべてを k8s 内で実行するサンプルを記載します。簡単のため minikube を利用します。 minikube config set memory 8192 minikube config set cpus 4 minikube start minikube ip 192.168.99.103 m