ウェブサイト検索

Dockerによる自動化されたプロダクションデプロイメントのための3つの戦略


Dockerは人気のある開発ツールで、再現可能な設定を使ってアプリケーションの孤立したインスタンスを簡単に開始できるためです。また、Dockerは本番環境でも使用でき、ライブデプロイメントが開発環境と同一であることを保証します。

コンテナを生産に投入することは、必ずしも単純に行えるわけではありません。

docker run

あなたのローカルマシン上で。手動でイメージをレジストリにプッシュし、リモートDockerホストに接続し、コンテナを起動するのはあまり良いアイデアではありません。これは人間の介入に依存しているため、時間がかかり、エラーが発生しやすくなります。

このガイドでは、Dockerのデプロイを自動化し、一貫した構成を維持するために使用できる3つの異なる戦略を見ていきます。これらのアプローチは、CIパイプラインの一部としてスクリプト化でき、コードが変更されるたびに新しいコンテナを起動することができます。スクリプトの最初のステージとして、Dockerイメージを構築し、それをレジストリにプッシュする必要があります。その後、以下のテクニックのいずれかを使用して、イメージをプルし、プロダクション環境でコンテナを起動します。

1. SSH経由のDocker Compose

Docker Composeを使用すると、一つのコマンドで複数のコンテナを起動できます。さらに、ComposeはYAMLファイルを介して構成され、変更のバージョン管理を行い、再現可能なデプロイを保証します。

既にComposeをローカル開発ツールとして使用しているかもしれません。作業ディレクトリにdocker-compose.ymlファイルを作成する必要があります。その後、1つ以上の要素を追加します。

services

開始するコンテナを定義する:

version: 3
services:
  app:
    image: example.com/app:latest
    ports:
      - 80:80
  database:
    image: mysql:8.0
    expose:
      - 3306

Composeファイルを取得したら、docker-compose up -dコマンドを使用してコンテナを起動します。ファイルを修正した場合は、変更を適用するためにコマンドを再実行してください。Composeは新しく宣言された状態を達成するために、コンテナを更新または置き換えます。

--pull フラグを追加すると、Composeはコンテナを起動する前に更新されたイメージを取得しようとします。また、--force-recreate を使用すると、基になる設定が変更されていなくても、新しいコンテナの作成を強制することができます。

これはすべて、プロダクションデプロイメントとどのように関連しているのでしょうか?これは、ComposeをCIパイプラインの一部として使用することで、docker-compose.ymlファイルに宣言した状態を満たすコンテナを簡単に起動できるということを意味します。各パイプラインでdocker-compose up -d --pullを実行することで、それぞれが最新のイメージバージョンを実行するコンテナのセットが得られます。

この方法を実装する方法はいくつかあります。最も簡単で安全な方法は、プロダクションホストにDockerとComposeをインストールし、SSHを介して接続することです。CIプロバイダーの設定を使用して、SSH資格情報をパイプラインでアクセス可能な変数として保存する必要があります。その後、パイプラインでSSHクライアントを設定し、docker-compose.ymlファイルをリモートホストにコピーし、docker-compose upコマンドを実行します。

こちらがサンプルスクリプトです:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo $SSH_PRIVATE_KEY | ssh-add -
echo $SSH_HOST_KEY > ~/.ssh/known_hosts
scp docker-compose.yml:ci-user@example.com:/home/ci-user/docker-compose.yml
ssh -t ci-user@example.com docker-compose up -d

代わりに、Dockerコンテキストを使用して、パイプラインの環境内でローカルにComposeバイナリを実行できます。これには、リモートホストでDockerソケットを公開する必要があります。これはセキュリティリスクとなる可能性があるため、SSHも使用できる状況ではこのアプローチは一般的に好ましくありません。

この方法に従うと、パイプラインを実行するホストにDockerとComposeをインストールすることになります。パイプラインスクリプト内で、リモートの本番ホストを指しているDockerコンテキストを登録して選択します。接続の詳細は、CIプロバイダーの設定パネルに設定された変数として提供する必要があります。コンテキストを選択したら、パイプラインの環境内でdocker-compose up -dを実行しますが、コマンドはリモートサーバーに対して実行されます。

2. プラットフォーム・アズ・ア・サービス(PaaS)を使用すること

プラットフォームとしてのサービス(PaaS)を導入することは、プロダクションでDockerコンテナを運用する別のアプローチです。Dokkuのようなソリューションを使用して自分でホスティングすることも、Amazon ECS、DigitalOcean App Platform、またはHerokuなどのホスティングされたサービスを選択することもできます。

PaaSは、イメージの構築、詳細な設定の維持、および独自のDockerホストのプロビジョニングの複雑さを抽象化します。リポジトリをプラットフォームに直接プッシュするためにGitを使用するか、変更をアップロードするためのCLIコマンドを実行します。PaaSは、ソースアセット、Dockerfile、またはプラットフォーム特有の設定ファイルからコンテナの作成を処理します。

PaaSソリューションは、最小限の手動でのDocker操作で迅速にオンラインになるための優れた方法です。これらはCIパイプラインに統合しやすく、ほとんどの主要プロバイダーは、始めるためのサンプルスクリプトを提供しています。しかし、PaaSの限界を超える可能性があり、その場合は将来的にインフラストラクチャを再考する必要があるかもしれません。

選択したプラットフォームへの展開を自動化する手順は、プロバイダーによって異なります。DokkuやGit統合を備えた類似のPaaSを使用している場合、CIスクリプトは次のように2行で済むことがあります:

git remote add dokku dokku@example.com:app-name
git push dokku master

このスクリプトはあなたのDokkuサーバーをGitのリモートとして追加し、リポジトリの内容をプッシュします。Dokkuは自動的にあなたのDockerfileからイメージをビルドし、コンテナインスタンスを起動します。この機能を利用するには、CIサーバーのSSH公開鍵をDokkuに追加する必要があります。そうしないと、CIスクリプトはプラットフォームに認証できなくなります。

3. Kubernetes/Docker Swarmによるオーケストレーション

KubernetesやDocker Swarmなどのオーケストレーターを使用することは、ライブコンテナインスタンスを実行する最も一般的な方法と言えるでしょう。これらのツールは、運用環境でコンテナをデプロイおよびスケールするために特別に設計されています。

オーケストレーターはインフラ管理の複雑さを取り除き、アプリケーションとそのコンポーネントに集中できるようにします。Docker Composeと同様に、状態構成に対して宣言的アプローチを取り、最終的な状態がどのようになるべきかを定義します。オーケストレーターは、その状態を達成するための適切なアクションの順序を決定します。

Kubernetesは最も人気のあるオーケストレーターです。Kubernetesクラスターと対話する方法の1つは、公式CLI管理ツールであるKubectlを使用することです。Kubectlを使用すると、クラスター内に作成するコンテナリソースを定義するYAML形式のマニフェストファイルを適用できます。

ここに、単一のコンテナインスタンスを作成するシンプルなマニフェストがあります:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
        - name: demo
          image: example.com/image:latest

このマニフェストをクラスターに適用するには、Kubectlを使用できます:

kubectl apply -f manifest.yaml

ファイルへのその後の変更は、コマンドを繰り返すことで適用されます。Kubernetesは、新しく宣言された状態を達成するために必要なアクションを自動的に実行します。

これにより、Kubernetesは自動化されたプロダクションデプロイメントにとって優れたオプションとなります。パイプライン内でkubectl applyを使用して、リポジトリ内のマニフェストを読み込み、クラスターに宣言された状態を適用できます。各コミットごとに新しいイメージタグを作成すると、Kubernetesはそのイメージをプルし、デプロイメントのために新しいコンテナを起動します。

これを設定するには、パイプライン変数としてKubeconfig設定ファイルの内容を提供する必要があります。これにより、Kubectlはクラスター接続に使用する資格情報を得ます。その後、ローカルのKubectlバイナリはリモートクラスターに対して操作します。

Docker Swarm は、Docker に統合された別のオーケストレーションオプションです。以前に説明したのと同じ docker-compose.yml ファイルを使用して、Swarm スタックをセットアップすることができます。その後、SSH 経由で Swarm ホストに接続するか、Docker コンテキストを使用してローカル Docker バイナリのターゲットを変更することで、同様のデプロイメントアプローチを使用できます。

オーケストレーターは、単純なコンポーズや管理されたPaaSよりもはるかに複雑です。Kubernetesの場合、コンテナをデプロイする前に、新しい抽象化、用語、設定ファイル形式を学ぶ必要があります。しかし、クラスターは追加の機能を提供し、長期間にわたってアプリケーションを維持するのを容易にします。複数のホストにわたってレプリカを簡単にスケールし、冗長性を組み込み、ログとメトリックを集約することができます。

したがって、オーケストレーションは複数のコンテナを運用する大規模システムにとって最適な選択です。しかし、業界の注意を引くツールがあるからといって、すべてのデプロイメントにKubernetesを使用すべきだというわけではありません。ComposeやPaaSは、スケーラビリティやベンダーロックインにそれほど気を使わない小規模なユースケースでは、設定、理解、維持が容易です。

要約

私たちは、コンテナをプロダクションワークロードとして実行する3つの異なる方法を見てきました。実装の詳細は、選択した戦略、サポートツールチェーン、およびCI環境によって異なるため、ワークフローの一部としての自動化をどのように設定できるかについての正確な説明は省略しました。ただし、3つすべては、コードをマージまたはプッシュするたびに実行されるCIパイプラインに簡単に統合できます。

Kubernetesのようなツールを使ったオーケストレーションは、複数のコンテナで動作するシステムのスケーラブルなデプロイメントのための優先方法として急速に普及しました。それは対象とするサービスの運用を大幅に簡素化できますが、同時に重要な学習曲線とメンテナンスの負担も伴うため、代替手段を考慮せずに飛び込むべきではありません。

少数のコンポーネントから形成された小規模システムは、既存のDockerホスト上で再現可能な設定でコンテナを起動するためにComposeを使用することで、より良い結果が得られるかもしれません。これにより、宣言型設定などのKubernetesのいくつかの利点を享受できますが、追加の複雑さはありません。また、既存のComposeファイルにDocker Swarmのサポートを追加することで、後でオーケストレーションに「徐々に」移行することができ、複数の分散レプリカのコンテナを起動することが可能です。

最後に、プラットフォーム・アズ・ア・サービスのオプションは、詳細なコンテナの詳細を考えることなく、アプリケーションのデプロイメントを加速させます。これらのサービスは、最小限の設定から完全なインフラストラクチャの自動化を提供する可能性があります。しかし、長期的には制約がある可能性があるため、コミットする前にあなたのソリューションが時間とともにどのように成長するかを考慮してください。

コンテナを本番環境にデプロイする際には、イメージホスティングや設定注入についても考慮する必要があります。公開レジストリサービスを使用して、イメージを本番環境で利用できるようにすることができます。その代わりに、プライベートレジストリを運営し、CIパイプラインの一部として認証情報を提供することもできます。設定値は通常、環境変数として提供され、CIプロバイダーの設定画面で定義できます。

関連記事: