อัปเดตคอนเทนเนอร์ของบริการใน Amazon ECS


32

วิธีใดที่แนะนำให้ใช้สำหรับการอัปเดตคอนเทนเนอร์ของบริการที่ทำงานใน Amazon ECS

เอกสาร AWSกล่าวว่า: "ถ้าคุณมีการปรับปรุงภาพหางของแอพลิเคชันของคุณคุณสามารถสร้างคำนิยามของงานใหม่ที่มีภาพที่และปรับใช้ในการให้บริการของคุณหนึ่งงานในเวลา." นี่คือทุกสิ่งที่มีอยู่ในเอกสารปัจจุบัน (13 เมษายน 2558)

ฉันเข้าใจถูกต้องหรือไม่ว่าทางเดียวที่จะอัปเดตแอปพลิเคชันคอนเทนเนอร์ของฉันใน Amazon ECS คือการสร้างงานใหม่จากนั้นหยุดงานเก่าและเริ่มงานใหม่

ฉันใช้แท็ก "ล่าสุด" สำเร็จแล้วด้วย Core OS & Fleetctl สิ่งนี้มีประโยชน์ที่ไม่จำเป็นต้องเปลี่ยนแท็กรูปภาพของนักเทียบท่าสำหรับการอัปเดตใหม่เนื่องจากการโหลดบริการใหม่จะเห็นการเปลี่ยนแปลงใหม่และอัปเดตคอนเทนเนอร์ (ใช้แท็กเดียวกัน "ล่าสุด")

คุณใช้วิธีใดในการอัปเดตบริการของคุณด้วยอิมเมจ Docker ที่อัปเดตใน Amazon ECS


ยังพยายามคิดเรื่องนี้เช่นกันเพราะเราหวังว่าจะใช้ ECS สำหรับการปรับใช้ daemons ที่หลากหลายซึ่งจำเป็นต้องทำงานอย่างต่อเนื่องในการผลิต
parent5446

1
เพื่อยืนยันคุณบอกว่าการรีสตาร์ทบริการ ecs จะดึงรูปภาพเวอร์ชันล่าสุดลงมาใช่ไหม ฉันกำลังมองหาเอกสารเกี่ยวกับเรื่องนี้และไม่สามารถหาได้ทุกที่
mmilleruva

1
การยืนยันใด ๆ ในอันนี้?
Lior Ohana

@ LiorOhana น่าเสียดายจริง ๆ ดูคำตอบของฉันสำหรับรายละเอียด
hamx0r

ฉันโพสต์คำตอบโดยละเอียดใหม่ด้านล่าง แต่เพื่อชี้แจงที่นี่: บริการของคุณจะพยายามดึงสำเนาคอนเทนเนอร์ของคุณใหม่จาก repo โดยยึดตามแท็กที่คุณตั้งไว้ หากภารกิจถูกฆ่าตายเมื่อบริการปรับใช้งานอีกครั้งจะไม่มีการจดจำสิ่งที่อยู่ใน repo เฉพาะสิ่งที่อยู่ใน repo
MrDuk

คำตอบ:


18

ไม่แน่ใจว่านี่ถือเป็นคำถามที่ถูกทอดทิ้งหรือไม่ - สะดุดสิ่งนี้ในขณะที่แก้ไขปัญหาของฉันและตอนนี้เพิ่มโซลูชันของฉันทันทีที่ได้รับการแก้ไข

หากต้องการอัปเดตบริการด้วยที่เก็บใหม่คุณต้อง:

  1. อัปโหลดคอนเทนเนอร์ใหม่ไปยังที่เก็บ;
  2. อัพเดทการกำหนดงานทริกเกอร์;
  3. อัพเดทคอนเทนเนอร์ทริกเกอร์;
  4. สำคัญ: ตรวจสอบให้แน่ใจว่ากฎการบริการอนุญาตให้เปิดใช้งานเวอร์ชันใหม่ได้

หากงานบริการไม่ได้รับการอัพเดตเป็นเวอร์ชั่นล่าสุดให้ตรวจสอบข้อผิดพลาด ตัวอย่างเช่นบางที ECS ไม่สามารถเริ่มบริการรุ่นใหม่ของคุณ: คุณมีอินสแตนซ์ ec2 เพียงหนึ่งเดียวในคลัสเตอร์และพอร์ตแอปพลิเคชันถูกใช้แล้วบนโฮสต์ ในกรณีนี้ตั้งค่าขีด จำกัด "min health / max health" เป็น "0%, 100%" - ด้วยวิธีนี้ ECS จะเลือกที่จะฆ่าคอนเทนเนอร์เก่าก่อนที่จะนำไปใช้ใหม่ สิ่งนี้กำลังเกิดขึ้นในอีกไม่กี่นาที - อย่ารีบเร่งถ้าคุณไม่เห็นความคิดเห็นทันที

