2020年5月16日土曜日

Gitlab で Gitaly だけを外部のサーバに移行する方法

概要

Gitaly は gitlab 内で動作しているプロセスで git リポジトリに gRPC プロトコルでアクセスできるようになる gitlab のコンポーネントです
Omnibus Install された gitlab の場合は基本的には gitlab-rails のアプリケーションと同じ VM 内で動作しています
しかし git リポジトリが大きくなりスケールさせる必要がある場合には別 VM に移行することができます
今回は Gitaly だけを外部の VM に移行する方法を紹介します

Gitaly のインストール (Omnibus GitLab のインストールを使う)

まずは普通に Omnibus Install で Gitlab をインストールします
注意するのはインストールの際に指定する EXTERNAL_URL を指定しないことです

  • sudo apt -y update
  • sudo apt install -y curl openssh-server ca-certificates
  • curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
  • sudo apt -y install gitlab-ee

gitlab.rb を編集して gitaly だけを起動するようにする

Omnibus Install で起動するプロセスを gitaly だけにします

  • sudo su -
  • mv /etc/gitlab/gitlab.rb{,.back}

まずは各プロセスを起動しないように設定します
また Gitaly をリモートからでもアクセスできるように LISTEN させます

  • touch /etc/gitlab/gitlab.rb
  • vim /etc/gitlab/gitlab.rb
postgresql['enable'] = false
redis['enable'] = false
nginx['enable'] = false
unicorn['enable'] = false
sidekiq['enable'] = false
gitlab_workhorse['enable'] = false
grafana['enable'] = false
alertmanager['enable'] = false
prometheus['enable'] = false
gitlab_rails['rake_cache_clear'] = false
gitlab_rails['auto_migrate'] = false
gitlab_rails['internal_api_url'] = 'http://gitlab.example.com'
gitaly['auth_token'] = 'abc123secret'
gitaly['listen_addr'] = "0.0.0.0:8075"

internal_api_url は http を指定しましょう
また auth_token は好きな文字列で OK です
次に gitaly が管理する git リポジトリを指定します

  • vim /etc/gitlab/gitlab.rb
git_data_dirs({
  'default' => {
    'path' => '/var/opt/gitlab/git-data'
  },
  'storage1' => {
    'path' => '/mnt/gitlab/git-data'
  },
})
  • mkdir -p /mnt/gitlab/git-data

あとは reconfigure を実行します

  • gitlab-ctl reconfigure

プロセスを確認すると gitaly とその他メトリックを取得するためのプロセスのみが動作しているのが確認できると思います

  • gitlab-ctl status
run: gitaly: (pid 3010) 501s; run: log: (pid 2812) 520s
run: gitlab-exporter: (pid 2996) 502s; run: log: (pid 2995) 502s
run: logrotate: (pid 2902) 515s; run: log: (pid 2926) 514s
run: node-exporter: (pid 2985) 502s; run: log: (pid 2942) 508s

/etc/hosts に gitlab の FQDN を解決できるように登録しておく

  • sudo vim /etc/hosts
192.168.100.10  gitlab.example.com

gitlab 本体で外部の gitaly を参照するようにする

あとは gitlab 本体で構築した外部の gitaly を参照させます
この作業は gitaly サーバではなく gitlab 本体のサーバで行います

  • sudo vim /etc/gitlab/gitlab.rb
git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://192.168.100.13:8075' },                                                              
  'storage1' => { 'gitaly_address' => 'tcp://192.168.100.13:8075' },                                                             
})

gitlab_rails['gitaly_token'] = 'abc123secret'

これで reconfigure -> start しましょう

  • sudo gitlab-ctl reconfigure
  • sudo gitlab-ctl start

/etc/gitlab/gitlab-secrets.json を gitlab 本体からコピーする

gitaly サーバに gitlab 本体側からコピーしてきます
コピペでも何でも OK です
これがないと push 時にエラーになります

  • sudo su -
  • mv /etc/gitlab/gitlab-secrets.json{,.back}
  • scp gitlab.example.com:/etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json

コピー後は gitaly 側で reconfigure が必要になるので実行します

  • gitlab-ctl reconfigure

動作確認

あとは実際にプロジェクトを作成して外部の gitaly 側にデータが格納されているか確認します

適当にプロジェクトを作成し git clone してみましょう
そして add -> commit -> push して gitaly 側の git_data_dirs を確認してみましょう

  • ls /var/opt/gitlab/git-data/repositories/ /mnt/gitlab/git-data/repositories/
/mnt/gitlab/git-data/repositories/:
+gitaly

/var/opt/gitlab/git-data/repositories/:
+gitaly  @hashed

こんな感じで default 側に @hashed というディレクトリができていれば OK です

トラブルシューティング

gitlab 本体でエラーを確認する場合は/var/log/gitlab/gitlab-rails あたりを確認しましょう

gitaly 側で確認するログは /var/log/gitlab/gitaly/current になります

マイグレーションできるのか

ちなみに自分が試したときはすでにプロジェクトがある状態でした

  • 1 つ以上の git push をしているプロジェクト
  • まだ 1 つも git push していないプロジェクト

これらのプロジェクトがある状態で外部の gitaly を参照するようにした場合は前者はプロジェクトにアクセスすると 404 になり後者はアクセスしてもエラーにはなりませんでした
理由としては簡単で push 済みの前者のプロジェクトは外部の gitaly にリポジトリのデータがないので 404 エラーになっているかなと思います
また後者は push していないのでまだ git リポジトリが作れていないのでエラーになりません
ただ clone しようとした場合両者とも fatal: the remote end hung up unexpectedly になりました

これを踏まえて両者のプロジェクトが外部の gitaly に移行してもエラーにならないようにする必要があるかなと思います
おそらく単純なファイルなのでそれを移動すれば直るはずですが試していないので何とも言えません
一番手っ取り早く解消するのは gitlab 本体側の git_data_dirs に外部以外のローカルのパスも書いておくことだと思います

gitlab 本体側

git_data_dirs({
  'default' => { 'path' => '/var/opt/gitlab/git-data' },
  'storage1' => { 'gitaly_address' => 'tcp://192.168.100.13:8075' },
  'storage2' => { 'gitaly_address' => 'tcp://192.168.100.13:8075' },
})

gitaly 側

git_data_dirs({
  'storage1' => {
    'path' => '/var/opt/gitlab/git-data'
  },
  'storage2' => {
    'path' => '/mnt/gitlab/git-data'
  },
})

これだと WebUI も git clone もエラーにならず既存のプロジェクトも動作します
が gitlab 本体側に相変わらず git のデータが配置されてしまうので微妙な感じになってしまいます

default と storage1, storage2 がどう使われるか不明

おそらく gitaly が良い感じに振り分けてくれるのだと思います
ただ続けてプロジェクトを作った場合に全部 default 側に作成されました
ストレージの容量などを見て分散してくれる感じなのでしょうか
どこかドキュメントを探すかコードをみればわかるかなと思います

最後に

Gitlab を構成するコンポーネントの 1 つである Gitaly を外部の VM に移行する方法を紹介しました
これで単純に git リポジトリの分散はできるようになります
Gitaly がダウンすると WebUI も git リポジトリのアクセスもできなくなります
そのため Praefect という HA 機構もありこれを使うことで更に堅牢な Gitlab を構築することができます

参考サイト

0 件のコメント:

コメントを投稿