パイプラインの効率性
CI/CDパイプラインは GitLab CI/CDの基本的な構成要素です。パイプラインをより効率的にすることで、開発者の時間を節約することができます:
- DevOpsプロセスのスピードアップ
- コストの削減
- 開発者のフィードバックループを短縮
新しいチームやプロジェクトでは、低速で非効率なパイプラインからスタートし、試行錯誤しながら時間をかけて設定を改善していくのが一般的です。より良いプロセスとは、効率を向上させるパイプライン機能をすぐに使用し、ソフトウェア開発ライフサイクルを早期に短縮することです。
まず、GitLab CI/CDの基本に慣れ、クイックスタートガイドを理解していることを確認してください。
ボトルネックとよくある障害の特定
非効率なパイプラインをチェックする最も簡単な指標は、ジョブの実行時間、ステージ、パイプライン自体の総実行時間です。パイプラインの総実行時間は、以下の要素に大きく影響されます:
GitLab Runnerに関するその他の注意点:
- ランナーの可用性とプロビジョニングされたリソース。
- ビルドの依存関係とそのインストール時間。
- コンテナ・イメージのサイズ。
- ネットワーク遅延と低速接続。
パイプラインが不必要に頻繁に失敗することも、開発者のライフサイクルを遅らせる原因になります。失敗したジョブで問題のあるパターンを探すべきです:
- 不規則に失敗する、あるいは信頼できないテスト結果を生成する、不安定なユニットテスト。
- テストカバレッジが低下し、コード品質がその挙動と相関します。
- 安全に無視できる失敗が、代わりにパイプラインを停止させます。
- 長いパイプラインの最後で失敗したテストが、もっと前のステージにある可能性があり、 フィードバックの遅れを引き起こします。
パイプライン分析
パイプラインのパフォーマンスを分析し、効率を改善する方法を見つけます。分析により、CI/CDインフラストラクチャの障害となる可能性を特定できます。これには分析が含まれます:
- ジョブのワークロード。
- 実行時間のボトルネック
- パイプライン全体のアーキテクチャ。
パイプラインのワークフローを理解し、文書化し、可能なアクションや変更について議論することが重要です。パイプラインのリファクタリングには、DevSecOpsライフサイクルにおけるチーム間の慎重な相互作用が必要な場合があります。
パイプライン分析は、コスト効率のイシューを特定するのに役立ちます。例えば、有料のクラウドサービスでホストされているRunnerは、プロビジョニングされている可能性があります:
- CI/CD パイプラインに必要以上のリソースが提供され、コストが浪費されています。
- リソースが足りず、ランタイムが遅く、時間の無駄。
パイプラインインサイト
パイプラインの成功チャートと期間チャートは、パイプラインの実行時間と失敗したジョブ数に関する情報を提供します。
ユニットテスト、インテグレーションテスト、エンドツーエンドテスト、コード品質テストなどのテストは、CI/CDパイプラインによって問題が自動的に発見されることを保証します。パイプラインには多くのステージがあり、実行時間が長くなる可能性があります。
異なるものをテストするジョブを同じステージで並行して実行し、全体の実行時間を短縮することで、実行時間を改善することができます。欠点は、並列ジョブをサポートするために同時に実行するランナーを増やす必要があることです。
GitLab のテストレベルは、多くのコンポーネントが関係する複雑なテスト戦略の例です。
有効非巡回グラフ(DAG) 視覚化
有効非巡回グラフ (DAG) 視覚化は、パイプラインのクリティカルパスを分析し、ブロッカーの可能性を理解するのに役立ちます。
パイプラインのモニタリング
グローバルなパイプラインの健全性は、ジョブやパイプラインの期間とともに監視すべき重要な指標です。CI/CDアナリティクスはパイプラインの健全性を視覚的に表現します。
インスタンス管理者は、追加のパフォーマンスメトリクスとセルフモニタリングにアクセスできます。
APIから特定のパイプラインの健全性メトリクスを取得できます。外部の監視ツールは、APIをポーリングしてパイプラインの健全性を検証したり、長期的なSLA分析のためにメトリクスを収集したりできます。
例えば、GitLab CI Pipelines Exporterfor PrometheusはAPIやパイプラインイベントからメトリクスを取得します。プロジェクトのブランチを自動的にチェックし、パイプラインのステータスと期間を取得できます。Grafanaダッシュボードと組み合わせることで、オペレーションチームのためのアクション可能なビューを構築するのに役立ちます。メトリクスグラフはインシデントに埋め込むこともでき、問題解決を容易にします。さらに、ジョブや環境に関するメトリクスをエクスポートすることもできます。
GitLab CIパイプラインエクスポーターを使用する場合は、設定例から始める必要があります。
あるいは、check_gitlab
のようなスクリプトを実行できる監視ツールを使うこともできます。
ランナー監視
CIランナーをホストシステムやKubernetesのようなクラスタで監視することもできます。これにはチェックが含まれます:
- ディスクとディスクIO
- CPU使用率
- メモリ
- Runnerプロセスリソース
Prometheus Node ExporterはLinuxホスト上のRunnerを監視することができ、kube-state-metrics
Kubernetesクラスタ内で実行されます。
また、GitLab Runnerの自動スケーリングをクラウドプロバイダーでテストしたり、オフライン時間を定義してコストを削減することもできます。
ダッシュボードとインシデント管理
既存のモニタリングツールとダッシュボードを使用してCI/CDパイプラインモニタリングをインテグレーションするか、ゼロから構築します。ランタイムデータがチーム内でアクション可能で有用であり、オペレーション/SREが問題を早期に特定できるようにします。インシデント管理は、問題を分析するためのメトリクスチャートとすべての貴重な詳細を埋め込むことで、ここでも役立ちます。
ストレージ使用状況
コストと効率を分析するために、以下のストレージの使用状況をレビューします:
-
ジョブのアーティファクトとその設定
expire_in
。保管期間が長すぎると、ストレージの使用量が増え、パイプラインが遅くなる可能性があります。 - コンテナレジストリの使用。
- パッケージレジストリの使用。
パイプライン設定
パイプラインを設定する際には、パイプラインを高速化しリソースの使用量を削減するために慎重に選択してください。これには、パイプラインをより速く効率的に実行するGitLab CI/CDの組み込み機能を利用することも含まれます。
ジョブの実行頻度を減らす
あらゆる状況で実行する必要のないジョブを見つけ、パイプライン設定を使って実行しないようにします:
- 新しいパイプラインに取って代わられた古いパイプラインを停止するには、
interruptible
キーワードを使用します。 -
rules
を使用して、不要なテストをスキップします。たとえば、フロントエンドのコードだけが変更された場合にバックエンドのテストをスキップします。 - 必要のないスケジュールパイプラインの実行頻度を減らします。
高速フェイル
CI/CDパイプラインの早い段階でエラーを検出できるようにします。完了までに非常に時間がかかるジョブは、ジョブが完了するまでパイプラインが失敗ステータスを返さないようにします。
失敗する可能性のあるジョブが早い段階で実行されるようにパイプラインを設計しましょう。例えば、初期ステージを追加し、シンタックス、スタイルリンティング、Gitコミットメッセージ検証、および同様のジョブをそこに移動させます。
高速なジョブからの高速なフィードバックの前に、長いジョブを早期に実行することが重要かどうかを判断しましょう。最初の失敗によって、パイプラインの残りの部分を実行すべきでないことが明らかになり、パイプラインのリソースを節約できるかもしれません。
有効非巡回グラフ(DAG)
基本的な設定では、ジョブは常に、実行する前に前のステージにある他のすべてのジョブが完了するのを待ちます。これは最も単純な設定ですが、ほとんどの場合最も遅いです。有効非巡回グラフと 親子パイプラインはより柔軟で、より効率的ですが、パイプラインの理解や分析が難しくなります。
キャッシュ
もう1つの最適化方法は、依存関係をキャッシュすることです。NodeJS/node_modules
のように、依存関係がめったに変更されない場合、キャッシュすることでパイプラインの実行がずっと速くなります。
cache:when
を使えば、ジョブが失敗したときでもダウンロードした依存関係をキャッシュできます。
Dockerイメージ
Dockerイメージのダウンロードと初期化は、ジョブの全体的な実行時間の大部分を占める可能性があります。
Dockerイメージがジョブの実行を遅くしている場合は、ベース・イメージのサイズとレジストリへのネットワーク接続を分析してください。GitLabがクラウドで稼働している場合は、ベンダーが提供するクラウドコンテナレジストリを探してください。それに加えて、他のレジストリよりも高速にGitLabインスタンスからアクセスできるGitLabコンテナレジストリを利用することができます。
Dockerイメージの最適化
大きなDockerイメージは多くの容量を消費し、接続速度が遅いとダウンロードに時間がかかるため、最適化されたDockerイメージを構築します。可能であれば、すべてのジョブに1つの大きなイメージを使用するのは避けましょう。複数の小さなイメージを使用し、それぞれを特定のタスクに使用することで、ダウンロードと実行を高速化できます。
ソフトウェアがプリインストールされたカスタムDockerイメージを使うようにしましょう。一般的なイメージを使用して毎回ソフトウェアをインストールするよりも、設定済みの大きなイメージをダウンロードする方がはるかに速いのが普通です。DockerBest practices for writing Dockerfilesの記事には、効率的なDockerイメージの構築に関する詳しい情報があります。
Dockerイメージのサイズを小さくする方法:
- 小さなベースイメージを使う、例えば
debian-slim
。 - vimやcurlのような便利ツールは、厳密に必要でない場合はインストールしないでください。
- 開発者専用のイメージを作成してください。
- パッケージによってインストールされる man ページやドキュメントを無効にして容量を節約。
-
RUN
レイヤーを減らし、ソフトウェアのインストールステップをまとめます。 - マルチステージビルドを使用して、builderパターンを使用する複数のDockerfileを1つのDockerfileにマージし、イメージサイズを縮小できます。
-
apt
を使用する場合は、不要なパッケージを避けるために--no-install-recommends
を追加してください。 - 最後に不要になったキャッシュやファイルをクリーンアップします。例えば、DebianやUbuntuの場合は
rm -rf /var/lib/apt/lists/*
、RHELやCentOSの場合はyum clean all
。 - diveや DockerSlimのようなツールを使ってイメージを分析し、縮小します。
Dockerイメージの管理を簡素化するために、Dockerイメージを管理する専用のグループを作成し、CI/CDパイプラインでテスト、ビルド、公開することができます。
テスト、文書化、学習
パイプラインの改善は反復プロセスです。小さな変更を加え、その効果を監視し、また繰り返すのです。小さな改善を積み重ねることで、パイプラインの効率は大きく向上します。
パイプラインの設計とアーキテクチャを文書化することは助けになります。MarkdownのMermaidチャートを使って、GitLabリポジトリで直接これを行うことができます。
CI/CDパイプラインの問題やインシデントを、調査や解決策を含めてイシューに記録しましょう。これは新しいチームメンバーのオンボーディングに役立ちますし、CIパイプラインの効率性に関して繰り返し起こる問題を特定するのにも役立ちます。