Cập nhật vùng chứa dịch vụ trong Amazon ECS


32

Cách tiếp cận nào được khuyến nghị để cập nhật vùng chứa dịch vụ đang chạy trong Amazon ECS?

Các tài liệu AWS nói: "Nếu bạn đã cập nhật hình ảnh Docker của ứng dụng của bạn, bạn có thể tạo ra một định nghĩa nhiệm vụ mới với hình ảnh đó và triển khai nó đến dịch vụ của bạn, một trong những nhiệm vụ tại một thời điểm." Đây là khá nhiều thứ hiện có trong tài liệu hiện tại (ngày 13 tháng 4 năm 2015).

Tôi có hiểu chính xác không, rằng cách duy nhất để cập nhật vùng chứa ứng dụng của tôi trong Amazon ECS là tạo một tác vụ mới, sau đó dừng tác vụ cũ và bắt đầu tác vụ mới?

Tôi đã sử dụng thành công thẻ "mới nhất" với Core OS & Fleetctl. Điều này có lợi ích là không cần thay đổi thẻ hình ảnh Docker cho các bản cập nhật mới, vì tải lại dịch vụ sẽ thấy các thay đổi mới và cập nhật vùng chứa (sử dụng cùng một thẻ "mới nhất").

Những cách tiếp cận nào bạn đã sử dụng để cập nhật dịch vụ của mình với hình ảnh docker được cập nhật trong Amazon ECS?


Cũng cố gắng tìm ra điều này, vì chúng tôi hy vọng sẽ sử dụng ECS ​​để triển khai nhiều loại daemon cần chạy liên tục trong sản xuất.
cha mẹ5446

1
Chỉ cần xác nhận, bạn nói rằng khởi động lại một dịch vụ ecs sẽ kéo xuống phiên bản mới nhất của hình ảnh? Tôi đã tìm tài liệu về điều này và không thể tìm thấy nó ở bất cứ đâu.
mmilleruva

1
Bất kỳ xác nhận về điều này?
Lior Ohana

@LiorOhana Thật đáng buồn. Xem câu trả lời của tôi để biết chi tiết.
hamx0r

Tôi đã đăng một câu trả lời chi tiết mới bên dưới, nhưng để làm rõ ở đây: Dịch vụ của bạn sẽ luôn cố gắng lấy một bản sao mới của container của bạn từ repo, dựa trên thẻ bạn đã đặt. Nếu một nhiệm vụ là giết, khi dịch vụ triển khai nó một lần nữa, nó không có hồi ức về những gì trong repo, chỉ những gì trong repo.
MrDuk 23/03/18

Câu trả lời:


18

Không chắc chắn nếu đây được coi là câu hỏi bị bỏ rơi - vấp phải điều này trong khi khắc phục sự cố của tôi và bây giờ thêm giải pháp của tôi bây giờ nó đã được giải quyết.

Để cập nhật dịch vụ với container mới, bạn cần:

  1. tải container mới lên kho lưu trữ;
  2. kích hoạt cập nhật định nghĩa nhiệm vụ;
  3. kích hoạt cập nhật container;
  4. quan trọng: đảm bảo quy tắc dịch vụ cho phép khởi chạy phiên bản mới của tác vụ.

Nếu tác vụ dịch vụ không được cập nhật lên phiên bản mới nhất, hãy kiểm tra tab "sự kiện" để biết lỗi. Ví dụ: có thể ECS không thể khởi động phiên bản dịch vụ mới của bạn: bạn chỉ có một phiên bản ec2 trong cụm và cổng ứng dụng đã được sử dụng trên máy chủ. Trong trường hợp này, đặt giới hạn "tối thiểu sức khỏe / sức khỏe tối đa" thành "0%, 100%" - theo cách này, ECS sẽ chọn tiêu diệt container cũ trước khi triển khai cái mới. Điều này cũng xảy ra trong vài phút - đừng vội vàng nếu bạn không thấy phản hồi ngay lập tức.

Dưới đây là một kịch bản triển khai ví dụ để cập nhật vùng chứa trong cụm và dịch vụ được cấu hình sẵn. Lưu ý không cần chỉ định phiên bản nếu bạn chỉ có nghĩa là "sử dụng mới nhất từ ​​gia đình".

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
Điều này buộc tôi phải có một định nghĩa nhiệm vụ như một tệp cục bộ và nếu tôi hiểu chính xác, đó là nơi duy nhất tôi có thể xác định các biến môi trường. Có cách nào để làm điều này mà không có các biến môi trường cục bộ không? Lý tưởng nhất là tôi muốn đưa ra một lệnh để trỏ đến thẻ hình ảnh docker mới mà không gửi bất kỳ thông tin nào khác về tác vụ / dịch vụ / container / vv.
rmac

1
Các ý kiến ​​trên set "min health/max health" limits to "0%, 100%"là vàng. Cảm ơn bạn rất nhiều!
sivabudh

1
Lời cảnh báo ở đây, nếu bạn thiết lập minđể 0%, khi bạn thay đổi định nghĩa nhiệm vụ triển khai dịch vụ của bạn, bạn đang chủ yếu cho nó toàn quyền để đưa xuống tất cả các nhiệm vụ cùng lúc cho việc triển khai đó.
MrDuk


1

Tôi sử dụng một số phần từ tập lệnh triển khai ecs với các cải tiến của mình (nó lấy hình ảnh từ mỗi mô tả vùng chứa và thay thế phần thẻ của nó bằng $ 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"

Bạn nên cung cấp thông tin hữu ích từ các liên kết trong câu trả lời của mình để cung cấp liên kết. Bạn có thể làm như vậy, xin vui lòng?
BE77Y

1
Đã cập nhật câu trả lời của tôi
ForeverYoung

1

Sau khi tải lên hình ảnh Docker mới, ngay cả khi nó có cùng thẻ với một tác vụ được sử dụng bởi một Tác vụ, người ta phải sao chép tác vụ mới nhất và sau đó định cấu hình Dịch vụ để sử dụng Tác vụ mới đó. Tùy chọn, người ta có thể chỉ cần có 2 tác vụ trùng lặp và định cấu hình Dịch vụ để trao đổi giữa chúng mỗi khi Cập nhật hình ảnh Docker.

Về cơ bản, để khiến cho Docker Container mới được ECS tạo ra, một bản cập nhật cho Dịch vụ phải kích hoạt nó và cách duy nhất để kích hoạt Dịch vụ là cập nhật theo cách nào đó - như bằng cách bảo nó sử dụng số nhiệm vụ khác nhau.

Lưu ý rằng các Container đang chạy có thể không tự động dừng chỉ vì Dịch vụ đã được cập nhật - bạn có thể cần xem danh sách Nhiệm vụ của mình và dừng chúng theo cách thủ công.


Điều này thực sự không đúng - bạn luôn có thể tự hủy một tác vụ thay vì dựa vào dịch vụ của mình để thực hiện. Khi dịch vụ phát hiện ra nó đã bị giết, nó sẽ cố gắng đưa nó trở lại, buộc phải rút lại tương tựtag
MrDuk 23/03/18

1

Cách tiếp cận phù hợp với tôi tương tự như trên. Sau khi tạo dịch vụ và tác vụ của bạn và bắt đầu mọi thứ diễn ra, hãy chỉnh sửa Nhóm tự động nhân rộng và đảm bảo tối thiểu , tối đamong muốn được đặt thành 1 .

Nhóm có thể là nhóm mặc định; nếu bạn không chắc chắn thì bạn có thể truy cập nó bằng cách chọn tab ECS Instances trong cụm của bạn, sau đó từ menu thả xuống Hành động chọn Tài nguyên cụm và nhấp vào liên kết gần dưới cùng của hộp thoại mở ra.

Khi tất cả đã sẵn sàng, bất cứ khi nào bạn muốn triển khai một hình ảnh container được cập nhật, hãy đến khu vực Nhiệm vụ của cụm và Dừng nhiệm vụ . Bạn sẽ nhận được cảnh báo, nhưng với điều kiện tự động mở rộng quy mô, dịch vụ sẽ bắt đầu hoạt động trở lại với lần đẩy mới nhất.

Không cần phải tạo phiên bản mới của dịch vụ hoặc tác vụ.

Lưu ý rằng dịch vụ / tác vụ tự cập nhật mọi nơi từ ngay lập tức đến trong vòng một phút hoặc lâu hơn. Nếu bạn tuyệt vọng chờ đợi, bạn có thể chạy Nhiệm vụ mới theo cách thủ công. Dịch vụ sẽ không sở hữu nó, vì vậy nó không lý tưởng, nhưng nó vẫn sẽ quay lại một dịch vụ mới nếu nó chết.


1

Tôi biết đây là một chủ đề cũ, nhưng giải pháp dễ dàng hơn nhiều so với hầu hết các câu trả lời ở đây đưa ra.

Cách cập nhật container đang chạy theo hai bước:

Dưới đây giả sử bạn có một dịch vụ đang chạy một tác vụ đang tham chiếu một vùng chứa được gắn thẻ latest(hoặc bất kỳ thẻ tĩnh nào khác không thay đổi qua các cập nhật của vùng chứa).

  1. Tải lên container mới của bạn vào kho lưu trữ
  2. Giết thủ công nhiệm vụ của bạn

Nếu mục tiêu là để chúng tôi xây dựng một công trình mới, chúng tôi không thực sự cần phải dựa vào dịch vụ của mình cho điều đó (và tôi tranh luận, chúng tôi không nên dựa vào nó). Nếu bạn giết nhiệm vụ của mình, dịch vụ sẽ nhận ra nó không có các Desired Counttác vụ đang chạy và chỉ cần quay một nhiệm vụ mới. Điều này sẽ kích hoạt việc kéo lại container của bạn, dựa trên cùng một thẻ.

Các dịch vụ ECS là mạng bảo mật HA, không phải là sự thay thế cho đường ống CD / CI của bạn.


Tiền thưởng: Nếu mục tiêu là để một dịch vụ nhận ra một container mới đã được đẩy (bất kể thẻ nào), chúng ta cần xem xét ý nghĩa của việc đó. Chúng ta có thực sự muốn một dịch vụ cơ bản kiểm soát đường ống triển khai cho chúng ta không? Có khả năng là không. Lý tưởng nhất là bạn sẽ đẩy các thùng chứa của mình bằng các thẻ khác nhau (dựa trên các phiên bản phát hành hoặc thứ gì đó). Trong trường hợp này, rào cản đối với việc triển khai là dịch vụ phải được thông báo về một điều mới - một lần nữa, đó là mạng lưới an toàn cho dịch vụ và không có gì nữa.


Cách triển khai thẻ mới theo ba bước:

  1. Tải mới của bạn lên container:tagkho lưu trữ
  2. Tạo một định nghĩa nhiệm vụ mới tham chiếu cái mới tag
  3. Cập nhật dịch vụ của bạn để tham khảo định nghĩa nhiệm vụ mới
    • Cẩn thận đây! Nếu bạn đã minimum healthyđặt thành 0%một số câu trả lời khác, bạn sẽ trao cho AWS toàn quyền giết toàn bộ dịch vụ của bạn để triển khai định nghĩa nhiệm vụ mới. Nếu bạn thích triển khai lăn / dần dần, hãy đặt mức tối thiểu của bạn thành thứ gì đó >0%.
    • Ngoài ra, thiết lập của bạn minimum healthyđể 100%và bạn maximum healthyđến một cái gì đó >100%để cho phép dịch vụ của bạn để triển khai mới các nhiệm vụ trước khi tiêu diệt hết những cái cũ (giảm thiểu tác động đến người dùng của bạn).

Từ thời điểm này, dịch vụ của bạn sẽ tự động nhận ra bạn đã chỉ định một tác vụ mới và triển khai triển khai dựa trên ngưỡng minimum/ maximumlành mạnh mà bạn đã định cấu hình.


tốt, cảm ơn, tốt hơn so với các câu trả lời khác
Olegzandr Denman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.