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
関連記事
- kubernetes で GitLab および GitLab Runner を実行する設定サンプル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 minik...
- GitLab インストール手順 (CentOS 6)Git を用いたプロジェクト開発を複数人で行う場合、サーバーでレポジトリ管理を行えると便利です。何らかの事情で GitHub や Bitbucket を利用できない場合は、サーバーを構築して GitLab をインストールします。ここでは特に CentOS 6 の場合についてインストール手順をまとめます。 コマンドを実行するサーバーの用意 個人的な検証用途であれば Vagrant や Virtual...
- Git 中級者になるためのコマンド集履歴にタグを付与する (git tag) 一覧表示 タグだけを一覧表示 $ git tag ログにタグ情報を付与して表示 $ git log --decorate=full 直近のコミットにタグを付与 コメントあり $ git tag -a v1.0 -m 'コメント' コメントなし $ git tag v1.0 過去のコミットにタグを付与 履歴を調査 $ git log
- 複数の物理ホストの Debian9 上に Kubernetes (k8s) クラスタを Rancher で立ち上げるDocker オーケストレーションツールの一つに Kubernetes (k8s) があります。k8s 実行環境の構築方法は複数ありますが、ここでは AWS や GCP 等のクラウドサービスを利用せず、Debian9 がインストールされた複数台の物理マシンがネットワーク内に存在する状況を考えます。これら複数の Debian9 上に k8s クラスタを立ち上げるためには [Ranche
- RancherOS で構築した k8s クラスタ用に GlusterFS で簡単な分散ファイルシステムを構築k8s クラスタの各 Node マシンに GlusterFSサーバのコンテナを一つだけ起動して、簡単な分散ファイルシステムを構築します。各 Node へのコンテナ設置のためには DaemonSet が利用できそうですが、ここでは RancherOS の rancher.services を利用します。 1台構成 後に `rancher.ser