Powered by Docker: プラットフォーム エンジニアとしてエンジニアリング運用を効率化

Powered by Dockerは、Dockerのパートナーや実務家によるユースケースと成功事例を紹介するブログ投稿シリーズです。 この記事は、Siimpl.io の Neal Patel によって寄稿されました。 Neal は 10 年以上のソフトウェア開発の経験があり、Docker のキャプテンです。

バックグラウンド

私は、中堅スタートアップ企業のプラットフォームエンジニアとして、ボトルネックを特定し、エンジニアリング組織の速度と規模に対応するためのエンジニアリングオペレーションを効率化するソリューションを開発する責任を負っています。 この記事では、クライアントの1人で直面した課題のいくつかを概説し、それらにどのように対処したか、そしてあなたの会社でこれらの課題に取り組む方法についてのガイドを提供します。

あるクライアントは、開発環境とCI/CD環境間の同期が不十分である、ロールバックメカニズムが不十分なためにインシデント対応が遅い、テレメトリツールが断片化して問題解決が遅れるなど、エンジニアリング上の重大な課題に直面していました。 Siimpl は、開発効率の向上、システムの信頼性の向上、オブザーバビリティの合理化を実現する戦略的ソリューションを実装し、障害を成長の機会に変えました。

私たちが直面した主な課題を見ていきましょう。

非効率的な開発とデプロイ

  • 問題: 開発者ツールと CI/CD ツールの間に同等性が欠けていたため、エンジニアが自信を持って変更をテストすることが困難でした。
  • ゴール: 開発、テスト、本番環境全体で一貫した環境を確保する必要がありました。

信頼性の低いインシデント対応

  • 問題: ロールバックが必要な場合、これを効率的に実現するための適切なインフラストラクチャがありませんでした。
  • ゴール: デプロイの問題が発生した場合に備えて、簡単に安定版に戻したいと考えていました。

包括的なテレメトリの欠如

  • 問題: SRE チームは、テレメトリの収集と公開を簡素化するツールを作成しましたが、配布とアップグレード性は不十分でした。 また、採用率も非常に低いことがわかりました。
  • ゴール: テレメトリ収集の構成方法を標準化し、自動インストルメンテーション ライブラリの構成を簡略化して、開発者エクスペリエンスをターンキーにする必要がありました。

ソリューション:効率的な開発とデプロイ

ブログ ソリューション 効率的な開発 1200

セルフホストのGitHubランナーとDocker Buildxを使用したCI/CD構成

マルチアーキテクチャのサポート(arm64/amd64)の要件があり、最初はDocker BuildxとQEMUを使用してCI/CDで実装しました。 しかし、エミュレートされたアーキテクチャのビルド時間により、パフォーマンスが極端に低下していることに気づきました。

QEMU(エミュレートビルド)を廃止し、Arm64とamd64セルフホストランナーをターゲットにすることで、ビルド時間を約90%短縮することができました。これにより、非常に高速なネイティブ アーキテクチャ ビルドの利点が得られましたが、事後にマニフェストを公開することでマルチアーキテクチャをサポートすることができました。 

ここでは、これから説明するソリューションの実例をご紹介します https://github.com/siimpl/multi-architecture-cicd

これを自分でデプロイする場合は、 README.md にガイドがあります。

前提 条件

