Dockerは、再現可能な構成でアプリケーションの分離されたインスタンスを簡単に開始できるため、人気のある開発ツールです。また、実稼働環境が開発環境と同一であることを保証する本番環境でも使用できます。
コンテナを本番環境に移行することは、docker run
を実行するほど簡単ではありません。 ローカルマシンで。イメージをレジストリに手動でプッシュし、リモートのDockerホストに接続して、コンテナーを起動することはお勧めできません。これは人間の介入に依存しているため、時間がかかり、エラーが発生しやすくなります。
このガイドでは、Dockerのデプロイを簡単に自動化し、一貫した構成を維持するために使用できる3つの異なる戦略について説明します。これらのアプローチは、CIパイプラインの一部としてスクリプト化して、コードが変更されるたびに新しいコンテナーを開始できます。スクリプトの最初の段階としてDockerイメージをビルドし、レジストリにプッシュする必要があります。次に、以下のいずれかの手法を使用して、イメージをプルし、本番環境でコンテナーを起動します。
1。 Docker Compose Over SSH
Docker Composeを使用すると、1つのコマンドで複数のコンテナーを起動できます。さらに、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
作成ファイルを取得したら、docker-compose up -d
を使用します コンテナを起動するコマンド。ファイルを変更する場合は、コマンドを繰り返して変更を適用します。 Composeは、コンテナを更新または置換して、新しい宣言された状態を実現します。
--pull
を追加する フラグは、コンテナを起動する前に更新されたイメージをプルするように作成するように指示します。 --force-recreate
を使用することもできます 基になる構成が変更されていない場合でも、新しいコンテナーの作成を強制します。
これはすべて、本番環境の展開とどのように関連していますか?つまり、CIパイプラインの一部としてComposeを使用して、docker-compose.yml
で宣言した状態を満たすコンテナーを簡単に起動できます。 ファイル。 docker-compose up -d --pull
を実行します 各パイプラインで、それぞれが最新バージョンのイメージを実行する一連のコンテナを提供します。
このメソッドを実装する方法はいくつかあります。最も簡単で安全な方法は、DockerとComposeを本番ホストにインストールしてからSSH経由で接続することです。パイプラインにアクセス可能な変数としてSSHクレデンシャルを保存するには、CIプロバイダーの設定を使用する必要があります。次に、パイプラインで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:[email protected]:/home/ci-user/docker-compose.yml
ssh -t [email protected] docker-compose up -d
または、Dockerコンテキストを使用して、パイプラインの環境内でComposeバイナリをローカルで実行することもできます。これには、リモートホストでDockerソケットを公開する必要があります。これはセキュリティリスクになる可能性があるため、SSHも使用できる状況では、このアプローチは一般的にあまり好ましくありません。
この方法に従うと、パイプラインを実行するホストにDockerとComposeをインストールする必要があります。パイプラインスクリプト内で、リモートの本番ホストを指すDockerコンテキストを登録して選択します。接続の詳細は、CIプロバイダーの設定パネルで設定された変数として提供する必要があります。コンテキストを選択した状態で、docker-compose up -d
を実行します パイプラインの環境にありますが、リモートサーバーに対して実行されたコマンドを参照してください。
2。 Platform-as-a-Service(PaaS)の使用
Platform-as-a-Service(PaaS)オファリングの採用は、本番環境でDockerコンテナーを実行するためのもう1つのアプローチです。 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 [email protected]:app-name
git push dokku master
このスクリプトは、DokkuサーバーをGitリモートとして追加し、リポジトリのコンテンツをプッシュします。 DokkuはDockerfile
から画像を自動的に作成します コンテナインスタンスを開始します。これを機能させるには、CIサーバーのSSH公開鍵をDokkuに追加する必要があります。そうしないと、CIスクリプトがプラットフォームに対して認証できなくなります。
3。 Kubernetes /DockerSwarmによるオーケストレーション
KubernetesやDockerSwarmなどのオーケストレーターを使用することは、間違いなく、ライブコンテナーインスタンスを実行する最も一般的な方法です。これらのツールは、実稼働環境でコンテナを展開およびスケーリングするために設計されています。
オーケストレーターは、インフラストラクチャ管理の複雑さを取り除き、アプリケーションとそのコンポーネントに集中できるようにします。 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と統合されたもう1つのオーケストレーションオプションです。同じdocker-compose.yml
を使用してSwarmスタックを設定できます 前述のようにファイル。次に、SSH経由でSwarmホストに接続するか、Dockerコンテキストを使用してローカルDockerバイナリのターゲットを変更する、同様のデプロイアプローチを使用できます。
オーケストレーターは、プレーンなComposeやマネージドPaaSを使用するよりもはるかに複雑です。 Kubernetesの場合、コンテナをデプロイする前に、新しい抽象化、用語、設定ファイル形式を学ぶ必要があります。ただし、クラスターには追加の機能もあり、アプリケーションを長期間にわたって簡単に保守できます。複数のホストにレプリカを簡単にスケーリングし、冗長性を組み込み、ログとメトリックを集約できます。
したがって、オーケストレーションは、複数のコンテナーを実行する大規模なシステムに最適なオプションです。これは、ツールが業界の注目を集めているために、すべてのデプロイでKubernetesを使用する必要があるという意味ではありません。作成またはPaaSは、スケーラビリティとベンダーロックインの心配が少ない小規模なユースケースのセットアップ、推論、および保守が容易になります。
本番ワークロードとしてコンテナを実行する3つの異なる方法を見てきました。実装の詳細は、選択した戦略、サポートツールチェーン、およびCI環境によって異なるため、ワークフローの一部として自動化を設定する方法の正確な説明は省略しました。ただし、コードをマージまたはプッシュするたびに実行されるCIパイプラインに3つすべてを簡単に統合できます。
Kubernetesのようなツールを使用したオーケストレーションは、複数のコンテナーを実行するシステムのスケーラブルなデプロイに急速に好まれる方法になりました。設計されたサービスの運用を大幅に簡素化できますが、学習曲線とメンテナンスのオーバーヘッドが大幅に増えるため、代替案を検討せずに飛び込むべきではありません。
いくつかのコンポーネントで構成された小規模なシステムでは、Composeを使用して、既存のDockerホストで再現可能な構成でコンテナーを起動するとより良い結果が得られる場合があります。これにより、宣言型の構成など、Kubernetesの利点のいくつかが追加の複雑さなしに提供されます。 Docker Swarmサポートを既存のComposeファイルに追加して、コンテナーの複数の分散レプリカを開始できるようにすることで、後でオーケストレーションを「簡単に」行うことができます。
最後に、Platform-as-a-Serviceオプションは、詳細なコンテナーの詳細について考えることなく、アプリケーションのデプロイメントを加速します。これらのサービスは、最小限の構成から完全なインフラストラクチャ自動化の見通しを提供します。長期的には制限される可能性がありますが、コミットする前に、ソリューションが時間の経過とともにどのように成長するかを考えてください。
コンテナを本番環境にデプロイするときは、イメージホスティングと構成インジェクションも考慮する必要があります。パブリックレジストリサービスを使用して、本番環境でイメージを使用できるようにすることができます。または、独自のプライベートレジストリを実行し、CIパイプラインの一部としてクレデンシャルを提供することもできます。構成値は通常、CIプロバイダーの設定画面で定義できる環境変数として提供されます。