GitLabとコンテナプラットフォームの連携

目次

はじめに

昨今の開発環境においては、オンプレミスであってもコンテナアプリケーションを稼働させたいというニーズが高まっています。
その様なオンプレミスかつ外部インターネットに接続できない閉域環境などでも、効率的かつセキュアな開発基盤の整備は欠かせません。
こうした環境では、GitHubのようなパブリックサービスは利用が難しいため、自社内で完結できるソースリポジトリおよびCI/CDプラットフォームとしてGitLabが有力な選択肢として挙げられます。

閉域環境において、CI/CDとKubernetesやOpenShiftといったコンテナプラットフォームを統合したい企業にとっては、GitLabを中核とした構成が現実的かつ強力な選択肢となります。

本シリーズでは、そのようなユースケースを想定し、閉域網におけるGitLabとコンテナプラットフォーム(本記事ではOpenShift)とのCI/CD構築や連携方法を解説します。

今回はシリーズの第一回として、GitLabの構築手順と、閉域環境のOpenShiftクラスターとの連携方法を中心に解説します。

検証環境構成

本記事では、GitLabと閉域環境のOpenShiftクラスターを連携させたCI/CD基盤の構築手順を紹介します。今回構築した検証環境の構成は以下の通りです。

  • 外部インターネットに接続可能なサーバー上にGitLabを構築
  • 閉域環境下のOpenShiftクラスターにGitLab Runnerをデプロイし、GitLabと連携
  • 踏み台サーバー が以下の機能を兼任:
    • GitLabとOpenShift間の名前解決を行う内部DNSサーバー
    • コンテナの永続ストレージや、GitLabのコンテナレジストリ格納領域を提供する NFSサーバー
    • 必要なトラフィックのルーティングを担う ロードバランサー

※本記事では GitLab の構築に焦点を当てており、踏み台サーバーや OpenShift クラスターの構築手順については割愛しています。
※「コンテナプラットフォーム」は一般的なKubernetes基盤を指し、本記事で使用する「OpenShiftクラスター」はその具体的な構築済み環境を意味します。

目標

本記事での検証構成では、以下の実現を目標とします。

  • GitLabのインストールと初期設定
  • OpenShiftクラスターへのGitLab Runnerのデプロイ
  • GitLabとGitLab Runner間の連携の確立

構築手順についても上記の順に沿って解説します。

用語説明

GitLab:ソースコード管理(Git)、コンテナレジストリ、CI/CD など、開発に必要な機能を統合したオールインワンのプラットフォーム。

GitLab Runner:GitLabのCI/CDジョブを実行するためのエージェント。様々な実行環境(Kubernetes、Docker、Shellなど)で動作可能。

Kubernetes Executor:GitLab Runner が Kubernetes クラスター上で Pod を動的に起動し、ジョブを実行するモード。Kubernetes 環境でのCI/CDに最適。

構築情報

本記事では、以下の構成と前提条件に基づいてGitLabを構築しています。

前提条件

以下の環境はあらかじめ構築済みであることを前提としています。

  • 外部インターネットに接続できない OpenShift クラスター
  • OpenShift用のミラーレジストリーサーバー
  • 踏み台サーバー兼作業用端末
    OpenShiftクラスターにアクセス可能であり、以下の役割を兼任:
    • 内部DNSサーバー
      • GitLab、GitLab Container Registry、OpenShift クラスター間の名前解決を提供
    • NFSストレージサーバー
      • OpenShift内のコンテナで使用される永続ストレージ(PersistentVolume)を提供
    • ロードバランサー
      • OpenShiftクラスターへの HTTPS 通信(APIや Webコンソール)を中継
  • GitLabの内部公開用ドメインを取得済み
    • 取得したドメインは踏み台サーバーの内部DNSに登録済み

※ 本記事では OpenShiftクラスターおよび踏み台サーバーの構築手順は割愛しています。

GitLabサーバー構成

  • OS: RHEL9.4
  • CPU: 8コア
  • メモリ: 16GB
  • ストレージ: 200GB

GitLab公式ドキュメント:Reference Architectureのうち、最小構成に準拠。実際に必要なリソースは利用規模(秒間リクエスト数やユーザー数)により変動します。

バージョン情報

  • GitLab: 18.2.1
  • GitLab Runner: 18.2.0
  • GitLab エディション: Community Edition

※ GitLab本体はバージョン 18.2.1、GitLab Runnerはバージョン 18.2.0を使用しています。 
なお、公式ドキュメントによれば、同一マイナーバージョン内でのパッチバージョン差は互換性に影響せず、連携にも問題がないため、本構成でも正常に動作することを確認済みです。
※本記事のOpenShiftクラスターはOpenShift 4.x系で構築されていますが、Kubernetes標準に準拠したクラスターであれば同様の構成が可能です。

GitLabの構築

GitLabは、Linuxパッケージを用いた手動インストールや、HelmチャートやOperatorによるKubernetes上へのデプロイなど、複数の構築手段が提供されています。
本記事では、RHELサーバー上にLinuxパッケージを用いてGitLab Community Editionを構築する方法を紹介します。

必要なツールのインストール

GitLabをインストールするRHELサーバーにログインし、rootユーザーに切り替えます。

$ sudo su -

作業用ディレクトリを作成します。

# mkdir -p /data/work
# cd /data/work

GitLabの構築に必要なパッケージをインストールします。

# dnf install curl nfs-utils openssl postfix -y

※ツールの説明:

  • curl: GitLabのリポジトリ追加で使用
  • nfs-utils: 踏み台サーバー内のNFS共有ディレクトリを利用するために使用
  • openssl: 自己署名証明書の作成に使用
  • postfix: メール通知機能に使用(今回はローカル送信のみ)

GitLabのインストール

GitLabのリポジトリを追加し、外部公開URLを指定してGitLabパッケージをインストールします。

# curl "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh" | bash
# EXTERNAL_URL=https://gitlab.local.example.com \
dnf install gitlab-ce

自己署名証明書の作成と配置

今回は内部DNSを使用する閉域環境のため、自己署名証明書を利用します。まずは、GitLabサーバーのドメインとGitLabコンテナレジストリのドメインの自己署名証明書を作成します。

自己署名証明書を作成するための秘密鍵を作成します。

# openssl genpkey -algorithm RSA -out gitlab.local.example.com.key -pkeyopt rsa_keygen_bits:2048


証明書の情報を記載した設定ファイルを作成します。
alt_namesにGitLabサーバーのドメインとGitLabコンテナレジストリのドメインを設定します。

# vi san.cf

[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[ req_distinguished_name ]
C = JP
ST = Tokyo
L = Minato-city
O = My Local Environment
OU = My Team
CN = gitlab.local.example.com

[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = gitlab.local.example.com
DNS.2 = registry.gitlab.local.example.com

作成した秘密鍵と設定ファイルを利用して、自己署名証明書を作成します。

# openssl req -new -key gitlab.local.example.com.key \
-out gitlab.local.example.com.csr -config san.cnf

# openssl x509 -req -days 3650 -in gitlab.local.example.com.csr \
-signkey gitlab.local.example.com.key \
-out gitlab.local.example.com.crt \
-extfile san.cnf -extensions v3_req

# 作成結果の確認
# openssl x509 -in gitlab.local.example.com.crt -noout -text

# 出力例(一部省略)
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgIULJoazWr+hErKovG2ZiUSZ5qtHxswDQYJKoZIhvcNAQEL
...
-----END CERTIFICATE-----

作成した自己署名証明書と秘密鍵をGitLabのSSLディレクトリにコピーします。

# cp gitlab.local.example.com.jp.crt /etc/gitlab/ssl
# cp gitlab.local.example.com.key /etc/gitlab/ssl

ファイルのパーミッション設定を以下のように行います。

  • 証明書ファイル(.crt)は読み取り専用(644)にします。
  • 秘密鍵(.key)は機密性が高いため、所有者のみ読み書き可能(600)にします。
# chmod 644 /etc/gitlab/ssl/gitlab.local.example.com.crt
# chmod 600 /etc/gitlab/ssl/gitlab.local.example.com.key

GitLab設定ファイルの編集

GitLabの設定ファイル /etc/gitlab/gitlab.rb を編集します。

# vi /etc/gitlab/gitlab.rb

下記に示す内容を設定ファイル/etc/gitlab/gitlab.rbに記載します。

基本設定(外部公開URL)

参考:https://docs.gitlab.com/omnibus/settings/ssl/#configure-https-manually

これらの設定はGitLabにアクセスするためのURLを設定します。今回は自己署名証明書を利用するので、Let’s Encrypt設定を無効化します。また、ドメイン名が長すぎるとエラーが起きるので、nginx[‘server_names_hash_bucket_size’] = 128と設定します。

external_url "https://gitlab.local.example.com"
letsencrypt['enable'] = false
nginx['server_names_hash_bucket_size'] = 128  # ドメイン名が長い場合のエラー対策

コンテナレジストリ設定(プライベートレジストリとして使用)

参考:https://docs.gitlab.com/administration/packages/container_registry/#container-registry-domain-configuration

これらの設定はGitLabコンテナレジストリの設定をします。アクセスするためのURLやその証明証書ファイルを指定します。今回はコンテナレジストリのディレクトリを踏み台サーバーにマウントするので、gitlab_rails[‘registry_path’]にはマウントするディレクトリを設定します。

registry_external_url "https://registry.gitlab.local.example.com"
registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.local.example.com.crt"
registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.local.example.com.key"
gitlab_rails['registry_path'] = "/mnt/gitlab-registry"

メール通知設定(Postfixによるローカル配送)

参考:https://docs.gitlab.com/omnibus/settings/smtp/

これらの設定はGitLabのメール通知設定を行います。GitLabサーバー上のPostfixのSMTPサーバーにメール通知する設定をします。

gitlab_rails['gitlab_email_from'] = 'gitlab@example.com'
gitlab_rails['gitlab_email_display_name'] = 'GitLab'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "127.0.0.1"
gitlab_rails['smtp_port'] = 25
gitlab_rails['smtp_domain'] = "localhost"
gitlab_rails['smtp_authentication'] = "none"
gitlab_rails['smtp_enable_starttls_auto'] = false
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_ssl'] = false

設定の適用と動作確認

GitLabの設定適用

上記の /etc/gitlab/gitlab.rbを記載したら以下のコマンドでGitLabの設定を適用します。

# gitlab-ctl reconfigure

サービスの状態確認

GitLabのサービスの状態を確認します。

# gitlab-ctl status

全てのサービスがrun:と表示されていれば正常です。

(例)
run: alertmanager: (pid 1319) 3117s; run: log: (pid 1317) 3117s
run: crond: (pid 1309) 3117s; run: log: (pid 1305) 3117s
run: gitaly: (pid 1284) 3117s; run: log: (pid 1282) 3117s
run: gitlab-exporter: (pid 1316) 3117s; run: log: (pid 1308) 3117s
run: gitlab-kas: (pid 1310) 3117s; run: log: (pid 1296) 3117s
run: gitlab-workhorse: (pid 1307) 3117s; run: log: (pid 1306) 3117s
…(省略)

以上でGitLabのインストールと初期構成は完了です。続いて、WebブラウザからGitLabにアクセスし、初期設定を行います。

GitLabの初期設定

初期パスワードの確認

GitLabの初回ログイン用パスワードは、インストール時に自動生成され/etc/gitlab/initial_root_password に保存されています。

以下のコマンドで確認します。

# cat /etc/gitlab/initial_root_password

Webコンソールへのアクセス

ブラウザからexternal_url に設定したドメインにアクセスします。
初回アクセス時には、次のようなログイン画面が表示されます。

  • ユーザー名:root
  • パスワード:上記で確認した初期パスワード

※本検証では、閉域環境の内部DNSドメインを使用しているため、外部接続可能なサーバーからVNCコンソール経由でアクセスしています。オフライン環境でもGUIでログイン・操作ができるよう、ネットワーク経路の確保またはポートフォワーディングなどの工夫が必要です。

ユーザーインターフェースの言語を日本語に変更

GitLabインストール直後のUIは英語表記になっています。日本語に切り替えるには、以下の手順で設定します。

  1. サイドメニューから[User settings] > [Preferences] > [Localization]と選択し、ローカライズ設定画面に移動
  2. ローカライズ設定画面の[Language]欄でJapaneseを選択すると、言語環境を日本語に変更

これで、GitLabの管理者アカウントでのログインと基本的なUI設定が完了しました。
次のステップでは、GitLab Runner の登録および CI/CD 環境の構築へと進みます。

GitLab Runnerの構築

本セクションでは、閉域環境の OpenShift クラスターに GitLab Runner をデプロイし、GitLab 本体と連携させる手順を解説します。
GitLab Runnerは Kubernetes Executor を利用し、OpenShift上でCI/CDジョブ用のPodを動的に起動します。

※Kubernetes Executorとは:
GitLab Runnerの実行方式の一つで、CI/CDジョブごとに Kubernetes上に一時的なPodを生成してジョブを実行するモードです。本記事では、このKubernetes Executorを用いてRunnerを構成します。

構築フロー概要

以下の手順で GitLab Runner を構築・連携します:

  • コンテナイメージを配置するプロジェクトを作成
  • GitLab用のプライベートレジストリに必要なコンテナイメージを事前格納
  • GitLab管理コンソールで Runnerを登録し、トークンを取得
  • Helmチャートを用いて OpenShiftにRunnerをデプロイ
  • 証明書・認証情報をOpenShift側に連携
  • Runnerの稼働確認

プロジェクトの作成

GitLabのコンソールから[+]を選択し、新規プロジェクトを作成します。

GitLabコンテナレジストリにイメージを格納

プロジェクトを作成したら、踏み台サーバーにログインし、ターミナルからRunnerが必要とする資材を取得します。

利用イメージ(例)

用途イメージ名
GitLab Runner 本体gitlab-org/gitlab-runner:alpine-v18.2.0
ジョブPodベースイメージalpine:latest

操作手順(RHEL + Podman 利用例)

※Docker 利用環境ではpodman → dockerに置き換えてください。

# podman login registry.gitlab.local.example.com

# podman pull registry.gitlab.com/gitlab-org/gitlab-runner:alpine-v18.2.0
# podman pull docker.io/library/alpine:latest

# podman tag registry.gitlab.com/gitlab-org/gitlab-runner:alpine-v18.2.0 registry.gitlab.local.example.com/<ユーザー名>/<プロジェクト名>/gitlab-runner:alpine-v18.2.0
# podman tag docker.io/library/alpine:latest registry.gitlab.local.example.com/<ユーザー名>/<プロジェクト名>/alpine:latest

# podman push registry.gitlab.local.example.com/<ユーザー名>/<プロジェクト名>/gitlab-runner:alpine-v18.2.0
# podman push registry.gitlab.local.example.com/<ユーザー名>/<プロジェクト名>/alpine:latest

GitLab上で Runner を登録

続いて、GitLab上でRunnerを登録します。本手順はGitLabのコンソール画面にログインして実施します。

  1. GitLab管理コンソールにログイン
  2. サイドメニューから[管理者メニュー] → [CI/CD] → [Runner]と移動
  3. [Create instance runner] を選択
  4. 任意のタグを入力し、[Runnerを作成]
  5. 表示された認証トークン(例: glrt-xxxxxxx)を控えておく

※本記事では、インスタンスRunner(全プロジェクトで利用可能なRunner)を採用しています。

Helmチャートの取得と展開準備

OpenShiftではOperatorを利用してGitLab Runnerをインストールすることも可能ですが、本環境は閉域構成のためOperatorの自動更新によるメリットを十分に活かせません。そこで今回は、Helm チャートを使用してGitLab Runner をインストールします。
本手順は踏み台サーバー内で実施します。

GitLabから提供されているRunnerのHelmチャートを取得

# helm repo add gitlab https://charts.gitlab.io
# helm repo update
# helm pull gitlab/gitlab-runner --version 0.79.0

OpenShift上の事前設定

OpenShiftにRunnerをデプロイするための準備を行います。
本手順は踏み台サーバー内で実施します。

Namespace 作成

GitLab Runnerのリソースを管理するNamespaceを作成します。

# oc create namespace gitlab-runner-test

ServiceAccount & SCC(anyuid)設定

OpenShiftでJobを実行するServiceAccountを作成します。

# oc create sa gitlab-runner-sa -n gitlab-runner-test

ServiceAccountの権限設定するgitlab-runner-sa-role.yaml を作成し、以下を適用します。

# vi gitlab-runner-sa-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: scc-anyuid
  namespace: gitlab-runner-test
rules:
- apiGroups:
  - security.openshift.io
  resourceNames:
  - anyuid
  resources:
  - securitycontextconstraints
  verbs:
  - use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-to-scc-anyuid
  namespace: gitlab-runner-test
subjects:
- kind: ServiceAccount
  name: gitlab-runner-sa
roleRef:
  kind: Role
  name: scc-anyuid
  apiGroup: rbac.authorization.k8s.io


# oc apply -f gitlab-runner-sa-role.yaml

OpenShiftに証明書と認証情報を登録

レジストリCAの登録(自己署名証明書対応)

証明書を踏み台サーバーのコンテナ証明書ストアに保存します。

$ mkdir -p /etc/containers/certs.d/registry.gitlab.local.example.com
$ openssl s_client -showcerts -connect registry.gitlab.local.example.com:443 < /dev/null | sudo tee /etc/containers/certs.d/registry.gitlab.local.example.com/ca.crt > /dev/null

GitLabコンテナレジストリの証明書をOpenShiftのCAストアに登録します。

# oc create configmap gitlab-runner-ca -n openshift-config \
--from-file=registry.gitlab.local.example.com=/etc/containers/certs.d/registry.gitlab.local.example.com/ca.crt
# oc patch image.config.openshift.io/cluster --patch '{"spec":{"additionalTrustedCA":{"name":"gitlab-runner-ca"}}}' --type=merge

プライベートレジストリのPull認証設定

GitLab RunnerのJobを実行するServiceAccountがコンテナレジストリにアクセスできるようにするために、証明書の認証情報をServiceAccountに紐づけます。

# oc create secret docker-registry gitlab-registry-secret \
--docker-server="registry.gitlab.local.example.com" \
--docker-username="<ユーザー名>" \
--docker-password="***" \
-n gitlab-runner-test

# oc secrets link gitlab-runner-sa gitlab-registry-secret --for=pull -n gitlab-runner-test

GitLab証明書のシークレット化

GitLab RunnerがGitLab サーバーにアクセスできるようにするためにシークレットを登録します。

# scp <GitLabサーバーのユーザー名>@<GitLabサーバーのIPアドレス>:/data/work/gitlab.local.example.com.crt .
# oc create secret generic gitlab-runner-secret \
--namespace gitlab-runner-test \
--from-file=gitlab.local.example.com.crt

HelmによるGitLab Runnerのデプロイ

values.yaml 設定例

gitlabUrlにはGitLabのURLを設定します。runnerTokenにはGitLab上でGitLab Runnerを作成した際に、確認した認証トークンの値を入力します。imageにはGitLab Runnerのイメージを指定します。runnersにはGitLab RunnerのJob Podのベースイメージを指定します。certsSecretNameにはGitLabサーバーの証明書情報が保存されているシークレットを指定します。

gitlabUrl: https://gitlab.local.example.com/
runnerToken: "glrt-xxxxxxxxxxxxxxxxx"

rbac:
  create: true

serviceAccount:
  create: false
  name: gitlab-runner-sa

image:
  registry: "registry.gitlab.local.example.com"
  image: <ユーザー名>/<プロジェクト名>/gitlab-runner
  tag: <タグ名>

runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{ default .Release.Namespace .Values.runners.jobNamespace }}"
        image = "registry.gitlab.local.example.com/<ユーザー名>/<プロジェクト名>/alpine:latest"

certsSecretName: gitlab-runner-secret

インストール実行

GitLab RunnerをHelmインストールします。

# helm install gitlab-runner ./gitlab-runner-0.79.0.tgz -f values.yaml -n gitlab-runner-test

動作確認

Podの起動確認

# oc get pod -n gitlab-runner-test

# Running 状態で起動していることを確認
NAME                             READY   STATUS    RESTARTS   AGE
gitlab-runner-7658bb5fdc-rb95v   1/1     Running   1          13h

GitLab側でRunnerステータス確認

GitLab管理コンソールの [Runner管理画面] にて、登録したRunnerが「オンライン」表示になっていることを確認します。

これでGitLabとOpenShiftクラスター上の GitLab Runnerの連携が完了しました。
このRunnerを利用して、GitLab CI/CDパイプラインからジョブを実行できるようになります。

まとめ

本記事では、Linuxサーバー上に GitLabを構築し、閉域環境にあるKubernetes(OpenShift クラスター)と連携してCI/CD環境を実現する手順を紹介しました。
特に、以下のような環境において、今回の検証内容は実用的なモデルケースとなります。

  • インターネット接続が制限されたオンプレミス環境
  • セキュリティ要件上、外部クラウドサービスの利用が難しい開発現場
  • 閉域環境下で Kubernetesを活用しているものの、CI/CD基盤の整備や統合に課題を抱えている開発現場

本シリーズでは今後も今回構築した環境を基に閉域環境でのリポジトリ管理やCI/CDパイプラインとコンテナプラットフォームの連携について解説する予定です。
「閉域環境でのDevSecOps」を本格展開するための一歩として、本記事の構成をぜひ活用してみてください。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です