パイプラインの敷設: 継続的インテグレーションとデリバリー

コンパイルされた実行可能ファイルでシステムが作成されていたとき、ソフトウェアのビルド プロセスの多くは、専任のビルド エンジニアに任されていました。
1990 年代、私が勤務していたCisco Systemsでは、専任のエンジニアリングチームが、ビルドツールと顧客に提供する最終的なディストリビューションの作成に専念していました。
私たちエンジニアの大半はビルド プロセスとほぼ関わりがなく、ビルドの後、必要なイメージをテスト用のマシンにダウンロードしていたものです。

今日では、チームの誰もがテスト用のイメージを作成できるツールによって、このプロセスはかなりオープンになっています。さらに重要なことに、Jenkins のような継続的インテグレーション ツールの開発によって、アプリケーションに小さな変更を加え、それらの変更でビルドを開始し、ビルドをテストして、最小限の操作でサーバーにプッシュすることが可能になりました。

継続的インテグレーションと継続的デリバリー (CI/CD) は神秘的な考えに見えるかもしれませんが、実際には非常に単純です。CI/CD プラクティスの中心にあるのは、「パイプライン」という概念です。

CI/CD パイプラインとは何か?

CI/CD の方法論は、「ソフトウェアをビルドするプロセスの各ステップは、前のステップが終了した後に実行される」という考えに基づいています。
ソフトウェアを迅速にデプロイしたり、小さな変更をテストに適用したり、顧客に提供できるようにするために、自動化して順番に実行するようにスケジューリングできるさまざまなステップがあります。
本質的に、CI/CDツールは、コードを希望の時間に実行するスケジューリングツールです。

このフレームワークで、ソフトウェア デリバリー パイプラインが可能になるのです。
JenkinsのCIツールを例に挙げると、初期の反復では、一連のステップを実行するための「フリースタイルジョブ」と呼ばれる様々なジョブを作成できます。複数のフリースタイルジョブを連結することで、「コード変更をブランチにコミットし、そのコミットやプッシュから、ソフトウェアの構成、テスト、ビルド、ターゲットマシンへのデプロイのプロセスを開始できるソフトウェア デリバリー パイプライン」を作成できます。

パイプラインを構築するには何が必要か?

まず最初に認識すべきことは、ほとんどのパイプラインには標準的なプロセスがありますが、あらゆる環境で上手くいくような手法は存在しないということです。パイプラインモデルの利点は、組織にとって最も重要なステージを適用し、その組織にとって最も効果的なものにすることができるということです。

私の環境で上手くいくことが他の環境では現実的ではないケースもあるかもしれませんが、私の環境でのパイプラインの例は次のようになります。

最初のステップはマージ リクエスト ビルダーです。
これは、開発がおこわれたブランチがあり、そのブランチに変更をプッシュすると、元のトランクと比較するフックがトリガーされるプロセスです。
システムは変更が加えられたことを認識し、それがビルドプロセスのトリガーとなります。

2番目のステップは、Dockerを使って並列テストを同時に実行できるようにしていることに基づいています。そのためには、一連のステップを実行して Dockerマスターサーバーを起動し、このマスターサーバーがDockerスレーブを作成します。スレーブを設定することで、個別の Docker コンテナーを複製して実行できるスペースを作成します。

3番目のステップは「Docker ビルド」フェーズと呼ばれるもので、マスターDockerイメージを起動し、開発をおこなっているブランチを使用してテスト環境を作成し、一連のテストを実行するために必要なすべての情報とテストデータをアプリケーションにセットアップします。

4番目のステップでは、シーケンスにタグ付けされたすべてのテストを取得し、設定したDocker スレーブの数に基づいて分割します。これにより、Dockerイメージのコピーを作成し、それぞれのコピーに一意の ID を与えて、必要なテストを実行できるようにします。この処理により、数百個のDockerコンテナーが作成され、テストが実行されます。このプロセスを通じて、Jenkinsはテストを監視して失敗を探します。失敗が見つからなければ (つまりすべてのテストが成功したら)、次のステップに進みます。

5番目のステップは、ターゲットマシンにソフトウェアを効果的にインストールするために必要な、実際のブランチイメージとその結果の成果物を作成することです。

6番目のステップは、最終的なターゲットマシンを起動することです。この場合の最終的なターゲットマシンとは、Dockerコンテナー内ではない専用のシステムのことです。システムに応じて、ターゲットマシンがどのようにセットアップされているか、どのフラグが設定されているかに基づいて、新規インストールやアップグレードを実行できます。

7番目および最後のステップはクリーンアップフェーズです。すべてのシステムがオフになっていることを確認し、ビルドやテスト システムを不要に実行していないことを確認します。クラウドベースのソリューションを使用しているため、これは重要なことであり、これらのマシンを稼働させたままにしておくことは、事実上、無駄にお金を使うことになります。すべてがクリーンアップされていることを確認することは、プロセスにとって非常に重要です。

私たちの環境では、現在、これらはすべてJenkinsで構成された個々のプロジェクトであり、正常に完了すると次のプロジェクトに渡されます。これは「シーケンシャルパイプライン」と表現するのが最適であり、上流プロジェクトおよび作業順序にしたがってプロセスが構成されます。

※最新のJenkinsの実装では、パイプラインの概念が簡略化されており、Jenkinsfileを使えば、上記で説明した個々のステップを Jenkinsfile に入れて、一つのプロセスとして実行できるようになっています。

パイプラインのケアと供給

CI/CD の目的、そしてそもそもデリバリー パイプラインを作成することは、ボトルネックや忙しいだけの作業を排除し、機能の作成/テストおよび顧客への提供など、最も重要なタスクに重点を置くことができるようにすることです。

これらのステップをスケジュールおよび順序付けすることで、機能を繰り返し追加し、プロセスを確実に再現することができます。さらに言えば、各新機能はシステムの他の部分と組み合わせてチェックできるため、欠陥が発生していないこと、もっと言えば、変更したことでコードの他の部分に不具合が発生しないことを確認できます。

これは、一度に複数の変更を加えてシステムをコンパイルしようとする場合と比べて大きな利点です。それでも、パイプラインを維持し、必要に応じて拡張しなければなりません。
新しい機能には新しいテストが必要です。新しいテストでは、テストを効果的に実行できるように容量を計画する必要があります。スクリプトを保守して、必要なときにリソースが利用可能で稼働していることを確認する必要があります。新しいテストは、チェックインし、CI/CD ツールと連携して実行し、効果的に動作していることを確認する必要があります。これにはすべて時間がかかり、すべての部分を保守する必要があります。

CI/CD パイプラインは、Jenkins の例でのプラグインのような様々な外部ツールに依存することになり、外部ツールを随時評価し、既存のシステムで更新してテストする必要があります。しかし、CI/CD パイプラインには、一度ステップを作成してしまえば、様々な人がステップを保守することができ、開発者だけに任せなくてもよいという側面もあります。

ソフトウェア デリバリ パイプラインの作成と運用のプロセスは、最初は複雑に見えるかもしれませんが、他のパイプラインと同様に、ステップ単位、セクション単位で作成されます。
それぞれの組織に、それぞれの要件や最適な構成方法があります。
パイプラインは必要に応じて短くても長くても構わないので、すでに実行しているステップを特定し、どのように開始できるかをまず確認しましょう。また、パイプラインは最初のセクションから始まるため、迷った場合は最初のセクションに戻りましょう。

作者について:

Michael Larsen(マイケル・ラーセン)は、20 年以上のキャリアの中で、「Army of One」または「The Lone Tester」の役割を担ってきました。仮想マシン ソフトウェア、静電容量式タッチデバイス、ビデオゲーム開発、分散型データベース、Web アプリケーションなど、幅広い技術と業界で働いてきました。現在はカリフォルニア州パロアルトの Socialtext に在籍しています。

(この記事は、開発元 Ranorex 社 Blog 「We are Laying a Pipeline: Understanding Continuous Integration and Delivery」2019年4月10日の翻訳記事です。)