[解決済み] 更新されたDockerイメージをAmazon ECSタスクにデプロイするにはどうすればよいですか?
2022-04-24 03:11:56
質問
を作るには、どのような方法がありますか? アマゾンECS タスクがDockerイメージを更新した後、そのイメージが対応するレジストリで更新されますか?
解決方法は?
私が作成した スクリプト 更新されたDockerイメージをECS上のステージングサービスにデプロイするために、対応するタスク定義がDockerイメージの現在のバージョンを参照するようにします。ベストプラクティスに沿っているかどうか確かではないので、フィードバックは歓迎します。
このスクリプトを動作させるためには、予備のECSインスタンスまたは
deploymentConfiguration.minimumHealthyPercent
の値を変更し、ECS が更新されたタスク定義をデプロイするためのインスタンスを取得できるようにします。
私のアルゴリズムはこんな感じです。
- タスク定義にあるコンテナに対応するDockerイメージにGitリビジョンのタグを付ける。
- Dockerイメージのタグを対応するレジストリにプッシュします。
- タスク定義ファミリーの古いタスク定義を登録解除する。
- 新しいタスク定義を登録し、現在の Git リビジョンでタグ付けされた Docker イメージを参照するようにしました。
- 新しいタスク定義を使用するようにサービスを更新します。
私のコードを以下に貼り付けます。
デプロイメント・エックス
#!/usr/bin/env python3
import subprocess
import sys
import os.path
import json
import re
import argparse
import tempfile
_root_dir = os.path.abspath(os.path.normpath(os.path.dirname(__file__)))
sys.path.insert(0, _root_dir)
from _common import *
def _run_ecs_command(args):
run_command(['aws', 'ecs', ] + args)
def _get_ecs_output(args):
return json.loads(run_command(['aws', 'ecs', ] + args, return_stdout=True))
def _tag_image(tag, qualified_image_name, purge):
log_info('Tagging image \'{}\' as \'{}\'...'.format(
qualified_image_name, tag))
log_info('Pulling image from registry in order to tag...')
run_command(
['docker', 'pull', qualified_image_name], capture_stdout=False)
run_command(['docker', 'tag', '-f', qualified_image_name, '{}:{}'.format(
qualified_image_name, tag), ])
log_info('Pushing image tag to registry...')
run_command(['docker', 'push', '{}:{}'.format(
qualified_image_name, tag), ], capture_stdout=False)
if purge:
log_info('Deleting pulled image...')
run_command(
['docker', 'rmi', '{}:latest'.format(qualified_image_name), ])
run_command(
['docker', 'rmi', '{}:{}'.format(qualified_image_name, tag), ])
def _register_task_definition(task_definition_fpath, purge):
with open(task_definition_fpath, 'rt') as f:
task_definition = json.loads(f.read())
task_family = task_definition['family']
tag = run_command([
'git', 'rev-parse', '--short', 'HEAD', ], return_stdout=True).strip()
for container_def in task_definition['containerDefinitions']:
image_name = container_def['image']
_tag_image(tag, image_name, purge)
container_def['image'] = '{}:{}'.format(image_name, tag)
log_info('Finding existing task definitions of family \'{}\'...'.format(
task_family
))
existing_task_definitions = _get_ecs_output(['list-task-definitions', ])[
'taskDefinitionArns']
for existing_task_definition in [
td for td in existing_task_definitions if re.match(
r'arn:aws:ecs+:[^:]+:[^:]+:task-definition/{}:\d+'.format(
task_family),
td)]:
log_info('Deregistering task definition \'{}\'...'.format(
existing_task_definition))
_run_ecs_command([
'deregister-task-definition', '--task-definition',
existing_task_definition, ])
with tempfile.NamedTemporaryFile(mode='wt', suffix='.json') as f:
task_def_str = json.dumps(task_definition)
f.write(task_def_str)
f.flush()
log_info('Registering task definition...')
result = _get_ecs_output([
'register-task-definition',
'--cli-input-json', 'file://{}'.format(f.name),
])
return '{}:{}'.format(task_family, result['taskDefinition']['revision'])
def _update_service(service_fpath, task_def_name):
with open(service_fpath, 'rt') as f:
service_config = json.loads(f.read())
services = _get_ecs_output(['list-services', ])[
'serviceArns']
for service in [s for s in services if re.match(
r'arn:aws:ecs:[^:]+:[^:]+:service/{}'.format(
service_config['serviceName']),
s
)]:
log_info('Updating service with new task definition...')
_run_ecs_command([
'update-service', '--service', service,
'--task-definition', task_def_name,
])
parser = argparse.ArgumentParser(
description="""Deploy latest Docker image to staging server.
The task definition file is used as the task definition, whereas
the service file is used to configure the service.
""")
parser.add_argument(
'task_definition_file', help='Your task definition JSON file')
parser.add_argument('service_file', help='Your service JSON file')
parser.add_argument(
'--purge_image', action='store_true', default=False,
help='Purge Docker image after tagging?')
args = parser.parse_args()
task_definition_file = os.path.abspath(args.task_definition_file)
service_file = os.path.abspath(args.service_file)
os.chdir(_root_dir)
task_def_name = _register_task_definition(
task_definition_file, args.purge_image)
_update_service(service_file, task_def_name)
_common.py
import sys
import subprocess
__all__ = ['log_info', 'handle_error', 'run_command', ]
def log_info(msg):
sys.stdout.write('* {}\n'.format(msg))
sys.stdout.flush()
def handle_error(msg):
sys.stderr.write('* {}\n'.format(msg))
sys.exit(1)
def run_command(
command, ignore_error=False, return_stdout=False, capture_stdout=True):
if not isinstance(command, (list, tuple)):
command = [command, ]
command_str = ' '.join(command)
log_info('Running command {}'.format(command_str))
try:
if capture_stdout:
stdout = subprocess.check_output(command)
else:
subprocess.check_call(command)
stdout = None
except subprocess.CalledProcessError as err:
if not ignore_error:
handle_error('Command failed: {}'.format(err))
else:
return stdout.decode() if return_stdout else None
関連
-
DockerRegistryV2 イメージの削除
-
[解決済み] Dockerコンテナの中から、マシンのローカルホストに接続するにはどうすればよいですか?
-
[解決済み] ホストからDockerコンテナにファイルをコピーする方法は?
-
[解決済み] リポジトリを使用せずに、あるホストから別のホストにDockerイメージをコピーする方法
-
[解決済み] ホストからDockerコンテナのIPアドレスを取得する方法
-
[解決済み] Dockerコンテナのシェルに入るにはどうしたらいいですか?
-
[解決済み] 古いDockerコンテナを削除する方法
-
[解決済み] 古くて使われていないDockerイメージを削除する方法
-
[解決済み] Dockerイメージの削除方法について教えてください。
-
[解決済み】Dockerは仮想マシンとどう違うの?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Docker: apt-utilsのインストールに問題があります。
-
[解決済み] 「docker build" は正確に1つの引数を必要とします。
-
[解決済み] Ansibleタスクのタイムアウトの最大長
-
[解決済み] Docker - コンテナが実行されていません
-
[解決済み] Docker - デーモンからのエラー応答:クライアントはサーバーよりも新しいです。
-
[解決済み] ドッカーコンテナの終了ステータス255は何を意味するのですか?
-
Docker npm getaddrinfo EAI_AGAIN registry.npmjs.org registry.npmjs.org:443
-
docker上で動作するphpからmysqlへの接続の解決策、表示(HY000/2002)。接続が拒否されました
-
dockerでgitlabをインストールする際にパーミッションの例外が発生する
-
docker-composeはmysqlをボリュームでデプロイする際のパーミッション拒否の問題を解決します。