このプロジェクトでは、次のツールを使用します。

  • Docker Build Cloud (すべての Docker 有料サブスクリプションに含まれています。
  • DBCクラウドドライバー
  • GitHub/GitHub アクション
  • Elastic Kubernetes Service (EKS)、Azure Kubernetes Service (AKS)、Google Kubernetes Engine (GKE) などのマネージド コンテナー オーケストレーション サービス
  • テラフォーム

このプロジェクトは、Terraform、Kubernetes、Helm などの業界標準のツールを使用しているため、必要な任意の CI/CD またはクラウド ソリューションに簡単に適応できます。

主な機能

このソリューションの秘密のソースは、CI/CD がビルドを実行するアーキテクチャを指定できるように、セルフホスト ランナーをプロビジョニングすることです。

最初のステップは、amd64ノードプールとArm64ノードプールの2つのノードプールをプロビジョニングすることです。これは aks.tf にあります。この例では、node_countは両方のノード プールで 1 に固定されていますが、スケーラビリティ/柔軟性を向上させるために、動的プールの自動スケーリングを有効にすることもできます。

resource "azurerm_kubernetes_cluster_node_pool" "amd64" {
  name                  = "amd64pool"
  kubernetes_cluster_id = azurerm_kubernetes_cluster.cicd.id
  vm_size               = "Standard_DS2_v2" # AMD-based instance
  node_count            = 1
  os_type               = "Linux"
  tags = {
    environment = "dev"
  }
}

resource "azurerm_kubernetes_cluster_node_pool" "arm64" {
  name                  = "arm64pool"
  kubernetes_cluster_id = azurerm_kubernetes_cluster.cicd.id
  vm_size               = "Standard_D4ps_v5" # ARM-based instance
  node_count            = 1
  os_type               = "Linux"
  tags = {
    environment = "dev"
  }
}

次に、セルフホストランナーの values.yaml を更新して、構成可能なnodeSelectorを持つ必要があります。 これにより、1 つのランナー スケール セットを アーム64プール にデプロイし、もう 1 つを amd64プールにデプロイできます。

Terraform リソースが正常に作成されたら、GitHub 構成 URL で指定した組織またはリポジトリにランナーを登録する必要があります。 これで、エミュレートされたビルドネイティブビルドのREGISTRY値を更新できます。

これらの変更を含むプルリクエストを作成したら、 [アクション ] タブに移動して結果を確認します。

ブログの「アクション」タブ 1200

2 つのジョブが開始され、1 つは QEMU でエミュレートされたビルド パスを使用し、もう 1 つはネイティブ ノード ビルドのセルフホスト ランナーを使用します。 キャッシュのヒットやビルドされる Dockerfile によっては、パフォーマンスが最大 90% 向上する可能性があります。 この大幅な改善にもかかわらず、Docker Build Cloudを利用すると、パフォーマンスを 95%向上させることができます。 さらに重要なことは、開発ビルド中にメリットを享受できることです。 詳細については、 docker-build-cloud.yml ワークフローをご覧ください。 Docker Build Cloudのサブスクリプションとクラウドドライバーがあれば、改善されたパイプラインを活用できます。

始める

1。 GitHub PAT の生成

2。 variables.tf を更新する

3。 AZ CLI の初期化

4。 クラスタのデプロイ

5。 パイプラインを検証するための PR を作成する

参考 README.md

信頼性の高いインシデント対応

SemVerタグ付きコンテナを活用して簡単にロールバック

デプロイの問題が予期せず発生する可能性があることを認識していたため、本番環境のデプロイメントを迅速かつ確実にロールバックするメカニズムが必要でした。 以下は、上記で実装したタグ付け戦略に基づいてデプロイを適切にロールバックするためのワークフローの例です。

  1. ロールバックプロセス:
    • 問題のあるビルドの場合、タグ付けされたイメージを使用して、デプロイは以前の安定バージョンにロールバックされました。
    • AWS CLI コマンドを使用して、目的のイメージタグで ECS サービスを更新しました。
on:
  workflow_call:
    inputs:
      image-version:
        required: true
        type: string
jobs:
  rollback:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      context: read
    steps:
     - name: Rollback to previous version
       run: |
         aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment --image ${{ secrets.REGISTRY }}/myapp:${{ inputs.image-version }}

包括的なテレメトリー

テレメトリ データの集約/公開のための ECS でのサイドカー コンテナの構成 (OTEL)

可観測性を標準化するためにOpenTelemetryを採用したとき、採用が最も困難なハードルの1つであることにすぐに気づきました。 チームとして、できるだけ多くの構成をインフラストラクチャ (Terraform モジュール) に組み込んで、オブザーバビリティ インストルメンテーションを簡単に配布および保守できるようにすることにしました。

  1. サイドカーコンテナのセットアップ:
    • サイドカーコンテナは、OpenTelemetryコレクターを実行するためにECSタスク定義で定義されていました。
    • コレクターは、アプリケーション コンテナーからテレメトリ データを集約して発行するように構成されました。
  2. タスク定義の例:
{
  "containerDefinitions": [
    {
      "name": "myapp",
      "image": "myapp:1.0.0",
      "essential": true,
      "portMappings": [{ "containerPort": 8080 }]
    },
    {
      "name": "otel-collector",
      "image": "otel/opentelemetry-collector:latest",
      "essential": false,
      "portMappings": [{ "containerPort": 4317 }],
      "environment": [
        { "name": "OTEL_RESOURCE_ATTRIBUTES", "value": "service.name=myapp" }
      ]
    }
  ],
  "family": "my-task"
}

OpenTelemetry 自動インストルメンテーション ライブラリ (Node.js) のマルチステージ Dockerfile の構成

アプリケーションレベルでは、ほとんどのアプリケーションがビルドプロセスにばらつきがあるため、自動インストルメンテーションの設定は課題となっていました。 マルチステージの Dockerfile を活用することで、マイクロサービス間で自動インストルメンテーション ライブラリを初期化する方法を標準化することができました。 私たちは主にnodejsショップだったので、以下はそのためのDockerfileの例です。

  1. マルチステージ Dockerfile:
    • Dockerfile は、ビルド環境を最終的なランタイム環境から分離するためにステージに分割され、クリーンで効率的なイメージが確保されます。
    • OpenTelemetry ライブラリはビルド ステージにインストールされ、ランタイム ステージにコピーされます。
# Stage 1: Build stage
FROM node:20 AS build
WORKDIR /app
COPY package.json package-lock.json ./
# package.json defines otel libs (ex. @opentelemetry/node @opentelemetry/tracing)
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Runtime stage
FROM node:20
WORKDIR /app
COPY --from=build /app /app
CMD ["node", "dist/index.js"]

業績

これらの課題に対処することで、ビルド時間を~90%短縮することができ、それだけでも、変更のリードタイム復元までの時間のDORAメトリックが~50%減少しました。ロールバック戦略とテレメトリの変更により、平均検出時間 (MTTD) と平均解決時間 (MTTR) を ~30% 短縮することができました。 アラートのチューニングとランブック(自動および手動)の追加により、 50〜60% に達する可能性があると考えています。

  1. 開発効率の向上: 開発、テスト、運用の各段階にわたって一貫した環境により、開発プロセスがスピードアップし、ネイティブ アーキテクチャ ソリューションを使用したビルド時間が約 90% 短縮されました。
  2. 信頼性の高いロールバック: 迅速かつ効率的なロールバックにより、ダウンタイムが最小限に抑えられ、システムの整合性が維持されます。
  3. 包括的なテレメトリ: Sidecar コンテナは、アプリケーションのパフォーマンスに影響を与えることなく、システムの健全性とセキュリティの詳細な監視を可能にし、開発者がデプロイするインフラストラクチャにすぐに組み込まれました。 アプリケーションコードの自動インストルメンテーションは、Dockerfileの採用により大幅に簡素化されました。

Siimpl:クラウドファーストソリューションで企業を変革

Dockerを中核とするSiimpl.ioの ソリューションは、チームがより速く、より信頼性が高く、スケーラブルなシステムを構築する方法を示しています。 CI/CD パイプラインの最適化、テレメトリの強化、安全なロールバックの確保など、Docker は成功の基盤を提供します。 今すぐ Docker をお試しいただき、開発者の生産性と運用効率を新たなレベルに引き上げましょう。

さらに詳しく 当社のウェブサイトから または、 solutions@siimpl.io