আমার অ্যামাজন ইসিএস কার্যগুলি তাদের ডকার চিত্রগুলি আপডেট করার জন্য সঠিক পন্থাটি কী ?
আমার অ্যামাজন ইসিএস কার্যগুলি তাদের ডকার চিত্রগুলি আপডেট করার জন্য সঠিক পন্থাটি কী ?
উত্তর:
যদি আপনার কাজটি কোনও পরিষেবার অধীনে চলছে তবে আপনি নতুন স্থাপনার জন্য বাধ্য করতে পারেন। এটি কার্য সংজ্ঞাটিকে পুনরায় মূল্যায়ন করতে এবং নতুন ধারক চিত্রটি টানতে বাধ্য করে।
aws ecs update-service --cluster <cluster name> --service <service name> --force-new-deployment
যতবারই আপনি কোনও কাজ শুরু করেন (হয় StartTask
এবং RunTask
এপিআই কলগুলির মাধ্যমে বা সেবার একটি অংশ হিসাবে এটি স্বয়ংক্রিয়ভাবে শুরু হয়ে যায়), ইসিএস এজেন্ট আপনার কার্য সংজ্ঞাতে docker pull
বর্ণিত কোনও একটি সম্পাদন করবে image
। আপনি প্রতিবার যখন আপনার রেজিস্ট্রিতে চাপ দিন একই চিত্রের নাম (ট্যাগ সহ) ব্যবহার করেন, আপনি কোনও নতুন টাস্ক চালিয়ে নতুন চিত্র চালাতে সক্ষম হবেন। মনে রাখবেন যে ডকার যদি কোনও কারণে রেজিস্ট্রিটিতে পৌঁছাতে না পারে (যেমন, নেটওয়ার্ক সমস্যা বা প্রমাণীকরণের সমস্যা), ইসিএস এজেন্ট একটি ক্যাশেড চিত্র ব্যবহার করার চেষ্টা করবে; আপনি নিজের চিত্র আপডেট করার সময় যদি ক্যাশেড চিত্রগুলি ব্যবহার করা থেকে বিরত থাকতে চান তবে আপনি প্রতিবার আপনার রেজিস্ট্রিতে একটি আলাদা ট্যাগ ঠেকাতে এবং নতুন টাস্ক চালানোর আগে যথাযথভাবে আপনার কার্য সংজ্ঞাটি আপডেট করতে চাইবেন।
আপডেট: এই আচরণটি এখন ECS_IMAGE_PULL_BEHAVIOR
ইসিএস এজেন্টে পরিবেশ পরিবর্তনশীল সেট দ্বারা সুর করা যেতে পারে set বিশদ জন্য ডকুমেন্টেশন দেখুন । লেখার সময় হিসাবে, নিম্নলিখিত সেটিংস সমর্থিত:
আপনার ধারক দৃষ্টান্তগুলির জন্য চিত্র চিত্রটি কাস্টমাইজ করতে ব্যবহৃত আচরণ। নিম্নলিখিতটি alচ্ছিক আচরণগুলি বর্ণনা করে:
যদি
default
নির্দিষ্ট করা থাকে তবে চিত্রটি দূরবর্তীভাবে টানা হয়। যদি চিত্রের টান ব্যর্থ হয় তবে কনটেইনারটি উদাহরণ হিসাবে ক্যাশেড চিত্রটি ব্যবহার করে।যদি
always
নির্দিষ্ট করা থাকে তবে চিত্রটি সর্বদা দূরবর্তীভাবে টানা হয়। যদি চিত্রের টান ব্যর্থ হয় তবে কার্যটি ব্যর্থ হয়। এই বিকল্পটি নিশ্চিত করে যে চিত্রের সর্বশেষতম সংস্করণটি সর্বদা টানা থাকে। কোনও ক্যাশেড চিত্রগুলি উপেক্ষা করা হয় এবং স্বয়ংক্রিয় ইমেজ ক্লিনআপ প্রক্রিয়া সাপেক্ষে।যদি
once
নির্দিষ্ট করা থাকে তবে চিত্রটি কেবল একই পাত্রে উদাহরণস্বরূপ পূর্ববর্তী কোনও টাস্কে টানা না থাকলে বা যদি ক্যাশেড চিত্রটি স্বয়ংক্রিয় ইমেজ ক্লিনআপ প্রক্রিয়া দ্বারা সরানো হয়েছিল তবেই কেবল দূরবর্তীভাবে টানতে হবে। অন্যথায়, উদাহরণে ক্যাশেড চিত্রটি ব্যবহৃত হয়। এটি নিশ্চিত করে যে কোনও অপ্রয়োজনীয় চিত্রের চেষ্টা করার চেষ্টা করা হয়নি।যদি
prefer-cached
নির্দিষ্ট করা থাকে তবে কোনও ক্যাশেড চিত্র না থাকলে চিত্রটি দূরবর্তীভাবে টানতে হবে is অন্যথায়, উদাহরণে ক্যাশেড চিত্রটি ব্যবহৃত হয়। ক্যাশেড চিত্রটি সরানো হয়নি তা নিশ্চিত করার জন্য ধারকটির জন্য অটোমেটেড ইমেজ ক্লিনআপ অক্ষম করা আছে।
/var/log/ecs
।
একটি নতুন টাস্ক সংজ্ঞা নিবন্ধন করা এবং নতুন টাস্ক সংজ্ঞাটি ব্যবহার করার জন্য পরিষেবাটি আপডেট করা এডাব্লুএস দ্বারা প্রস্তাবিত পদ্ধতি is এটি করার সহজতম উপায় হ'ল:
এই টিউটোরিয়ালটিতে আরও বিশদ রয়েছে এবং বর্ণনা করা হয়েছে যে উপরের পদক্ষেপগুলি কীভাবে শেষের থেকে শেষ পর্যন্ত পণ্য বিকাশ প্রক্রিয়াটির সাথে ফিট করে।
সম্পূর্ণ প্রকাশ: এই টিউটোরিয়ালটিতে বিটনামির কনটেইনার রয়েছে এবং আমি বিটনামির জন্য কাজ করি। তবে এখানে প্রকাশিত চিন্তাগুলি আমার নিজের এবং বিত্তনামীর মতামত নয়।
এই কাজটি করার দুটি পদ্ধতি আছে।
প্রথমে AWS CodeDeploy ব্যবহার করুন। আপনি ইসিএস পরিষেবা সংজ্ঞাতে নীল / সবুজ স্থাপনার বিভাগগুলি কনফিগার করতে পারেন। এর মধ্যে একটি কোডডপ্লয়রোলফোরসিইএস, স্যুইচের জন্য অন্য একটি টার্গেটগ্রুপ এবং একটি পরীক্ষা শ্রোতা (alচ্ছিক) অন্তর্ভুক্ত রয়েছে। এডাব্লুএস ইসিএস কোডডেপ্লাই অ্যাপ্লিকেশন এবং স্থাপনার গোষ্ঠী তৈরি করবে এবং এই কোডডেপ্লয় সংস্থানগুলিকে আপনার ইসিএস ক্লাস্টার / পরিষেবা এবং আপনার ELB / টার্গেটগ্রুপগুলির সাথে যুক্ত করবে। তারপরে আপনি কোনও স্থাপনা শুরুর জন্য কোডডেপ্লয় ব্যবহার করতে পারেন, যাতে আপনাকে কোনও অ্যাপসপেক প্রবেশ করতে হবে যা কোন পরিষেবা আপডেট করার জন্য কোন টাস্ক / ধারক ব্যবহার করে তা নির্দিষ্ট করে। আপনি এখানে আপনার নতুন কার্য / ধারক নির্দিষ্ট করেছেন। তারপরে, আপনি দেখতে পাবেন যে নতুন টার্গেটগ্রুপে নতুন দৃষ্টান্তগুলি ছড়িয়ে পড়েছে এবং পুরানো টার্গেটগ্রুপটি ইএলবির সাথে সংযোগ বিচ্ছিন্ন হয়ে যায় এবং শীঘ্রই পুরানো টার্গেটগ্রুপে নিবন্ধিত পুরানো দৃষ্টান্তগুলি বন্ধ হয়ে যাবে।
এটি খুব জটিল শোনায়। আসলে, যেহেতু / যদি আপনি আপনার ইসিএস পরিষেবাটিতে অটো স্কেলিং সক্ষম করে থাকেন তবে এটি করার একটি সহজ উপায় হ'ল এখানে কোনও ভদ্রলোকের মতো কনসোল বা ক্লাইটি ব্যবহার করে একটি নতুন স্থাপনাকে বাধ্য করা to
aws ecs update-service --cluster <cluster name> --service <service name> --force-new-deployment
এই পদ্ধতিতে আপনি এখনও "রোলিং আপডেট" স্থাপনার ধরণটি ব্যবহার করতে পারেন, এবং ইসিএস সহজভাবে নতুন উদাহরণগুলি স্পিন করবে এবং যদি সবকিছু ঠিক থাকে তবে আপনার পরিষেবার কোনও ডাউনটাইম ছাড়াই পুরানোগুলি নিষ্কাশন করবে। খারাপ দিকটি হ'ল আপনি মোতায়েনের উপর জরিমানা নিয়ন্ত্রণ হারিয়ে ফেলেছেন এবং কোনও ত্রুটি থাকলে আপনি আগের সংস্করণে ফিরে যেতে পারবেন না এবং এটি চলমান পরিষেবাটি ভেঙে দেবে। তবে এটি যাওয়ার একটি সহজ উপায়।
বিটিডাব্লু, 100 এবং 200 এর মতো ন্যূনতম স্বাস্থ্যকর শতাংশ এবং সর্বোচ্চ শতাংশের জন্য সঠিক সংখ্যা নির্ধারণ করতে ভুলবেন না don't
আমি ইসিএসে একটি স্টেজিং পরিষেবাতে আপডেট হওয়া ডকার ইমেজ স্থাপনের জন্য একটি স্ক্রিপ্ট তৈরি করেছি , যাতে সংশ্লিষ্ট টাস্ক সংজ্ঞাটি ডকার চিত্রের বর্তমান সংস্করণগুলিকে বোঝায়। আমি সর্বোত্তম অনুশীলনগুলি অনুসরণ করছি কিনা তা আমি নিশ্চিতভাবে জানি না, তাই প্রতিক্রিয়াটি স্বাগত জানানো হবে।
স্ক্রিপ্টটি কাজ করার জন্য আপনার একটি অতিরিক্ত ইসিএস উদাহরণ বা একটি deploymentConfiguration.minimumHealthyPercent
মান প্রয়োজন যাতে ইসিএস আপডেট হওয়া টাস্ক সংজ্ঞাটি স্থাপন করতে একটি উদাহরণ চুরি করতে পারে।
আমার অ্যালগরিদম এরকম:
আমার কোডটি নীচে আটকানো হয়েছে:
#!/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)
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
ডকার ইমেজ ট্যাগ একই ক্ষেত্রে নিম্নলিখিত ক্ষেত্রে আমার জন্য কাজ করেছে:
একই ইস্যুতে দৌড়ে। ঘন্টা ব্যয় করার পরে, আপডেট হওয়া চিত্রটির স্বয়ংক্রিয় স্থাপনার জন্য এই সরলীকৃত পদক্ষেপগুলি শেষ করেছেন:
1.ECS কার্য সংজ্ঞা পরিবর্তন: আরও ভাল বোঝার জন্য, ধরে নেওয়া যাক আপনি নীচের বিবরণ দিয়ে একটি কার্য সংজ্ঞা তৈরি করেছেন (দ্রষ্টব্য: এই সংখ্যাগুলি আপনার কার্য সংজ্ঞা অনুসারে পরিবর্তিত হবে):
launch_type = EC2
desired_count = 1
তারপরে আপনাকে নিম্নলিখিত পরিবর্তনগুলি করতে হবে:
deployment_minimum_healthy_percent = 0 //this does the trick, if not set to zero the force deployment wont happen as ECS won't allow to stop the current running task
deployment_maximum_percent = 200 //for allowing rolling update
আপনার চিত্রটিকে < আপনার চিত্র-নাম>: সর্বশেষতম হিসাবে ট্যাগ করুন । সর্বশেষতম কীটি সম্পর্কিত ইসিএস টাস্কটি টানতে যত্ন নিবে।
sudo docker build -t imageX:master . //build your image with some tag
sudo -s eval $(aws ecr get-login --no-include-email --region us-east-1) //login to ECR
sudo docker tag imageX:master <your_account_id>.dkr.ecr.us-east-1.amazonaws.com/<your-image-name>:latest //tag your image with latest tag
3. চিত্রটি ইসিআর তে চাপান
sudo docker push <your_account_id>.dkr.ecr.us-east-1.amazonaws.com/<your-image-name>:latest
4. প্রয়োগ বল প্রয়োগ-প্রয়োগ
sudo aws ecs update-service --cluster <your-cluster-name> --service <your-service-name> --force-new-deployment --region us-east-1
দ্রষ্টব্য: অঞ্চলটি আমাদের পূর্ব -১ হিসাবে ধরে নিয়ে আমি সমস্ত কমান্ড লিখেছি । প্রয়োগ করার সময় এটি কেবল আপনার নিজ অঞ্চলে প্রতিস্থাপন করুন।
এডাব্লুএস ক্লায়েন্ট ব্যবহার করে আমি উপরের পরামর্শ অনুসারে অ্যাডস এক্সস আপডেট-পরিষেবাটি চেষ্টা করেছি। ইসিআর থেকে সর্বশেষতম ডকারটি তুলেনি। শেষ পর্যন্ত, আমি আমার উত্তরীয় প্লেবুকটি পুনরায় চালু করেছি যা ইসিএস ক্লাস্টার তৈরি করেছে। Ecs_taskdefinition চললে টাস্ক সংজ্ঞাটির সংস্করণটি বিছিন্ন হয়। তাহলে সব ঠিক আছে। নতুন ডকার চিত্রটি তুলে নেওয়া হয়েছে।
সত্যিকার অর্থে নিশ্চিত নয় যে যদি টাস্ক সংস্করণ পরিবর্তন পুনরায় চালনা করতে বাধ্য করে, বা যদি ecs_service ব্যবহার করে প্লেবুকটি টাস্কটি পুনরায় লোড করার কারণ করে।
যদি কেউ আগ্রহী হন তবে আমি আমার প্লেবুকের স্যানিটাইজড সংস্করণ প্রকাশের অনুমতি পাব।
ভাল, আমি এটি করার একটি স্বয়ংক্রিয় পদ্ধতিও অনুসন্ধান করার চেষ্টা করছি, এটি ইসিআর-র পরিবর্তনের দিকে ধাক্কা দিচ্ছে এবং তারপরে সর্বশেষ ট্যাগটি পরিষেবাতে নেওয়া উচিত। ডান আপনি নিজের ক্লাস্টার থেকে আপনার পরিষেবার জন্য টাস্ক বন্ধ করে নিজেই এটি করতে পারেন। নতুন কাজগুলি আপডেট হওয়া ইসিআর পাত্রে টানবে।
নিম্নলিখিত কমান্ডগুলি আমার পক্ষে কাজ করেছিল
docker build -t <repo> .
docker push <repo>
ecs-cli compose stop
ecs-cli compose start