Dockerコンテナをアップグレードしてイメージの更新を適用する方法
Dockerコンテナは使い捨てで簡単に交換可能であることを目的としています。コンテナのベースイメージの新しいバージョンがリリースされた場合は、新しいイメージをプルして新しいコンテナインスタンスを開始する必要があります。こちらがコンテナ群のイメージアップデートを管理する方法です。
新しい画像を引き込む
画像の更新を適用する基本的な方法は、新しい画像を取得し、古いバージョンに基づく実行中のコンテナを破棄し、その代わりに新しいコンテナを起動することです。
ここにコンテナを使用するための一例があります。
nginx:latest画像 :
Pull new image
docker pull nginx:latest
Delete old container by name
docker rm example-nginx
Start a new container
docker run -d -p 80:80 --name example-nginx nginx:latest
Dockerにはイメージの更新を検出して実行中のコンテナを置き換えるための組み込みの方法がありません。その結果、複雑な手動置き換えプロセスが発生します。これは、単純な docker run コマンドの代わりにDocker Composeを使用してコンテナを起動することで簡素化できます。
Docker Composeを使用してコンテナを置き換える
Docker Composeは、docker-compose.ymlファイルを使用して、コンテナスタックの宣言的な表現を作成することを可能にします。このスタックは、ファイルに含まれる設定を使用してdocker-compose upで起動されます。これは通常docker runに与えられる長いフラグのリストを置き換えます。
Docker Composeには、スタック内のすべてのイメージの更新版をプルするための組み込みのpullコマンドがあります。ただし、その後に手動でdocker-compose upを再度実行する必要があるため、依然として2段階の手順です。
Pull all images in the stack
docker-compose pull
Restart the stack
If a new image version has been pulled, containers
using the old tag will be replaced with new instances.
docker-compose up -dDocker Composeは、イメージ名を入力したり、docker runに渡したフラグを覚えておく必要がない、よりシンプルで記憶しやすい体験を提供します。これらの2つのコマンドは、簡単に単一のシェルエイリアスに短縮できます。
alias composePullUp="docker-compose pull && docker-compose up -d"画像タグの管理
手動で画像を取得する際は、正しいタグを参照する必要があります。Docker Composeはこれを自動的に処理し、docker-compose.ymlで指定されたタグを選択します。
タグの新しいバージョンをプルすることは、必ずしもイメージの最新リリースを使用することと同じではありません。コンテナ内のソフトウェアの最新バージョンを使用したい場合は、イメージ作成者のタグ付けの慣行に注意してください。
例として、新しいバージョンのnode:14を引っ張ると、Node.js 14の最新のパッチリリースが取得できます。node:latestを引っ張ると、現在の最新のNode.jsバージョンである16が配信されます。古いコンテナがこのイメージを使用していた場合、プルおよび置き換えプロセスがコンテナ内のNodeバイナリのメジャーバージョンのバンプを引き起こします。
画像の再構築
これまで、Docker Hubや他のレジストリから直接取得する画像から開始されたコンテナを処理する方法を見てきました。自分で構築しているイメージは、その基本イメージが変更されたときに再構築する必要があります。
まず、画像を再構築します:
docker build --pull -t my-image:latest .それからあなたの容器を交換してください:
Delete old container by name
docker rm my-container
Start a new container
docker run -d --name my-container my-image:latest
docker buildに与えられた--pullフラグは、DockerにDockerfileで参照されているベースイメージをプルするよう指示します。このフラグがない場合、Dockerはシステム上にすでにイメージが存在する場合、既存のタグリファレンスを再利用します。
Docker Composeのユーザーは、対応するdocker-composeコマンドを使用して同様の結果を得ることができます:
docker-compose build --pull
docker-compose up -dComposeは再び、より簡単ではあるものの、依然として二段階のプロセスを提供します。特定の画像名やタグを忘れて、Composeに変更されたベースイメージを取得し、それに基づいてレイヤーを再構築し、コンテナを再作成させることができます。
コンテナ内のソフトウェア
時々、コンテナ内のソフトウェアを手動で更新したくなることがありますが、これはDockerの原則に反するため避けるべきです。
スケジュールに従ってapt-get update && apt-get upgrade -yを実行する(またはパッケージマネージャーの対応するコマンド)ことは、ベアメタルのLinuxサーバーを管理する際の標準的なプラクティスです。これらのコマンドは通常、Dockerコンテナ内では実行されませんが、イメージのビルド中に最新のセキュリティパッチを取得するためにDockerfileの一部として含まれることがあります。
ベースイメージを定期的に取得し、コンテナを作り直すことが、それらを最新の状態に保つための推奨される方法です。これにより、すべての上流のセキュリティ修正が得られ、個々のコンテナの寿命が短くなります。コンテナ環境は、インスタンスが作成された後に変更することを意図していません; ファイルシステムの変更は、一時的なパスへの書き込みおよびコンテナよりも長生きする専用のDockerボリュームに制限されるべきです。
コンテナ更新の自動化
第三者のプロジェクトを使用して、更新されたイメージタグを確認し、コンテナを再起動するプロセスを自動化できます。Watchtowerは人気のある選択肢で、実行中のコンテナを監視し、Docker Hubのイメージが変更されるとそれを置き換えます。
ウォッチタワー自体はコンテナとして展開されています。
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtowerこれで、機能するWatchtowerのインストールが完了しました。ホストのDockerソケットがWatchtowerコンテナにマウントされているため、コンテナの作成や削除のためにDockerコマンドを実行できます。
WatchtowerはDocker Hubでの新しいイメージリリースを自動的に検出し、それらをあなたのマシンにプルし、イメージを使用してコンテナを置き換えます。既存のコンテナはシャットダウンされ、その代わりに新しい同一のコンテナが作成されます。docker runに渡した同じフラグが置き換えられたコンテナに供給されます。
WatchtowerはデフォルトでDocker Hubのみで動作します。設定ファイルに資格情報を供給することで、プライベートイメージレジストリでも使用できます。
次の内容を持つJSONファイルを作成してください。
{
"auths": {
"example.com": {
"auth": "credentials"
}
}
}example.com をあなたのレジストリへのパスに置き換えてください。
次に、レジストリのユーザー名とパスワードから資格情報文字列を生成します:
echo -n 'username:password' | base64生成されたBase64エンコードされた文字列を設定ファイルに貼り付けて、credentialsプレースホルダーのテキストを置き換えてください。
レジストリへのアクセスを有効にするために、設定ファイルをWatchtowerコンテナにマウントします:
docker run -d
-v config.json:/config.json
-v /var/run/docker.sock:/var/run/docker.sock
containrrr/watchtower結論
Dockerには、実行中のコンテナに対してアップストリームイメージの更新を検出し適用するメカニズムがありません。新しいイメージバージョンがリリースされた場合、Docker CLIコマンドを順番に使用するか、docker-composeのような高レベルの抽象化を使用するか、Watchtowerのようなサードパーティツールを使用してコンテナを置き換えることができます。
あなたの状況によっては、この方法でコンテナをアップグレードする必要を感じないかもしれません。もしあなたのチームが各コミットでDockerイメージをビルドするためにCIパイプラインを使用しているのであれば、すでに1日に何度も最新のイメージを生成し、デプロイしているかもしれません。この場合、上流の修正があなたのイメージに含まれるように、docker buildを使用する際に--pullフラグを使っていることを確認してください。