ด้านล่างนี้เป็นตัวอย่างสคริปต์การปรับใช้เพื่ออัปเดตคอนเทนเนอร์ในคลัสเตอร์และบริการที่กำหนดค่าไว้ล่วงหน้า โปรดทราบว่าไม่จำเป็นต้องระบุเวอร์ชันหากคุณหมายถึง "ใช้รุ่นล่าสุดจากตระกูล"

awsRegion=us-east-1
containerName=..
containerRepository=..
taskDefinitionFile=...
taskDefinitionName=...
serviceName=...


echo 'build docker image...'
docker build -t $containerName .

echo 'upload docker image...'
docker tag $containerName:latest $containerRepository:$containerName
docker push $containerRepository:$containerName

echo 'update task definition...'
aws ecs register-task-definition --cli-input-json file://$taskDefinitionFile --region $awsRegion > /dev/null

echo 'update our service with that last task..'
aws ecs update-service --service $serviceName --task-definition $taskDefinitionName --region $awsRegion  > /dev/null

2
สิ่งนี้บังคับให้ฉันต้องนิยามภารกิจเป็นไฟล์แบบโลคัลและถ้าฉันเข้าใจอย่างถูกต้องนั่นเป็นที่เดียวที่ฉันสามารถกำหนดตัวแปรสภาพแวดล้อมได้ มีวิธีการทำเช่นนี้โดยไม่ต้องมีตัวแปรสภาพแวดล้อมในท้องถิ่นหรือไม่ เป็นการดีที่ฉันต้องการออกคำสั่งให้ชี้ไปที่แท็กอิมเมจ docker ใหม่โดยไม่ต้องส่งข้อมูลอื่น ๆ เกี่ยวกับงาน / บริการ / คอนเทนเนอร์ / ฯลฯ
rmac

1
ความคิดเห็นที่set "min health/max health" limits to "0%, 100%"เป็นสีทอง ขอบคุณมาก!
sivabudh

1
คำเตือนที่นี่หากคุณตั้งค่าminเป็น0%เมื่อคุณเปลี่ยนข้อกำหนดงานบริการของคุณปรับใช้คุณจะต้องให้สิทธิ์อย่างเต็มที่เพื่อลดภาระงานทั้งหมดในเวลาเดียวกันสำหรับการปรับใช้นั้น
MrDuk


1

ฉันใช้บางส่วนจากสคริปต์ ecs-deployด้วยการปรับปรุงของฉัน (ใช้ภาพจากทุกคำอธิบายคอนเทนเนอร์และแทนที่ส่วนแท็กด้วย $ TAG_PURE): https://gist.github.com/Forever-Young/e939d9cc41bc7a105cdcf8cd7ab9d714

# based on ecs-deploy script
TASK_DEFINITION_NAME=$(aws ecs describe-services --services $SERVICE --cluster $CLUSTER | jq -r .services[0].taskDefinition)
TASK_DEFINITION=$(aws ecs describe-task-definition --task-def "$TASK_DEFINITION_NAME" | jq '.taskDefinition')
NEW_CONTAINER_DEFINITIONS=$(echo "$TASK_DEFINITION" | jq --arg NEW_TAG $TAG_PURE 'def replace_tag: if . | test("[a-zA-Z0-9.]+/[a-zA-Z0-9]+:[a-zA-Z0-9]+") then sub("(?<s>[a-zA-Z0-9.]+/[a-zA-Z0-9]+:)[a-zA-Z0-9]+"; "\(.s)" + $NEW_TAG) else . end ; .containerDefinitions | [.[] | .+{image: .image | replace_tag}]')
TASK_DEFINITION=$(echo "$TASK_DEFINITION" | jq ".+{containerDefinitions: $NEW_CONTAINER_DEFINITIONS}")
# Default JQ filter for new task definition
NEW_DEF_JQ_FILTER="family: .family, volumes: .volumes, containerDefinitions: .containerDefinitions"
# Some options in task definition should only be included in new definition if present in
# current definition. If found in current definition, append to JQ filter.
CONDITIONAL_OPTIONS=(networkMode taskRoleArn)
for i in "${CONDITIONAL_OPTIONS[@]}"; do
  re=".*${i}.*"
  if [[ "$TASK_DEFINITION" =~ $re ]]; then
    NEW_DEF_JQ_FILTER="${NEW_DEF_JQ_FILTER}, ${i}: .${i}"
  fi
done

# Build new DEF with jq filter
NEW_DEF=$(echo $TASK_DEFINITION | jq "{${NEW_DEF_JQ_FILTER}}")
NEW_TASKDEF=`aws ecs register-task-definition --cli-input-json "$NEW_DEF" | jq -r .taskDefinition.taskDefinitionArn`

echo "New task definition registered, $NEW_TASKDEF"

aws ecs update-service --cluster $CLUSTER --service $SERVICE --task-definition "$NEW_TASKDEF" > /dev/null

echo "Service updated"

ขอแนะนำให้ให้ข้อมูลที่เป็นประโยชน์จากลิงก์ในคำตอบของคุณเพื่อจัดทำ link-rot กรุณาทำเช่นนั้นได้ไหม
BE77Y

1
อัปเดตคำตอบของฉัน
ForeverYoung

1

หลังจากอัพโหลดอิมเมจใหม่ Docker แม้ว่าจะมีแท็กเดียวกันกับที่ใช้โดยงานหนึ่งต้องคัดลอกงานล่าสุดแล้วกำหนดค่าบริการเพื่อใช้งานใหม่ อีกทางเลือกหนึ่งสามารถมีงานที่ซ้ำกันได้ 2 งานและกำหนดค่าบริการให้สลับระหว่างงานเหล่านั้นทุกครั้งที่มีการอัพเดตอิมเมจ Docker

โดยพื้นฐานแล้วเพื่อทำให้ ECS Docker Container เกิดขึ้นใหม่โดย ECS การอัปเดตบริการจะต้องเปิดใช้งานและวิธีเดียวที่จะทำให้ทริกเกอร์การบริการคือการอัปเดตในบางวิธีเช่นบอกให้ใช้งาน หมายเลขงานอื่น

โปรดทราบว่าการใช้งานบรรจุภัณฑ์ที่มีอยู่อาจไม่หยุดอัตโนมัติเพียงเพราะบริการได้รับการอัปเดต - คุณอาจต้องดูรายการงานของคุณและหยุดทำงานด้วยตนเอง


สิ่งนี้ไม่เป็นความจริง - คุณสามารถฆ่าภารกิจด้วยตนเองแทนที่จะพึ่งพาบริการของคุณเพื่อทำมัน เมื่อบริการตรวจพบว่ามันถูกฆ่าตายมันจะพยายามนำมันขึ้นมาอีกครั้งบังคับให้ดึงออกมาอีกครั้งtag
MrDuk

1

วิธีการที่เหมาะกับฉันนั้นคล้ายกับข้างบน หลังจากที่สร้างการบริการและงานของคุณและเริ่มต้นทุกอย่างไปแก้ไขAuto-Scaling กลุ่มและให้แน่ใจว่านาที , สูงสุดและต้องการมีการกำหนดให้1

กลุ่มอาจเป็นค่าเริ่มต้น ถ้าคุณไม่แน่ใจว่าแล้วคุณสามารถได้รับมันได้โดยการเลือกECS อินสแตนซ์แท็บในคลัสเตอร์ของคุณแล้วจากการกระทำแบบเลื่อนลงเลือกทรัพยากรคลัสเตอร์และคลิกลิงก์อยู่ด้านล่างของกล่องโต้ตอบที่เปิด

เมื่อนั่นคือทั้งหมดที่อยู่ในสถานที่เวลาที่คุณต้องการในการปรับใช้การปรับปรุงภาพภาชนะไปกับงานในพื้นที่ของคลัสเตอร์และหยุดงาน คุณจะได้รับคำเตือน แต่หากตั้งค่าการปรับขนาดอัตโนมัติบริการจะเริ่มต้นอีกครั้งด้วยการกดครั้งล่าสุด

ไม่จำเป็นต้องสร้างเวอร์ชันใหม่ของบริการหรืองาน

โปรดทราบว่าบริการ / งานอัปเดตตัวเองจากทุกที่ทันทีภายในไม่กี่นาที หากคุณหมดหวังที่จะรอคุณเพียงแค่เรียกใช้งานใหม่ด้วยตนเอง บริการจะไม่เป็นเจ้าของดังนั้นจึงไม่เหมาะ แต่จะยังคงหมุนบริการใหม่หากบริการเสียชีวิต


1

ฉันรู้ว่านี่เป็นเธรดเก่า แต่การแก้ปัญหานั้นง่ายกว่าคำตอบส่วนใหญ่ที่นี่ทำให้เป็น

วิธีอัปเดตคอนเทนเนอร์ที่รันอยู่ในสองขั้นตอน:

ด้านล่างจะถือว่าคุณมีบริการที่ทำงานซึ่งอ้างอิงถึงแท็กคอนเทนเนอร์latest(หรือแท็กสแตติกอื่น ๆ ที่ไม่เปลี่ยนแปลงการปรับปรุงคอนเทนเนอร์)

  1. อัปโหลดคอนเทนเนอร์ใหม่ของคุณไปยังที่เก็บ
  2. ฆ่างานของคุณด้วยตนเอง

หากเป้าหมายของเราคือการสร้างสิ่งใหม่ออกมาสู่ป่าเราไม่จำเป็นต้องพึ่งพาบริการของเราสำหรับสิ่งนั้น (และฉันขอเถียงว่าเราไม่ควรไว้ใจมัน) หากคุณฆ่างานของคุณบริการจะรับรู้ว่าไม่มีDesired Countงานที่ทำงานอยู่และเพียงแค่หมุนงานใหม่ วิธีนี้จะทริกเกอร์คอนเทนเนอร์ของคุณอีกครั้งโดยใช้แท็กเดียวกัน

บริการ ECS คือ HA ความปลอดภัยสุทธิไม่ใช่สิ่งทดแทน CD / CI ไปป์ไลน์ของคุณ


โบนัส:หากเป้าหมายคือการให้บริการรับรู้ว่ามีการผลักคอนเทนเนอร์ใหม่ (โดยไม่คำนึงถึงแท็ก) เราต้องพิจารณาความหมายของสิ่งนั้น เราต้องการบริการพื้นฐานที่ควบคุมการวางระบบของเราหรือไม่? น่าจะไม่ เป็นการดีที่คุณจะผลักภาชนะของคุณด้วยแท็กที่แตกต่างกัน (ขึ้นอยู่กับรุ่นที่วางจำหน่ายหรือบางสิ่งบางอย่าง) ในกรณีนี้อุปสรรคในการปรับใช้คือบริการจะต้องได้รับแจ้งเกี่ยวกับสิ่งใหม่ - อีกครั้งมันเป็นเครือข่ายความปลอดภัยสำหรับบริการและไม่มีอะไรเพิ่มเติม


วิธีปรับใช้แท็กใหม่ในสามขั้นตอน:

  1. อัปโหลดใหม่ของคุณcontainer:tagไปยังที่เก็บ
  2. สร้างคำนิยามภารกิจใหม่โดยอ้างอิงถึงภารกิจใหม่ tag
  3. อัปเดตบริการของคุณเพื่ออ้างอิงคำจำกัดความงานใหม่
    • ระวังที่นี่! หากคุณได้minimum healthyกำหนดให้0%เป็นคำตอบอื่น ๆ ที่แนะนำคุณจะให้สิทธิ์อย่างเต็มรูปแบบกับ AWS ในการฆ่าบริการทั้งหมดของคุณเพื่อปรับใช้ข้อกำหนดงานใหม่ หากคุณต้องการการปรับใช้แบบกลิ้ง / ทยอยให้ตั้งค่าขั้นต่ำของคุณเป็นอย่าง>0%อื่น
    • อีกทางหนึ่งคือตั้งค่าของคุณminimum healthyเป็น100%และmaximum healthyบางสิ่งบางอย่าง>100%เพื่อให้บริการของคุณสามารถปรับใช้งานใหม่ก่อนที่จะกำจัดงานเก่า (ลดผลกระทบต่อผู้ใช้ของคุณ)

จากจุดนี้บริการของคุณจะรับรู้โดยอัตโนมัติว่าคุณได้ระบุงานใหม่และดำเนินการปรับใช้ตามเกณฑ์minimum/ maximumHealthy ที่คุณได้กำหนดค่าไว้


ดีขอบคุณดีกว่าคำตอบอื่น ๆ
Olegzandr Denman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.