CI/CDとは?
2022.08.12 Kong翻訳記事

今日の産業界の進むペースは、ソフトウェア開発者にとって、ソフトウェアの開発、テスト、リリースを実行してきたこれまで以上に頻度をあげるようプレッシャーをかけています。このペースに対応できるように、チームではワークフローに次の 2つのコアプロセスを組み込みました。継続的インテグレーション(CI, Continuous Integration)継続的デプロイメント(CD, Continuous Deployment) です。

継続的インテグレーションと継続的デプロイメント (CI/CD) は、アプリケーションのコード管理とその安全で予測可能な出荷を自動化する DevOps ワークフローのサブセットです。この記事では、CI/CD について深く掘り下げてみます。ソフトウェア開発のライフ サイクルの一部として、継続的インテグレーションと継続的デプロイメントの個々の役割について見ていき、さまざまなコンポーネントとステージを検証します。

目次

継続的インテグレーション (CI) とは?

継続的インテグレーション (Continuous Integration:CI) とは、ソフトウェア開発者が新しいコードを既存のコードに統合する自動化プロセスです。このプロセスでは、コードの変更点をアプリケーションのリポジトリにマージし、ビルドとテストを実行して、更新されたアプリケーションの正確性と機能を確認します。

なぜ CI なのか?

モダン アプリケーション開発に CI が必要となる理由はいくつかあります。

バグの少なさ

CI 以前は、新しいコードのマージとテストのプロセスがさらに煩雑であったため、エンジニアリング チームはこのプロセスをそれほど頻繁には実行していませんでした。チームがコードをマージする頻度が減ると、マージが必要なコードを変更する機会が増加し、一般的には、統合が必要な大規模なコードになります。そして、このように大規模なコードになってしまうと、必然と未検出のバグが生まれ、最終的にはこれらのバグが本番環境に入り込んでしまっていました。
CI ではコードの統合作業が簡素化されるため、ソフトウェア開発者はコードをより頻繁に (より小さなチャンクで) プッシュしてテストできるため、バグが発生するリスクが低減されます。

コード統合の迅速化

CI があることで、ソフトウェア開発者はプル リクエストをより効率的に作成し、マージできます。ソフトウェア開発チームが複数のブランチで異なる機能を開発する場合、CI プロセスはソース管理ツールと連携し、コードの競合を解決できます。

テストの自動化

ソフトウェア開発者が CI を使用すると、自動テスト計画と関連するスクリプトが簡単に作成できるようになります。これで、ソフトウェアのテスト担当者の時間は大幅に節約できます。このようなテストは、テストが成熟するにつれて、CI プロセスで更新され、強化されていきます。

互換性のあるライブラリ

CI プロセスの実行頻度が高くなると、アプリケーションのソースコードは、正常に統合されているか、バグがないかなどのテストが常に行われることになります。このように頻繁に統合することで、自ら頻繁に更新を行っているサードパーティとの依存関係において、脆弱性と継続的な互換性がチェックできるようになります。

CI プロセス

一般にCI プロセスはいくつかの手順があります。

新しいコード変更のプル リクエストの作成

ソフトウェア開発者がコードを書き、その更新内容をローカル ブランチからセントラル リポジトリの開発ブランチにプッシュします。次に、ソフトウェア開発者はプル リクエストを作成し、開発ブランチをメイン ブランチにマージする意図をチームに通知します

コードのレビュー

通常、このプロセスの次のステップは、開発チームの上級メンバーが開発ブランチのコード変更を確認 (レビュー) することです。そして、そのチーム メンバーがプル リクエストを承認または却下します。プル リクエストを却下する場合、通常、レビュー担当者は理由を明記します。

ビルド

プル リクエストが承認されると、新しいコードが含まれたアプリケーションをビルドするための自動プロセスが開始されます。このビルド プロセスの結果は、ある種のビルド アーチファクトです。このアーチファクトは、更新されたアプリケーションを含む zip ファイル、コンパイルされたバイナリ、またはその他の形式になります。

テスト

次に、一連の自動テストを実行し、新しくビルドしたアプリケーションが正しく動作するか検証します。

マージ

ビルドが成功し、すべてのテストがパスした場合、開発ブランチ コードをメイン ブランチにマージします。

継続的デプロイメント (CD) とは?

継続的デプロイメントと継続的デリバリーは、いずれも略称が CD です。ただし、この記事で CD を使用する場合は、継続的デプロイメント (Continuous Deployment:CD) を指します。継続的デプロイメントについて説明した後、継続的デリバリーとの違いを明確にしていきます。
CDは、CI プロセスが終了するとすぐに始動する自動化されたソフトウェア リリース プロセスです。CI プロセスの正常なアウトプット (つまり、テストし検証を終えたアプリケーションとコード変更がマージされたもの) は、継続的デプロイメントのインプット (利用するデータ) となります。

なぜ CD なのか?

CD を使用すると、ソフトウェア開発チームは、コード変更のビルド、テスト、およびデプロイを、自信を持って行うことができます。自動化を用いた CI プロセスが大部分であれば、開発者は新しいアプリケーションのバグや脆弱性が徹底的にテストされていると確信できます。CD プロセスも同様に自動化を用いることで、更新されたアプリケーションが本番環境に適切にデプロイされ、ユーザーが使用可能な状態にできます。

CD のコード化と自動化により、設定手順が忘れられたり、環境設定が誤って入力されたりすることを防げます。その結果、アプリケーションがシームレスにデプロイできるという高い信頼性が得られ、デプロイメントの実施を特定のチーム メンバーに依存しなくてもよくなります。
また、企業は競争力を維持するには、常に革新的でなければならないため、CD を使用すると、手動でのソフトウェア テストや設定に費やす時間を大幅に削減できます。このような時間の削減により、反復的な開発が可能となり、市場投入までの時間の短縮が可能になります。

CD プロセス

通常、CD プロセスは5つの重要な手順で構成されています。

ステップ1:ステージング環境へのデプロイメント

CD パイプラインは、CI パイプラインの正常な実施によって生成されたビルド アーチファクトを取得し、そのアーチファクトを仮稼働 (「ステージング」とも呼ばれる) 環境にデプロイします。

ステップ2:ステージング環境でのテスト

このフェーズでは、CD パイプラインは、ステージング環境で一連の自動テストを実行し、アプリケーションが期待どおりに動作しているかどうか検証します。また、この段階ではセキュリティの脆弱性やコンプライアンスのチェックも行うことがあります。

ステップ3:本番環境へのデプロイメント

ステージング環境でのテストがすべて正常に終了すると、CD パイプラインでアプリケーションを本番環境にデプロイします。このデプロイメントの手順には、ほとんどの場合次のような作業が含まれます

  • リソースのプロビジョニング
  • 更新されたアプリケーションのインストール
  • アプリケーションの依存関係のインストール
  • アプリケーション環境の設定

CD が登場する以前は、これらのタスクは手動で実行されており、時間がかかる上に、エラーが発生しやすくなっていました。

ステップ4:本番環境のテスト

このステップでは、CD パイプラインで本番環境にあるアプリケーションをテストします。更新されたアプリケーションは CI パイプラインでテストされ、またステージング環境でもテストされるため、DevOps チームによっては、この本番環境のテスト手順を任意と考えることもあります。ただし、ここは、インフラストラクチャまたは構成設定の違いにより、ステージング環境には存在しなかったかもしれないエラーを検出するために極めて重要なステップとなります。

ステップ5:監視とフィードバック

この最後のステップでは、アプリケーションのヘルス状態と安定性を常に監視し、ユーザーからのフィードバックを収集します。ここでのフィードバックは、次の反復開発サイクルの基盤となります。DevOps チームによっては、これらの「運用段階」の関連作業を、CD パイプラインとは切り離した独自のプロセスとして捉えていることもあります。

継続的デリバリーと継続的デプロイメント

ここまでの説明では、ビルド アーチファクトを生む継続的インテグレーションのプロセスと、そのアーチファクトを本番環境にデプロイする継続的デプロイメントのプロセスを見てきました。
継続的デリバリーでは、CI からビルド アーチファクトを取得し、ステージング環境にデプロイしてテストを実施し、本番環境にアプリケーションをデプロイする前にマニュアル承認を待ちます。なぜマニュアル承認が必要なのでしょうか? 一般的には、アプリケーションを本番環境にデプロイする前に、品質保証 (QA) 担当エンジニアなどによるマニュアルでのテスト実施時間とスペースを確保します。
2 つの違いについて、Martin Fowler は、次のようにツイートしています。

Martin Fowlerのツイート
継続的デリバリーとは、すべての変更を本番環境にデプロイできるようにすることです。継続的デプロイメントとは、すべての変更をデプロイすることです。

Martin Fowler 「継続的デリバリーとは、すべての変更を本番環境にデプロイできるようにすることです。継続的デプロイメントとは、すべての変更をデプロイすることです。」

継続的デリバリーと継続的デプロイメントの違いは、継続的デリバリーでは、デプロイメントに対してマニュアルでのテストと明示的な承認が必要であるのに対し、継続的デプロイメントではプロセス全体が自動化される点です。

ソフトウェア開発における CI/CD の役割

CI/CD で、モノリシックな アプリケーション開発やビッグバン デプロイメントで発生していた問題点の多くが解決されました。

コード管理の改善

CI/CD を使用すると、異なるチームが Git ブランチを使用して、同じコードベースで同時に作業できます。コード リポジトリと CI ツールは、それぞれのチームの変更を管理するため、進行中のタスクの有無とステータスを開発担当者が簡単に確認できます。
たとえば、テックリードとレビュー担当者は、Git リポジトリを参照して、現在のブランチを見て、コードが最後にブランチにプッシュされた時刻を確認できます。また、そのブランチのコードとメイン ブランチのものを比較できます。同様に、CI パイプラインの過去の実行内容を見て、発生したエラーを確認することもできます。

コード競合なし

ビッグバン デプロイメント (何もないところから一度に大量にすべてのものをデプロイすること) では、ソフトウェア開発者はコードをチェックインする際に、互いの作業を上書きしてしまう可能性があります。CI/CD パイプラインでは、段階的なデプロイメントを実施することでこのリスクを軽減しており、これは、サイロ化された開発を最小限に抑え、コードの競合を排除する方法となっています。

自動化

CI パイプラインの自動化ツールは、チェックイン コードが指定されたコーディング ガイドラインに準拠しているかどうか検証するため、コードの質全体の標準が向上します。CI と CD のいずれもが、さまざまな環境での機能テストと統合テストをほぼ自動化します。これで、チームはより多くのテストを作成し、その他詳細なチェック項目を作成することができます。ビルド、テスト、リリースを自動化することで、CI/CD では手動でのコード処理に伴うリスクを回避できます。

生産性の向上

CI/CD プロセスは、反復的な開発とコードの迅速な配布を優先するアジャイル開発手法に沿っています。CI/CD を使用すると、複数のチームが既存の機能の改善、新機能、バグ修正を並行して作業できます。これで、チーム全体のスループットと生産性を向上させることができます。

ソフトウェアの自動バージョン管理

厳密な規則がない複数のチーム構成においては、コード タグが大きな混乱を招く可能性があります。たとえば、チーム A はあるソフトウェアの機能を開発し、それを出荷して、それに v3 とタグ付けし、すぐにアプリケーション全体をv4 を開発する作業を開始したとします。同時に、チーム B は自分たちのソフトウェア機能を出荷します。コードベースを確認した後、彼らはこの新しいバージョンを v4 とタグ付けしたとします。ここでチーム A が新たに開発した機能を v4 として出荷すると、この競合により、デプロイされたコード バージョンで混乱が生じます。

CI/CD ツールには、デプロイメント バージョンの命名時に競合を回避する特別な方法が備わっています。CI/CD を使用すると、ソフトウェアのデプロイメントにバージョン番号を手動でタグ付けする必要はありません。

容易なロールバック

ほとんどの CI/CD パイプラインは、コードの統合やデプロイメント中に障害が発生した場合、グレースフル ロールバックができるよう設計されており、ソース コード リポジトリ (CIの場合) 、またはターゲット環境 (CDの場合) は元の状態に戻ります。

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

ここまでは、「CI/CD プロセス」と「CI/CD パイプライン」という用語を同義語として使用してきました。技術的には、CI/CD パイプラインは、ソフトウェアのソース コードの統合とアプリケーションのデプロイメントを自動化するソフトウェアベースのワークフローです。CI/CD パイプラインは、これまでに説明してきた CI プロセスや CD プロセスによく似ているため、多くの従事者は「プロセス」と「パイプライン」を同じ意味で使用しています。

CI/CD パイプラインは、さまざまなポイントでトリガーできます。たとえば、あるチームは、プル リクエストが承認され、コードがメイン ブランチにマージされた直後にパイプラインが開始されるように構成できます。また別のチームは、プル リクエストがオープンされた直後に開発ブランチのパイプラインをトリガーすることもできます。

CI/CD パイプラインのコンポーネント

CI/CD パイプラインは通常、YAML で記述され、各アクションには明示的なコマンドが含まれています。ただし、一部のツールでは、開発者が設定フォームのフィールドに入力できるGUI を用いて、パイプラインを簡単に作成できるようになっているものもあります。その裏では、CI/CD ツールは一般に、YAMLでパイプラインのコードを生成しています。

CI/CD パイプラインは、ジョブ、ステージ、タスクで構成されます。

  • ステージは、複数のジョブやタスクで構成されるパイプラインの主要部分です。
  • ジョブは、パイプラインで実行されるアクションです。これは、単独で定義することも、ステージの子要素として定義することもできます。
  • タスクとは、抽象化され再利用可能なパッケージ化されたスクリプトで、通常は開発者による一連のインプットが記述されています。たとえば、マシンが配置されているサブネットに応じて、マシンにスクリプトをインストールするタスクが挙げられます。

次の図は、パイプライン アーキテクチャの例です。

このワークフローを、別々のコンポーネントに分解した YAML ファイルの例が次のとおりです。

stages:
- stage: First Stage
  jobs:
  - job: echo "Hello world"
  - job: echo "Hello CI/CD"

- stage: Last Stage
  jobs:
  - job: echo "Hello last stage"
  - job: echo "Goodbye CI/CD"

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.7'
    architecture: 'x64'

この CI/CD パイプラインには、2 つのステージ、4 つのジョブ、および 1 つのタスクがあります。ここでキーワードの stages は、ファイルに多くのステージが含まれることを示しています。上記のコード スニペットは、次の 2 つのステージを示しています。「First Stage」と「Last Stage」です。First Stage は 2 つのジョブからなっており、「Hello world」と「Hello CI/CD」というメッセージをユーザーに表示します。

ステージと同様に、キーワードの jobs は、セクションに複数のジョブがあることを示しています。ジョブは、job キーワードを使用して宣言されます。

- stage: First Stage
  jobs:
  - job: echo "Hello world"
  - job: echo "Hello CI/CD"

First Stage と同様に、Last Stage にもテキスト メッセージを表示する 2 つのジョブが含まれています。

- stage: Last Stage
  jobs:
  - job: echo "Hello last stage"
  - job: echo "Goodbye CI/CD"


最後に、python 3.7 をインストールするタスクもあります。

- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.7'
    architecture: 'x64'


ジョブとタスクの間に依存関係はありません。開発者は、ジョブが実行する bash スクリプトを加えることで、タスクなしでジョブを作成できます。ただし、タスクを使用することで時間を節約できる複雑なユースケースは他にもあります。

CI/CD パイプラインの種類

CI/CD パイプラインを作成およびカスタマイズするには、さまざまな方法があります。

基本的なパイプライン

基本的な CI/CD パイプラインでは、カスタマイズが不要な、シンプルなワークフローを実行できます。このタイプのパイプラインでは、一連の独立したジョブが順次に実行されます。

有向非巡回グラフ (DAG) パイプライン

DAG を使用すると、CI/CD パイプライン内のジョブ間の関係を定義できます。いくつかのチェックおよびロジックを使用して、いくつかの関連するジョブを順次に実行したり、他のジョブを並行して実行することを選択できます。これにより、パイプラインをより効率的かつ迅速に実行できるようになります。次の図は、DAG ワークフローの例です。

ここでは、Group A のジョブは相互に関連しており、Group B のジョブも相互に関連付けされています。CI/CD パイプラインで Other jobs を実行した後、Group A と B は並行して実行を開始できます。ただし、各グループのジョブは順次実行されます。

マージ リクエストのパイプライン

マージ リクエストの CI/CD パイプラインは、メイン ブランチに新しいマージ リクエスト (プル リクエスト) を作成すると実行されます。また、マージ リクエストの有効期間中に複数回実行することもできます。このパイプラインをトリガーするその他のシナリオには、次のようなものがあります。

  • 新しいコミットをプッシュして、マージ リクエストがまだオープン状態のとき
  • マージ リクエストのパイプラインを手動でトリガーするとき

マージ結果パイプライン

マージ結果パイプラインは、マージ リクエスト パイプラインの特殊なものです。ただし、マージ結果パイプラインは、メイン ブランチとマージされたソース コードの結果に対して実行されます。たとえば、プル リクエストがメイン ブランチにマージされた直後に、このパイプラインは、新たにマージされたコード バージョンをその入力データとして、メイン ブランチで実行されます。

マージ トレイン

マージ トレインは、コード リポジトリのメイン ブランチへのマージを待機しているマージ リクエストのキューです。1 つのトレインには多数のマージ リクエストを持たせることができ、各マージ リクエストでマージ結果パイプラインを実行します。各パイプラインには、トレイン内の前にあるマージ リクエストの変更が含まれています。マージ トレインは、古い変更内容がメイン ブランチに入り、ソフトウェアを破壊するのを防ぎます。最終的には、このアプローチにより、正常に処理されたマージ結果パイプラインのみが、本番環境に移行できるようになります。

マージ トレインの仕組み:

マージ トレインに 3 つのマージ リクエスト (A1、A2、A3) があるとします。3 つの並列マージ結果パイプラインが作成されます。

  • 最初のパイプラインは、メイン ブランチと組み合わせて A1 の変更に対して実行されます。
  • 2 つ目のパイプラインは、メイン ブランチと組み合わせて A1 と A2 の変更に対して実行されます。
  • 3 つ目のパイプラインは、メイン ブランチと組み合わせて A1、A2、および A3 の変更に対して実行されます。

A2 パイプラインに障害が発生すると、トレインから離れます。A3 パイプラインはそのまま継続されますが、A1 と A3 の変更のみで実行されます。A1 が正常に終了すると、メイン ブランチにマージされ、A3 が実行されます。さらにマージ リクエストがトレインに入ると、A1 の変更はすでにメイン ブランチに含まれており、A3 のマージ リクエストの変更はマージ トレインにすでに含まれていることになります。

親子パイプライン

CI/CD パイプラインが大きくなるにつれて、次のような課題が発生する場合があります。

  • 同じ CI/CD パイプラインで類似したジョブを複数回参照すると、バグが本番環境に到達する可能性が高くなる。依存ジョブが変更された場合、開発者はパイプライン内でそのジョブへの参照をすべて更新する必要がある。
  • 複数のサブコンポーネント、参照されるジョブ、およびテストにより、パイプラインが肥大化し、維持が困難になる場合がある。
  • パイプラインは、速度最適化のために書き直す必要が多々ある。

親子パイプラインを使用すると、ソフトウェア開発者は、大規模な CI/CD パイプラインを再利用可能なテンプレートに分割できます。これにより、構成の読み取りが容易になり、開発者はワークフローを簡単に理解して管理できます。

マルチプロジェクト パイプライン

CI/CD パイプラインは、複数のプロジェクトにわたって設定できるため、あるプロジェクトの 1 つのパイプラインが開始されると、別のプロジェクトの別のパイプラインがトリガーさます。

CI/CD でのステージ

CI と CD 内の個々のプロセスについては、すでに個別に説明してきました。そのため、完全に自動化された CI/CD パイプラインには、おおまかに次のようなステージがあると言えます。

ステージ 1:ソース管理

ソフトウェア開発者は、コードを記述した後、Git コマンドを使用してコードをコード リポジトリの開発ブランチにプッシュします。次に、プル リクエストをオープンします。プル リクエストは、1 人または複数の技術担当者がレビューします。変更が承認されると、パイプラインで開発ブランチをメイン ブランチにマージします。

ステージ 2:コードのビルド

このフェーズでは、パイプラインはデプロイメント用のコードをパッケージ化します。この作業には、ソース コードとその依存関係からのバイナリ (つまり、実行可能ファイル) のビルドが含まれます。

ステージ 3:自動テストと検証

CI/CDパイプラインで、前のステージで作成したアーチファクトに対して、自動化したユニット テストと統合テストを実行します。テストが失敗した場合、メイン ブランチは元のコードに戻されます。これで、テストが再度実施される前に、開発者はすばやく修正を行い、デプロイできるようになります。すべてのテストが成功すると、ワークフローは次のステージに進みます。

ステージ 4:ステージング環境へのデプロイ

CI/CD パイプラインでステージング環境に接続し、新しくビルドした (テスト済みの) コードをデプロイします。

ステージ 5:最終自動テストと検証

パイプラインで、ステージング環境のアプリケーションに対してエンドツーエンドテストの最終セットを実行し、アプリケーションが期待どおりに動作しているかどうか確認します。

ステージ 6:本番環境へのデプロイ

すべてのテストが正常に実行されると、このステップで、アプリケーションの変更を本番環境で有効にします。

まとめ

CI/CD は、ソフトウェア チームが迅速かつ信頼性の高い方法でコードをビルド、テスト、および出荷できるようになるワークフロー モデルの広義の用語です。

Kong は、最新のマイクロサービスベースの分散アプリケーション向けに、業界最高の API Gateway を提供します。ソフトウェア開発者と DevOps エンジニアは、しばしばさまざまな環境で、Kong とそのプラグインをデプロイし設定する必要があります。CI/CD プロセスは、Kong のデプロイメントおよび構成スクリプトを作成するのに役立ちます。また、decK や inso などのツールを使えば、既存の CI/CD ツール チェーンに容易に統合でき、Kong のデプロイと管理を簡単に行うことができます。そして、これらは、安全かつ予測可能な方法でテストし、後で適用することができます。これで、デプロイ後の手作業での調整が不要になります。また、環境間での設定のずれの可能性も排除できます。

Kong 製品の使用方法と、それら製品の API 指向の開発作業への統合については、今すぐ個別のデモを予約いただき、お確かめください。

原文:What Is CI/CD?

関連記事