Fedora ServerへのGitLab CEデプロイガイド:SELinuxとfirewalldを活用した社内ソースコード管理・CI/CDプラットフォームの自己構築

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

背景:GitHubが社内チームには不十分な場合

チームは5人のdeveloperと2人のsysadminで構成されている——小規模だが、GitHub Freeが徐々に問題になるには十分な規模だ。privateリポジトリのCI minutesは予想以上に早く消費される。一部の社内プロジェクトはコードをクラウドに置くことが許可されていない。そして、GitLab Runnerをセルフホストで試してみたところ、build timeが明らかに短縮された——GitHubサーバーへのアップロード帯域幅に依存しなくなったのだ。

Fedora Serverを選んだ理由は実のところかなり個人的なものだ——2年間Fedora desktopを使っていて、操作に慣れている。パッケージの更新がCentOSやRocky Linuxより速く、カーネルも新しく、SELinuxのポリシーも頻繁にパッチされる。GitLab CEはFedora上でちゃんと動く——ただし、ほとんどのガイドが推奨する「手っ取り早くSELinuxとfirewalldを無効化する」ということをしなければの話だが。

最低スペック:4GB RAM、2 CPU、20GB disk。ただしこれは文字通りの「最低」だ——GitLabはアイドル時でも約2.5〜3GB RAMを消費する。同じマシンにGitLab Runnerも追加で動かすつもりなら、安全のために8GBを用意しておくべきだ。

GitLab CEのインストール

システムの準備

まずシステムを更新し、必要な依存パッケージをインストールする:

sudo dnf update -y
sudo dnf install -y curl policycoreutils openssh-server openssh-clients postfix
sudo systemctl enable --now sshd postfix

公式リポジトリからGitLab CEをインストール

GitLabはリポジトリを自動設定するスクリプトを提供しており、その後はDNFで通常通りパッケージをインストールできる:

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.yourdomain.com" dnf install -y gitlab-ce

gitlab.yourdomain.comを実際のドメインまたはIPに置き換える。静的IPで社内運用する場合はhttp://192.168.1.100でも問題ない。インストール完了後、GitLabは自動的に初回のgitlab-ctl reconfigureを実行する——このプロセスには約3〜5分かかるが、完全に正常な動作だ。

詳細設定

SELinuxの設定——無効化しないこと

これは自分が読んだほとんどのガイドと最も異なる点だ。多くの記事では手っ取り早くsetenforce 0を実行するか、/etc/selinux/configSELINUX=disabledを設定するよう勧めている。自分はそうしない——productionサーバーでSELinuxを無効化するのは、数分のセットアップ時間を節約するために重要な保護レイヤーを捨てることになる。GitLab CEが実際に必要なのは、いくつかのbooleanを有効化するだけで十分だ:

# GitLabのネットワーク接続を許可(webhook、メール送信に必要)
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_relay on

# GitLabデータディレクトリのファイルコンテキストを修正
sudo semanage fcontext -a -t gitlab_shell_t "/var/opt/gitlab(/.*)?" 
sudo restorecon -Rv /var/opt/gitlab/

# SELinuxがブロックしているものを確認
sudo ausearch -m avc -ts recent | grep gitlab

booleanを有効化してもSELinuxエラーが残る場合は、audit logを読んでカスタムポリシーを作成する:

sudo ausearch -m avc -ts recent | audit2allow -M gitlab-custom
sudo semodule -i gitlab-custom.pp

この方法はSELinuxを無効化するよりもはるかに安全だ——GitLabが必要とするoperationだけを正確に許可する。さらに、audit logを読むことでGitLabが実際に内部で何をしているかが理解でき、後でtroubleshootが必要になったときに役立つ。

firewalldの設定

GitLabにはHTTP(80)とHTTPS(443)が必要だ。SSH cloneはシステムSSHとport 22を共有しているため、追加で開放する必要はない:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# 確認
sudo firewall-cmd --list-all

GitLabがカスタムポート(例:8080)で動作している場合は、対応するルールを追加する:

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

gitlab.rbのチューニング

メインの設定ファイルは/etc/gitlab/gitlab.rbだ。productionでは以下の設定を使用している:

# /etc/gitlab/gitlab.rb

# メインURL——正確に設定すること。SSLがある場合はHTTPSを使用
external_url 'https://gitlab.yourdomain.com'

# SMTP設定(Gmailの例)
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "app-password-here"
gitlab_rails['smtp_domain'] = "gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true

# Puma webサーバーのRAM制限
puma['worker_processes'] = 2
puma['min_threads'] = 1
puma['max_threads'] = 4

# RAMを節約するためSidekiq workersを削減
sidekiq['concurrency'] = 10

# バックアップを7日間保持
gitlab_rails['backup_keep_time'] = 604800

変更を適用する:

sudo gitlab-ctl reconfigure

Let’s EncryptでHTTPSを有効化

GitLab CEにはLet’s Encryptが組み込まれている。gitlab.rbに以下を追加する:

letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['[email protected]']
letsencrypt['auto_renew'] = true
letsencrypt['auto_renew_hour'] = 3
letsencrypt['auto_renew_day_of_month'] = "*/7"
sudo gitlab-ctl reconfigure
sudo gitlab-ctl renew-le-certs

確認とモニタリング

初回ログイン

一時的なrootパスワードを取得する(24時間有効):

sudo cat /etc/gitlab/initial_root_password

rootアカウントとそのパスワードでhttp://your-gitlab-urlにログインし、すぐに変更する。翌日まで放置しないこと。

サービスの状態確認

sudo gitlab-ctl status

正常なoutputは以下のようになる——すべてのサービスがrun状態である:

run: alertmanager: (pid 1234) 120s
run: gitaly: (pid 1236) 120s
run: nginx: (pid 1240) 120s
run: postgresql: (pid 1242) 120s
run: redis: (pid 1244) 120s
run: sidekiq: (pid 1246) 120s
run: puma: (pid 1248) 120s

サービスがdownしている場合は個別に再起動する:

sudo gitlab-ctl restart puma
sudo gitlab-ctl restart sidekiq

ヘルスチェックとデータベース確認

# 包括的なヘルスチェックを実行
sudo gitlab-rake gitlab:check

# メール送信テスト(Rails consoleで実行)
sudo gitlab-rails console
# consoleで入力:
Notify.test_email('[email protected]', 'GitLab Test', 'Test email').deliver_now

PrometheusとGrafanaによるモニタリング

GitLabにはPrometheusとGrafanaが組み込まれている。gitlab.rbでGrafanaを有効化する:

grafana['enable'] = true
grafana['http_port'] = 3000
sudo gitlab-ctl reconfigure
# アクセス先: http://your-gitlab-url/-/grafana

GrafanaダッシュボードはPuma、Sidekiq、Gitaly、PostgreSQLなど各サービスのCPU/RAMとrequest rate、latencyを表示する。大きなdeploymentがあるときにこのタブを開いてボトルネックをすぐに確認する——デバッグ時間をかなり節約できる。

自動バックアップ

# 手動バックアップを作成
sudo gitlab-backup create

# 作成済みバックアップを確認
ls -lh /var/opt/gitlab/backups/

rootのcrontabに追加して毎日午前2時に自動バックアップを実行する:

sudo crontab -e
# 以下の行を追加:
0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1

6ヶ月のproduction運用でよく遭遇したエラー

  • 502 Bad Gateway: Pumaが起動完了していないことが多い。1〜2分待つか、sudo gitlab-ctl restart pumaを実行する。
  • SELinuxによるgit operationsのブロック: sudo ausearch -m avc | grep gitを実行し、上記の手順でポリシーを作成する。
  • ディスクの急速な枯渇: GitLab CI artifactsとcontainer registryはディスクを非常に速く消費する。各プロジェクトのCI settingsでartifacts_expire_inを設定し、sudo gitlab-ctl registry-garbage-collectでregistryを定期的に整理する。
  • 異常なRAM使用量の増加: Sidekiqは数日間の稼働後にmemory leakを起こすことがある——sidekiq['enable_sidekiq_cluster'] = falseを追加するか、cronで定期的に再起動する。

ディスクがほぼいっぱいになったときのシンプルなアラートを追加する:

# crontabに追加
*/30 * * * * df -h /var/opt/gitlab | awk 'NR==2 {gsub(/%/,"",$5); if ($5+0 > 80) print "GitLab disk usage: " $5 "%"}' | grep -q "%" && echo "Disk alert" | mail -s "GitLab Disk High" [email protected]

6ヶ月のproduction運用を経て、FedoraのGitLab CEは当初の予想よりも安定していた。SELinuxは最初の1週間が最も手間がかかった——新たなoperationのたびに新しいポリシーが必要になる。しかし一度設定が完了すれば、1ヶ月間手を触れる必要がない。最も価値があるのはやはりGitLab Runnerによる社内CI/CDだ:build timeが明らかに短縮され、minutesの消費を心配せず、外部へのアップロード帯域幅にも依存しない。

Share: