『DevOps実践ガイド』読書メモ(3)

パート 3 ステップ 1: フロー テクノロジーの実践

パート III の目標は、運用環境を中断したり、顧客サービスを中断したりすることなく、開発から運用までの作業の安定的かつ迅速な流れを可能にするために必要な技術的実践とアーキテクチャを作成することです。これは、実稼働環境への変更のデプロイとリリースのリスクを軽減することを意味します。これは、継続的デリバリーと呼ばれる一連の技術的実践を通じて実現されます。

継続的デリバリーには、自動化されたデプロイメント パイプラインの基礎を築くこと、チームが自動テストを使用してコードがデプロイ可能な状態にあるかどうかを継続的に検証できることを保証すること、開発者がコードを毎日トランクに送信することを保証すること、環境とコードを構築することが含まれます。低リスクのリリースに役立ちます。次の数章では、次のことに焦点を当てます。

  • 導入パイプラインの基礎を築きます。
  • 高速で信頼性の高い自動テストを実現します。
  • 継続的インテグレーションと継続的テストを実装および実践します。
  • 自動化、アーキテクチャの分離などを通じて、低リスクのリリースを実現します。

これらの実践により、本番環境に似た環境を作成するリードタイムを効果的に短縮できます。同時に、継続的なテストによって各チーム メンバーにフィードバックを迅速に提供できるため、小規模なチームが安全かつ独立してコードを開発、テストし、実稼働環境にデプロイできるようになり、実稼働環境へのデプロイメントとリリースが日常業務の一部になります。

9. 導入パイプラインの基礎を築く

開発から運用までの作業を迅速かつ確実に行うには、バリュー ストリームの各段階で本番環境に似た環境を使用する必要があります。さらに、これらの環境は自動化された方法でセットアップされる必要があります。理想的には、これは、運用チームによる手動操作に依存せず、バージョン管理システムに保存されているスクリプトと構成情報を使用してオンデマンドで構築されるべきです。デプロイメント パイプラインの目標は、バージョン管理システムの情報に基づいて運用環境全体を繰り返し構築することです。

9.1 開発環境、テスト環境、本番環境をオンデマンドで構築

運用および保守チームが環境を手動で構築および構成する必要がなくなり、代わりに自動化された方法を使用して次の操作を完了できます。

  • 仮想化環境をコピーします (VMware 仮想マシン イメージ、Vagrant スクリプトの実行、Amazon EC2 仮想マシン イメージ ファイルなど)。
  • 「ベアメタル物理マシン」の自動環境構築プロセスを構築します (たとえば、PXE を使用してベースライン イメージを通じてインストールします)。
  • 「コードとしてのインフラストラクチャ」構成管理ツール (Puppet、Chef、Ansible、SaltStack、CFEngine など) を使用します。
  • オペレーティング システムの自動構成ツール (Solaris Jumpstart、Red Hat Kickstart、Debian preseed など) を使用します。
  • 一連の仮想イメージまたはコンテナー (Vagrant や Docker など) を使用して環境を構築します。
  • パブリック クラウド (アマゾン ウェブ サービス、Google App Engine、Microsoft Azure など)、プライベート クラウド、またはその他の PaaS (OpenShift、Cloud Foundry などのサービスとしてのプラットフォーム) に新しい環境を作成します。

完全に制御可能な環境により、開発者は、本番サービスやその他の共有リソースから欠陥を安全に分離しながら、欠陥を迅速に再現、特定、修正できます。同時に、開発者は環境を変更して、環境を作成するインフラストラクチャ コード (構成管理スクリプトなど) を最適化して、開発と運用の間で情報をさらに共有することもできます。

9.2 統合コードウェアハウスの適用

前段階の作業により、開発環境、テスト環境、本番環境をオンデマンドで構築できるようになりました。次に、ソフトウェア システムのすべての部分が適切に動作していることを確認する必要があります。

バージョン管理システムは、システム内のファイルまたはファイルのコレクションに加えられた変更を記録します。これらのファイルは、ソフトウェア開発プロジェクトのソース コード、リソース ファイル、またはその他のドキュメントです。一連の変更はコミットを構成し、リビジョンとも呼ばれます。各リビジョンとそのメタデータ (変更を誰がいつ行ったかなど) は何らかの方法でシステムに保存されるため、ウェアハウスにある以前のリビジョンのオブジェクトをコミット、比較、マージ、復元することができます。バージョン管理システムは、本番環境のオブジェクトを以前のバージョンにロールバックすることでリスクを軽減することもできます。

壊滅的なインシデントが発生した場合でも、運用環境を再現可能かつ正確に (そして理想的には迅速に) 復元できるようにするには、次のリソースもバージョン管理システムに含める必要があります。

  • アプリケーションのすべてのコードと依存関係 (ライブラリ、静的コンテンツなど)。
  • データベース スキーマ、アプリケーション参照データなどの作成に使用されるスクリプト。
  • 前のセクションで説明した環境を構築するために使用されるすべてのツールとアーティファクト (VMware または AMI 仮想マシン テンプレート、Puppet または Chef 構成モジュールなど)。
  • コンテナの構築に使用されるファイル (Docker または Rocket 定義ファイルや構成ファイルなど)。
  • 自動テストと手動テストをサポートするすべてのスクリプト。
  • コードのパッケージ化、展開、データベースの移行、および環境のプロビジョニングをサポートするスクリプト。
  • すべてのプロジェクト成果物 (要件文書、導入プロセス、リリースノートなど)。
  • すべてのクラウド プラットフォーム設定ファイル (AWS CloudFormation テンプレート、Microsoft Azure Stack DSC ファイル、OpenStack HEAT テンプレート ファイルなど)。
  • エンタープライズ サービス バス、データベース管理システム、DNS ゾーン ファイル、ファイアウォール構成ルール、その他のネットワーク デバイスなどのさまざまなインフラストラクチャ サービスをサポートするために必要な追加のスクリプトまたは構成情報を作成します。

実稼働前環境の状態を再現できるだけでは十分ではなく、実稼働前環境とビルド プロセス全体を再現できなければなりません。したがって、使用するツール (コンパイラやテスト ツールなど) やそれらが依存する環境など、ビルド プロセスが依存するすべてのものをバージョン管理システムに含める必要があります。

実際、ほとんどの場合、環境にはコードよりも数桁多くの構成可能なパラメーターがあります。したがって、バージョン管理を使用する必要がある環境が最も多くなります。

9.3 インフラストラクチャの再構築を容易にする

アプリケーションや環境をオンデマンドで迅速に再構築できると、何か問題が発生した場合でも、修正に時間を費やすことなく、迅速に構築できます。

環境を繰り返し作成することで、リソース プールにサーバーを簡単に追加でき、それによって容量を簡単に増やすことができます (つまり、水平スケーリング)。また、再現不可能なインフラストラクチャに壊滅的な障害が発生した後にサービスを復元しなければならないという苦痛も回避できます。このような壊滅的な障害は、長年にわたる文書化されていない手動変更によって引き起こされることがよくあります。

環境の一貫性を確保するには、実稼働環境に対するすべての変更 (構成の変更、パッチ、アップグレードなど) をすべての実稼働前環境および新しく構築された環境にコピーする必要があります。

自動化された構成管理システム (Puppet、Chef、Ansible、Salt、Bosh など) を利用して一貫性を確保することも、自動化されたビルド メカニズムを通じて新しい仮想マシンまたはコンテナを作成し、実稼働環境にデプロイすることもできます。古いリソースを破壊または削除します。

後者のモデルは不変インフラストラクチャと呼ばれ、実稼働環境では手動操作が許可されなくなります。運用環境に変更を加える唯一の方法は、変更をバージョン管理にチェックし、コードと環境を最初から再構築することです。そうすることで、差異が実稼働環境に入り込む可能性が排除されます。

制御されていない構成の違いを排除するには、実稼働サーバーへのリモート ログインを無効にするか、実稼働環境のインスタンスを定期的に削除して置き換えて、手動による変更が確実に削除されるようにします。これにより、全員がバージョン管理システムを通じて正しい方法で変更を加えることが強制されます。これらの対策により、インフラストラクチャが既知の良好な状態から逸脱する可能性 (構成のドリフト、壊れやすいアーティファクト、粗雑品、スノーフレーク サーバーなど) が体系的に低減されます。

さらに、特に開発者が最新の環境を使用するには、実稼働前環境が最新であることを確認することが重要です。

9.4 運用環境に似た環境で実行する場合のみ「完了」する

オンデマンドで環境をセットアップできるようになり、すべてがバージョン管理されるようになりました。次の目標は、開発チームが日常業務でこれらの環境を確実に使用できるようにすることです。プロジェクトが終了するずっと前、または初めて運用環境にデプロイする前に、アプリケーションが運用環境に似た環境で正常に実行できることを確認する必要があります。

私たちの目標は、プロジェクト全体を通じて、開発と QA がコードを本番環境に似た環境と定期的に統合し、頻度を増やしていくことです。これを行うには、「完了」の定義を拡張します。「完了」とは、機能的に正しいコードが実装されただけでなく、各反復サイクルの最後に、動作する出荷可能なコードが本番環境に似た環境で統合およびテストされたことを意味します。

開発チームと運用チームがコードが環境とどのように相互作用するかを共同で理解し、コードを早期かつ頻繁にデプロイできるようにすることで、実稼働環境でのデプロイメントのリスクが大幅に軽減されます。これにより、プロジェクトの最後の瞬間にアーキテクチャ上の問題が発見されることも防止され、この種のセキュリティ上の危険が完全に排除されます。

9.5 概要

開発から運用までの迅速なワークフローを構築するには、誰でもオンデマンドで本番環境と同様の環境を取得できるようにする必要があります。ソフトウェア プロジェクトの初期段階から開発者に運用環境に似た環境を使用させることで、運用環境で問題が発生するリスクを大幅に軽減できます。これは、運用と保守によって開発効率が向上することを証明する多くの実践例の 1 つでもあります。「完了」という言葉の定義を拡張することにより、開発者は運用環境に似た環境でコードを実行することが求められます。

さらに、すべての運用成果物をバージョン管理システムに取り込むことで、「信頼できる唯一の情報源」が得られ、迅速かつ再現可能で文書化された方法で運用環境全体を再構築し、一貫したプラクティスを使用および開発できるようになります。仕事。インフラストラクチャを修理よりも再構築しやすくすることで、問題をより簡単かつ迅速に解決し、チームの生産性をより簡単に向上させることができます。

10. 高速かつ信頼性の高い自動テストを実現する

開発者と QA スタッフは日常的に、運用環境に似た環境を使用してアプリケーションを実行します。各機能のコードは実稼働環境に似た環境で統合および実行されており、すべての変更はバージョン管理システムにコミットされています。ただし、すべての開発作業が完了するまで待ってから、別の QA 部門に専用のテスト段階でバグを見つけて修正してもらうと、多くの場合、理想的な結果が得られません。また、テストが年に数回しか実行できない場合、開発者は、変更が導入されてから数か月後に初めて自分の犯した間違いを知ることになります。この時点で、問題の原因を特定することは困難であり、開発者はその修正を急ぐ必要があり、間違いから学ぶ能力が大幅に低下します。

自動テストは、重要かつ厄介な問題を解決します。Gary Gruver 氏は次のように述べています。「自動テストがなければ、コードを書けば書くほど、テストに費やす時間と費用が増えます。ほとんどの場合、このビジネス モデルはどのテクノロジー組織にとっても実行不可能です。」

10.1 コードと環境を継続的に構築、テスト、統合する

私たちの目標は、開発者が日常業務で自動化されたテスト スイートを作成し、開発の初期段階で製品の品質を確保できるようにすることです。そうすることで、迅速なフィードバック ループが促進され、開発者が問題を早期に特定し、制約 (時間やリソースなど) が最小限のときに迅速に解決できるようになります。

自動テスト スイートを作成する目的は、統合の頻度を増やし、テストを段階的なアクティビティから継続的なアクティビティに進化させることです。デプロイメント パイプライン (図 10-1 を参照) を構築すると、新しい変更がバージョン管理システムに入ると、一連の自動テストがトリガーされます。
ここに画像の説明を挿入します
デプロイメント パイプラインにより、バージョン管理システムにチェックインされたすべてのコードが、運用環境に似た環境で自動的に構築され、テストされることが保証されます。これにより、開発者はコードの変更を送信するときに、ビルド、テスト、または統合のエラーに関するフィードバックを即座に得ることができ、それらをすぐに修正できるようになります。適切な継続的インテグレーションを実践すると、コードは常にデプロイ可能および出荷可能な状態に保たれます。

これを実現するには、自動化されたビルドおよびテストのプロセスを専用の環境で作成する必要があります。これを行うことは非常に重要であり、その理由は次のとおりです。

  • ビルドおよびテストのプロセスは、エンジニアの個人的な仕事の習慣に関係なく、いつでも実行できます。
  • ビルドとテストのプロセスを個別に行うことで、エンジニアはコードのビルド、パッケージ化、実行、テストに必要なすべての依存関係を確実に理解できます (つまり、「アプリケーションは開発者のラップトップでは動作するが、運用環境では動作しない」という問題が解消されます)。
  • アプリケーションの実行可能ファイルと構成をパッケージ化して環境に繰り返しインストールします (Linux の RPM、yum、npm、Windows の OneGet など)。または、Java の EAR ファイルや WAR ファイル、Ruby gem などの開発フレームワーク固有のパッケージ形式を使用します。ファイル)。
  • プログラム コードをパッケージ化するのではなく、アプリケーションをデプロイ可能なコンテナー (Docker、Rkt、LXD、AMI など) にパッケージ化します。
  • 一貫性があり、再現可能な方法で運用環境に似た環境を構成します (例: 環境からコンパイラを削除する、デバッグ フラグをオフにするなど)。

デプロイメント パイプラインの目的は、バリュー ストリームのすべてのメンバー (特に開発者) にできるだけ早くフィードバックを提供し、コード、環境要因、自動化など、コードをデプロイ可能な状態から逸脱させる可能性のある変更を迅速に特定できるようにすることです。テスト、さらには展開パイプライン、インフラストラクチャへの変更 (Jenkins セットアップなど)。

パイプライン インフラストラクチャを展開した後は、継続的統合の実践も実装する必要があります。これには、次の 3 つの側面の協力が必要です。

  • 導入可能なステータスを検証するための包括的で信頼性の高い自動テスト スイート。
  • 検証テストが失敗した場合、「生産ライン全体を停止する」ことができる文化。
  • 開発者は、存続期間の長い機能ブランチではなく、トランクに取り組み、小さなバッチで変更をコミットします。

10.2 高速で信頼性の高い自動テスト スイートを構築する

新しい変更がバージョン管理システムにチェックインされるたびに、ビルドおよびテスト環境で迅速な自動テストを実行する必要があります。こうすることで、Google の GWS チームと同じように、すべての統合の問題を即座に発見して解決できます。これにより、コード統合の量が少なくなり、コードが常にデプロイ可能になります。

一般に、自動テストは高速なものから低速なものまで次のカテゴリに分類されます。

  • 単体テスト: 通常、各メソッド、クラス、または関数を個別にテストします。その目的は、開発者が設計したとおりにコードが実行されることを確認することです。多くの理由 (高速でステートレスなテストの必要性など) により、スタブアウトは、データベースとその他の外部依存関係を分離するためによく使用されます (たとえば、データベースを呼び出す代わりに静的な事前定義値を返すように関数を変更します)。
  • 受け入れテスト: 通常、アプリケーション全体をテストして、各機能モジュールが設計に従って正常に動作すること (たとえば、ユーザー ストーリーのビジネス受け入れ基準を満たしていること、API を正しく呼び出すことができること)、および回帰エラーがないことを確認します。が導入されます (つまり、以前の通常の機能は破壊されません)。Jez Humble と David Farley は、単体テストと受け入れテストの違いは次のとおりであると考えています。「単体テストの目的は、アプリケーションの特定の部分がプログラマの期待を満たしていることを証明することです...受け入れテストの目的は、アプリケーションはプログラマーの期待に沿うだけでなく、顧客の要望にも応えることができます。」 構築されたバージョンが単体テストに合格した後、展開パイプラインはそれに対して受け入れテストを実行します。受け入れテストに合格したビルドは通常、手動テスト (探索的テスト、ユーザー インターフェイス テストなど) および統合テストに使用できます。
  • 統合テスト: スタブ インターフェイスを呼び出すことなく、アプリケーションが運用環境内の他のアプリケーションやサービスと正しく対話できることを確認します。Jez Humble と David Farley は次のように書いています。「ほとんどのシステム統合テストには、アプリケーションの新しいバージョンをデプロイし、それらが適切に連携するようにすることが含まれます。この場合、スモーク テストは通常​​、アプリケーション全体に対して実行される一連のテストを指します。成熟した受け入れテスト。 " 単体テストと受け入れテストに合格したビルドのみが統合テストを実行できます。統合テストは脆弱なことが多いため、統合テストの数を最小限に抑え、単体テストおよび受け入れテスト中にできるだけ多くの欠陥を検出する必要があります。重要なアーキテクチャ要件は、受け入れテストの実行時に仮想またはシミュレートされたリモート サービスを呼び出す機能です。

プロジェクトの期限のプレッシャーに直面すると、開発者は「完了」の定義に関係なく、日常的に単体テストを作成できなくなる可能性があります。この状況を検出して排除するには、テスト カバレッジ (クラス、コード行数、順列などの数に応じて) を測定し、テスト カバレッジが一定を下回っている場合でも、測定結果を視覚化する必要があります。レベル (たとえば、クラスの単体テスト率が 80% 未満の場合)、テスト スイートの検証結果は失敗を示します。

10.2.1 自動テストの初期段階でエラーを発見する

自動テスト スイートの設計目標の 1 つは、テスト中にできるだけ早くエラーを発見することです。したがって、時間のかかる自動テスト (受け入れテストや統合テストなど) を実行する前に、より高速な自動テスト (単体テストなど) を実行してください。どちらのテストも手動テストの前に実行されます。

したがって、受け入れテストまたは統合テストでバグが見つかった場合は、バグをより早く、より早く、より安価に特定するために、対応する単体テストを作成する必要があります。Martin Fowler は、図 10-2 に示すように、単体テストを使用してほとんどのエラーを検出する「理想的なテスト ピラミッド」の概念について説明しています。対照的に、多くのテスト プロジェクトはその逆で、時間と労力のほとんどを手動テストと統合テストに費やしています。
ここに画像の説明を挿入します
単体テストや受け入れテストの作成と維持が難しく、コストがかかる場合は、アーキテクチャが結合しすぎている可能性があります。これは、モジュール間に明確な境界が存在しなくなった (または存在しなかった) ことを意味します。この場合、統合環境に依存せずにモジュールを独立してテストできるように、より疎結合なシステムを構築する必要があります。最も複雑なアプリケーションであっても、受け入れテストはわずか数分で完了できます。

10.2.2 テストをできるだけ早く並行して実行する

テストを迅速に実行したいため、複数のサーバーを使用する可能性のある並列テストを設計する必要があります。また、さまざまな種類のテストを並行して実行することもできます。たとえば、図 10-3 に示すように、特定のビルドが受け入れテストに合格した後、セキュリティ テストとパフォーマンス テストを並行して実行できます。手動の探索的テストは、ビルドがすべての自動テストに合格するまで実行される場合と実行されない場合があります (探索的テストはフィードバックを高速化できますが、最終的に失敗するビルドに対して手動でテストを実行することもできます)
ここに画像の説明を挿入します
。探索的テストだけでなく、他の形式の手動テストやリソース集約型テスト (パフォーマンス テストなど) にも使用されます。これらのテストはすべて、継続的または定期的に、できるだけ頻繁かつ包括的に実行する必要があります。

10.2.3 最初に自動テストを作成する

信頼性の高い自動テストを確保するための最も効果的な方法の 1 つは、テスト駆動開発 (TDD) やアクセプタンス テスト駆動開発 ( ATDD )などのテクノロジを使用して、日常業務で自動テストを作成することです

Kent Beck は、1990 年代後半にエクストリーム プログラミングの一部として TDD を導入しました。この手法には次の 3 つのステップがあります

  1. テストが失敗することを確認し、「追加したい機能のテスト ケースを作成」し、テスト ケースをチェックインします。
  2. テストが合格したことを確認し、「テストが合格するまで関数を実装するコードを作成」し、コードをチェックインします。
  3. 「古いコードと新しいコードをリファクタリングし、構造を最適化」し、すべてのテストが合格したことを確認して、コードを再度チェックインします。

自動テスト スイートはプログラム コードとともにバージョン管理システムにチェックインされ、使用可能な最新のシステム仕様セットが提供されます。開発者がシステムの使用方法を理解したい場合は、テスト スイートを参照して、システム API の呼び出し方法を示す例を見つけることができます。

10.2.4 手動テストを可能な限り自動化する

自動テストの目的は、できる限り多くのコード エラーを検出し、手動テストへの依存を減らすことです。
「テストは自動化できますが、品質を生み出すプロセスは自動化できません。自動化すべきテストを人間に依頼するのは人間の可能性の無駄です。」

自動テストを実行することで、すべてのテスター (もちろん開発者も含む) は、探索的テストやテスト プロセス自体の最適化など、自動化できない高価値のアクティビティを実行できるようになります。ただし、すべての手動テストを単純に自動化すると、望ましくない結果が生じる可能性があります。自動化されたテストが信頼性の低いものになったり、誤検知が発生したりすることは誰も望んでいません (つまり、コードが正しいため、テストは合格するはずですが、パフォーマンスの低下、タイムアウト、またはエラーが原因です)。信頼性が低い (unreliable) 制御された起動状態、またはデータベース スタブ化または共有テスト環境の使用によって引き起こされ、テストが失敗する予期しない状態。

言い換えれば、少数の信頼できる自動テストから始めて、時間をかけて追加していきます。これにより、システムの保証レベルが向上し、コードを展開可能な状態から外す変更を迅速に検出します。

10.2.5 パフォーマンス テストのテスト スイートへの統合

統合テスト中またはアプリケーションが運用環境にデプロイされた後に、アプリケーションのパフォーマンスの低下が見つかることがよくあります。パフォーマンスの問題は検出が難しいことが多く、問題が発見されるまでに時間の経過とともに徐々にパフォーマンスが低下し、手遅れになる可能性があります (インデックスのないデータベース クエリなど)。さらに、多くの問題は、特に以前に行われたアーキテクチャ上の決定、またはネットワーク、データベース、ストレージ、またはその他のシステムのこれまでに発見されていない制限に起因する場合、解決が困難です。

自動パフォーマンス テストを作成して実行する目的は、デプロイメント パイプラインの一部としてアプリケーション スタック全体 (コード、データベース、ストレージ、ネットワーク、仮想化など) のパフォーマンスを検証し、問題をできるだけ早く発見できるようにすることです。最小限のコストで解決し、できるだけ早く問題を解決します。

本番環境のような負荷の下でアプリケーションと環境がどのように動作するかを理解できれば、より適切な容量計画を立てて、次のような状況を検出できます。

  • データベースのクエリ時間の非線形的な増加 (たとえば、データベースのインデックスの作成を忘れると、ページの読み込み時間が 100 ミリ秒から 30 秒に増加します)。
  • コードを変更すると、データベース呼び出しの数、ストレージ領域の使用量、またはネットワーク トラフィックが数倍に増加します。

10.2.6 非機能要件テストのテスト スイートへの統合

コードをテストし、それが期待を満たし、運用環境のような負荷の下で適切に動作することを検証することに加えて、システムの他の品質属性も検証する必要があります。これらの品質属性は非機能要件と呼ばれることが多く、可用性、拡張性、容量、セキュリティなどが含まれます。

多くの非機能要件は、環境を正しく構成することで達成されるため、環境のセットアップと構成が正しいことを検証するために、対応する自動テストを作成する必要があります。たとえば、多くの非機能要件 (セキュリティ、パフォーマンス、可用性など) が依存する以下の項目の一貫性と正確性を保証する必要があります。

  • 使用されるアプリケーション、データベース、およびソフトウェア ライブラリ。
  • プログラミング言語インタプリタやコンパイラなど。
  • オペレーティング システム (例: 監査ログの有効化など);
  • すべての依存関係

コードとしてのインフラストラクチャ構成管理ツール (Puppet、Chef、Ansible、SaltStack、Bosh など) を使用する場合、コードのテストに使用するのと同じフレームワークを使用して、環境が正しく構成され、適切に実行されているかどうかをテストできます。環境テストを Cucumber または Gherkin テストに書き込む場合など)。

さらに、デプロイメント パイプライン内のアプリケーションのコード分析 (静的コード分析やテスト カバレッジ分析など) と同様に、ツール (Chef の Foodcritic や Puppet の puppet-lint など) もビルド環境のコードの分析に使用されます。すべてのセキュリティ強化チェックは、関連するすべての構成 (サーバーの仕様など) が正しいことを確認する自動テストの一環としても実行する必要があります。

自動テストでいつでも、コードがデプロイ可能な状態にあることを確認できます。デプロイ パイプラインに障害が発生した場合に、ビルドをグリーン状態に復元するために必要な手順をすぐに実行できるように、アンドン ロープ メカニズムを必ず設定してください。

10.3 デプロイメントパイプラインが失敗したときにアンドンコードを引く

デプロイメント パイプラインでビルドがグリーン ステータスにある場合、コードの変更を本番環境に自信を持ってデプロイできます。

導入パイプラインを環境に優しい状態に保つために、トヨタ生産システムの物理デバイスと同様の仮想アンドン ロープを必ず作成してください。開発者がビルドまたは自動テストの失敗を引き起こすコード変更を送信すると、問題が解決されるまで新しい変更を送信することはできません。この章の冒頭で説明した Google の場合のように、問題解決の助けが必要な場合は、必要なリソースをすべて入手できます。

デプロイメント パイプラインが失敗した場合は、少なくともチーム全体に通知してください。全員が協力して問題を修正したり、コードをロールバックしたり、展開パイプラインの最初の段階 (つまり、ビルドや単体テスト) がグリーン状態に戻るまで後続のコードのコミットを拒否するようにバージョン管理システムを構成したりすることもできます。問題が自動テストによって生成された誤検知に起因する場合は、テストを書き直すか削除する必要があります。デプロイ パイプラインをグリーン状態に戻すには、チームのメンバー全員がロールバック操作にアクセスできる必要があります (私は懐疑的ですが)。

導入パイプラインの後の段階 (受け入れテストやパフォーマンス テストなど) が失敗した場合、新しい作業をすべて停止するのではなく、問題が発生したらすぐに修正する責任を負う開発者とテスターのサブセットを待機させておく必要があります。これらの開発者とテスターは、これらの問題によって引き起こされる回帰エラーを検出するために、展開パイプラインの早い段階で新しいテストを実行する必要もあります。たとえば、受け入れテスト中に欠陥が発見された場合は、問題を把握するために単体テストを作成する必要があります。同様に、探索的テスト中に欠陥が発見された場合は、対応する単体テストまたは受け入れテストを作成する必要があります。

ある意味、このステップはサーバーの構築とテストよりも困難です。これらは純粋に技術的な作業ですが、このステップでは人間の行動を変え、インセンティブを提供する必要があります。

アンドン コードを引く理由
アンドン コードを引いてデプロイメント パイプラインの問題をすぐに解決しないと、アプリケーションと環境をデプロイ可能な状態に戻すことがさらに困難になります。次の状況を考えてください

  • 誰かがビルドまたは自動テストの失敗を引き起こすコードを提出しましたが、誰もそれを修正しませんでした。
  • 他の誰かが、失敗したビルドに加えてコード変更を送信しました。もちろん、これは自動テストには失敗しますが、修正はおろか、新たな欠陥の発見に役立つようなテストの結果を誰も見ることができません。
  • 既存のテストはどれも確実に実行できないため、新しいテスト ケースを作成する可能性は低いです。(なぜこれをわざわざ行うのでしょうか? 現在のテストに合格することさえできません。)

10.4 概要

この章では、ビルドが常にグリーンで展開可能な状態であることを確認するために、包括的な自動テストのセットを作成します。デプロイ パイプラインでのテスト スイートとテスト アクティビティを整理し、自動テストの失敗の原因となったコードの変更に関係なく、全員がシステムをグリーン状態に復元するために最善を尽くすことを要求する仕様を確立しました。

このアプローチは継続的統合の基礎を築き、多くの小規模チームが独立して安全にコードを開発、テスト、デプロイして顧客に価値を提供できるようにします。

おすすめ

転載: blog.csdn.net/u010230019/article/details/132729753