ウェブサイト検索

Docker化されたGitLab CIパイプラインでRsyncとSSHを使用する方法


rsyncは、帯域幅の消費を最小限に抑える効率的なアルゴリズムを使用する人気のファイル同期ユーティリティです。rsyncの一般的な役割の1つは、ウェブサイトのビルドをリモートの本番サーバーに展開することです。ここでは、rsyncの多様性とGitLab CIパイプラインによって提供される自動化を組み合わせる方法について説明します。

パイプライン実行者

GitLab CIは、いくつかの種類のパイプラインエグゼキュータをサポートしています。これらは、ジョブが実行される環境を定義します。

shell

executorはデフォルトで、ホストマシン上でベアメタル実行されます。これにより、パイプラインは追加の設定なしにホストで利用可能な任意のコマンドを使用できます。ほとんどの人気のあるLinuxディストリビューションにはrsyncがインストールされているため、このアプローチは理解しやすいです。

残念ながら、その

shell

executorは強い隔離を提供せず、時間の経過とともにホストの環境を汚染する可能性があります。より良い代替手段は、

docker

実行者は、各CIジョブのために新しいDockerコンテナを起動します。すべてのジョブはホストに影響を与えることができないクリーンな環境で実行されます。

ここでの欠点は、Dockerベースのイメージには一般的にrsyncが含まれていないことです。

ssh

. 公式のOSイメージでも、

ubuntu:latest

これらのコマンドなしで最小限のビルドとして出荷します。これにより、依存関係を追加し、rsyncでファイルを転送するための、少し複雑なパイプラインスクリプトが必要になります。

ここでは、rsyncをパイプラインに追加する方法を説明します。続行する前に、DockerベースのGitLab Runnerが使用可能であることを確認してください。また、使用する準備が整ったGitLabプロジェクトがあると仮定します。

準備中

リモートSSHホストに接続するためにrsyncを使用する場合は、SSHキーのペアが必要です。公開鍵と秘密鍵は、実行することで生成できます。

ssh-keygen -t rsa

接続するサーバーに公開鍵をコピーしてください。

次に、生成された秘密鍵をクリップボードにコピーします:

cat ~/.ssh/id_rsa | xclip -selection c

GitLabプロジェクトに移動し、左側のナビゲーションメニューの下部にある「設定」をクリックします。サブメニュー内の「CI/CD」項目をクリックします。その後のページで「変数」セクションまでスクロールします。

青い「変数を追加」ボタンをクリックします。「キー」フィールドに新しい変数の名前を付けます。私たちはSSH_PRIVATE_KEYを使用しています。プライベートキーを「値」フィールドに貼り付けてください。先頭の----BEGINと末尾の-----ENDの行を含めてください。

CI変数としてキーを追加すると、後でパイプライン内でそれを参照できるようになります。それは、あなたのパイプラインが作成するコンテナ内のSSHエージェントに追加されます。

パイプラインファイルの追加

GitLab CIは、リポジトリ内の.gitlab-ci.ymlファイルの内容に基づいてジョブを実行します。GitLabはこのファイルを自動的に見つけ、ブランチに変更をプッシュした際にそれが定義するパイプラインを実行します。

deploy:

stage: deploy

image: alpine:latest

script:

- rsync -atv --delete --progress ./ user@example.com:/var/www/html

この .gitlab-ci.yml には、作業ディレクトリの内容を example.com サーバーの /var/www/html に同期するために rsync を使用するジョブが含まれています。ビルド環境として alpine:latest Docker イメージを使用します。現在、rsync が Alpine イメージに含まれていないため、パイプラインは失敗します。

SSHとrsyncのインストール

Alpineは、依存関係が少なく、軽量なイメージなので、作業のための良いベースです。これにより、GitLabがジョブの開始時にイメージを取得する際のネットワーク使用量が減少し、パイプラインが迅速になります。rsyncを機能させるために、イメージにSSHとrsyncを追加し、その後SSHエージェントを起動し、以前に生成した秘密鍵を登録してください。

deploy:

stage: deploy

image: alpine:latest

before_script:

- apk update && apk add openssh-client rsync

- eval $(ssh-agent -s)

- echo "$SSH_PRIVATE_KEY" | ssh-add -

script:

- rsync -atv --delete --progress ./ user@example.com:/var/www/html

OpenSSHとrsyncはAlpineのapkパッケージマネージャーを使用してインストールされます。SSH認証エージェントが起動し、あなたの秘密鍵がssh-addを介して追加されます。GitLabは自動的に、あなたがプロジェクトの設定で定義した値を持つSSH_PRIVATE_KEY環境変数を挿入します。GitLabの変数画面で異なる鍵を使用した場合は、パイプラインを適切に調整してください。

ホスト検証の管理

SSHは、新しいリモートホストに接続する際に最初に確認を求める対話式のプロンプトを表示します。これはCI環境と互換性がなく、そこでこれらのプロンプトを見ることも、応答することもできません。

これに対処するための2つのオプションがあります:厳格なホストキーのチェックを無効にするか、あらかじめサーバーを「既知の」ホストとして登録することです。

最初のオプションでは、パイプラインのbefore_scriptに次の行を追加してください。

- echo "Host *ntStrictHostKeyChecking no" >> ~/.ssh/config

これが機能する一方で、潜在的なセキュリティリスクがあります。攻撃者があなたのサーバーのドメインやIPの制御を得た場合、事前の警告はありません。ホストキー確認を使用することで、リモートの身元があなたが期待するものであることを確認できます。

パイプラインの外部で、自分のマシンからリモートに接続することで、リモートを知られたホストとして非対話的に追加することができます。~/.ssh/known_hostsファイルを確認し、リモートのIPまたはホスト名が含まれている行を見つけます。この行をコピーし、前の手順に従って新しいGitLab CI変数を追加します。この変数にSSH_HOST_KEYという名前を付けてください。

さて、before_script セクションを次の行で更新してください:

- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts

これで、確認プロンプトを受けることなくサーバーに接続できるようになります。コードをGitLabリポジトリにプッシュし、パイプラインが完了するのを見守りましょう。

さらなる改善

このパイプラインは、Docker化された環境でSSHおよびrsyncを使用して開始する方法の簡単な例です。準備ステップを専用のビルドステージにラッピングし、パイプライン間で再利用できるDockerイメージを作成することで、システムをさらに改善する機会があります。

.gitlab-ci.yml は、変数のより多くの使用からも利益を得るでしょう。リモートサーバーのホスト名(example.com)、ディレクトリ(/var/www/html)、およびユーザー(user)をGitLab CIの変数に抽象化することで、ファイルをクリーンに保ち、カジュアルなリポジトリブラウザが環境の詳細を見るのを防ぎ、パイプラインファイルを編集せずに設定値を変更することができます。

要約

GitLab CIパイプラインでrsyncを使用するには、必要な依存関係を持つビルド環境を形成するための少し手動のセットアップが必要です。SSHプライベートキーを手動で注入し、リモートサーバーを既知のホストとして登録する必要があります。

一般的なベースイメージの上にSSHやrsyncを組み込んだコミュニティDockerイメージは利用可能ですが、最終的にはビルドに対するコントロールが少なくなります。あなたは必ずしも信頼できないイメージでパイプラインのサプライチェーンを拡張していることになります。OSのベースイメージから始めて、必要なものを追加することで、ビルドに対する自信を持つことができます。

関連記事: