Amazon ECS’de bir servisin konteynerini güncelle


32

Amazon ECS'de çalışan bir servisin konteynerini güncellemek için ne tür bir yaklaşım önerilmektedir?

AWS belgelerine diyor: "Eğer uygulamanın Docker görüntüsünü güncellenmiş varsa, bu resmin yeni bir görev tanımı oluşturmak ve servis, her seferinde bir görev için dağıtabilir." Bu, şu anda belgelerde mevcut olan hemen hemen her şeydir (13 Nisan 2015).

Amazon ECS'de uygulama kapsayıcımı güncellemenin tek yolunun yeni bir görev oluşturmak, ardından eski görevi durdurmak ve yeni görevi başlatmak olduğunu doğru mu anladım?

Core OS & Fleetctl ile "latest" etiketini başarıyla kullanıyorum. Bu hizmetin yeniden yüklenmesi yeni değişiklikler görecek ve kabı ("en yeni" etiketini kullanarak) kullanacağından, yeni güncellemeler için Docker resminin etiketini değiştirmeye gerek kalmaması avantajına sahiptir.

Amazon ECS'de hizmetinizi güncellenmiş liman işçisi görüntüsü ile güncellemek için ne tür yaklaşımlar kullandınız?


Ayrıca, ECS'yi üretimde sürekli olarak çalışması gereken çeşitli cemaatleri dağıtmak için kullanmayı umduğumuzdan da anlamaya çalışıyoruz.
parent5446

1
Sadece onaylamak için, bir ecs servisini yeniden başlatmanın görüntünün en son sürümünü aşağı çekeceğini söylemiştiniz. Bununla ilgili belgeleri aradım ve hiçbir yerde bulamadım.
mmilleruva

1
Bu konuda bir onay var mı?
Lior Ohana

@LiorOhana Ne yazık ki doğru. Ayrıntılar için cevabımı gör.
hamx0r

Aşağıda yeni ve ayrıntılı bir yanıt gönderdim, ancak burada açıklığa kavuşturmak için: Hizmetiniz, belirlediğiniz etikete bağlı olarak her zaman konteynerinizin yeni bir kopyasını depodan çekmeye çalışacaktır. Bir görev ölürse hizmet yeniden dağıtır zaman, ne hiç hatırlamadı oldu , yalnızca ne repo olan repo.
MrDuk

Yanıtlar:


18

Bunun terk edilmiş bir soru olarak kabul edilip edilmediğinden emin değilim - sorunumu giderirken buna tökezledi ve şimdi çözümüme çözüm getirildi.

Hizmeti yeni konteynerle güncellemek için yapmanız gerekenler:

  1. depoya yeni konteyner yükleyin;
  2. görev tanımı güncellemesini tetikleyin;
  3. konteyner güncellemesini tetikleyin;
  4. Önemli: Servis kurallarının, görevin yeni sürümünün başlatılmasına izin verdiğinden emin olun.

Servis görevi en son sürüme güncellenmemişse, hatalar için "olaylar" sekmesine bakın. Örneğin, ECS hizmetinizin yeni sürümünü başlatamadı: kümede yalnızca bir ec2 örneği var ve uygulama bağlantı noktası zaten ana bilgisayarda kullanılıyor. Bu durumda, "minimum sağlık / maksimum sağlık" sınırlarını "% 0,% 100" olarak ayarlayın - bu şekilde, ECS yenisini dağıtmadan önce eski kabı öldürmeyi seçecektir. Bu aynı zamanda birkaç dakikalık bir süreçte gerçekleşiyor - acil bir geri bildirim görmüyorsanız acele etmeyin.

Aşağıda, önceden yapılandırılmış bir kümede ve hizmette kapsayıcıyı güncellemek için örnek bir dağıtım komut dosyası verilmiştir. Not: Eğer sadece "aileden en son kullanımı" demek istiyorsan, versiyonları belirtmeye gerek yok.

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
Bu beni yerel olarak bir dosya olarak görev tanımlamaya zorlar ve doğru anlarsam, ortam değişkenlerini tanımlayabildiğim tek yer orasıdır. Yerel olarak çevre değişkenleri olmadan bunu yapmanın bir yolu var mı? İdeal olarak görev / servis / container / etc hakkında başka bir bilgi göndermeden yeni bir liman işçisi resim etiketine işaret etmek için bir komut vermek istiyorum.
rmac

1
Üzerine yorumlar set "min health/max health" limits to "0%, 100%"altındır. Çok teşekkür ederim!
sivabudh

1
Burada Uyarı, sen senin ayarlarsanız miniçin 0%Görev tanımına servis dağıtır değiştirdiğinizde, aslında çökertmek için o tam yetki veriyoruz hepsi bu dağıtım için aynı anda görevleri.
MrDuk


1

Geliştirmelerimde ecs-deploy betiğinin bir kısmını kullanıyorum (her kap tanımından görüntüler alıyor ve etiket bölümünü $ TAG_PURE ile değiştiriyor): 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 sağlamak için cevabınızdaki linklerden faydalı bilgiler sağlamanız önerilir. Lütfen yapabilir misiniz?
BE77Y

1
Cevabımı güncelledi
ForeverYoung

1

Yeni bir Docker resmi yükledikten sonra, Görev tarafından kullanılanla aynı etikete sahip olsa bile, kişi en yeni görevi kopyalamalı ve ardından Hizmeti bu yeni Görevi kullanacak şekilde yapılandırmalıdır. İsteğe bağlı olarak, bir kişi 2 yinelenen göreve sahip olabilir ve Hizmeti, Docker Image her güncellendiğinde aralarında değişecek şekilde yapılandırabilir.

Temel olarak, ECS tarafından yeni bir Docker Konteyneri yapılmasına neden olmak için, Servis güncellemesi onu tetiklemelidir ve Servis'i tetiklemenin tek yolu, bir şekilde kullanmasını söyleyerek olduğu gibi bir şekilde Güncellemektir. farklı görev numarası.

Mevcut çalışan Konteynerlerin yalnızca Hizmet güncellendiğinden otomatik olarak durmayabileceğini unutmayın; Görevler listenize bakmanız ve bunları el ile durdurmanız gerekebilir.


Bu aslında doğru değil - yapmak için hizmetinize güvenmek yerine her zaman bir görevi el ile öldürebilirsiniz. Servis öldürüldüğünü tespit ettiğinde, tekrar gündeme getirmeye çalışacak, aynı şeyi tekrar çekmeye zorlayacaktag
MrDuk

1

Benim için çalışan yaklaşım yukarıdakilere benzer. Hizmetinizi ve görevinizi oluşturduktan ve her şeyi yapmaya başladıktan sonra, Otomatik Ölçeklendirme Grubunu düzenleyin ve min , maks ve istenen değerlerin 1 olarak ayarlandığından emin olun .

Grup varsayılan grup olabilir; Emin değilseniz kümenizdeki ECS Örnekleri sekmesini seçerek elde edebilirsiniz , ardından Eylemler açılır listesinden Küme Kaynakları'nı seçin ve açılan iletişim kutusunun altındaki bağlantıyı tıklayın.

Hepsi yerinde olduğunda, istediğiniz zaman için güncelleştirilmiş konteyner görüntü gitmek dağıtmak için Görev küme ve alanında Durdur görevi . Bir uyarı alırsınız, ancak otomatik ölçeklendirme ayarlanmışsa, servis en son basışta tekrar çalışmaya başlayacaktır.

Hizmetin veya görevin yeni sürümlerini oluşturmanıza gerek yok.

Hizmetin / görevin kendilerini bir dakikadan kısa bir süre içinde anında herhangi bir yere güncellediğini unutmayın. Bekleyen bir umutla karşılaşırsanız, sadece Yeni Görevi manuel olarak çalıştırın. Hizmetin sahibi olmayacak, bu yüzden ideal değil, ama ölürse yeni bir tane daha açacak.


1

Bunun eski bir konu olduğunu biliyorum, ancak çözüm buradaki cevapların çoğundan daha kolay.

Çalışan konteyner nasıl iki adımda güncellenir:

Aşağıda, etiketli bir kaba latest(ya da konteyner güncellemelerinde değişiklik göstermeyen başka bir statik etikete) değinen bir görevi çalıştıran bir hizmetiniz olduğu varsayılmaktadır .

  1. Yeni konteynerinizi depoya yükleyin
  2. Görevlerinizi manuel olarak öldürün

Eğer hedef vahşi doğada yeni bir yapı kazanmamız için ise, bunun için hizmetimize güvenmemize gerek yok (ve tartışmalıyım, buna güvenmemeliyiz). Görevinizi öldürürseniz, hizmetin Desired Countçalışan görevleri olmadığını ve yalnızca yenisini açacağını anlar . Bu, aynı etikete göre kabınızın yeniden çekilmesini tetikler.

ECS hizmetleri, HA güvenlik ağıdır, CD / CI boru hattınızın yerine geçmez .


Bonus: Eğer amaç bir servisin yeni bir konteynerin ittiğini (etiketlerden bağımsız olarak) tanımaksa, bunun sonuçlarını düşünmemiz gerekir. Dağıtım hattımızı bizim için kontrol eden temel bir hizmet istiyor muyuz? Muhtemelen hayır. İdeal olarak, kaplarınızı farklı etiketlerle (sürüm sürümlerine veya benzeri şeylere dayanarak) iteceksiniz. Bu durumda, konuşlandırmanın önündeki engel, hizmetin yeni bir şeyden haberdar edilmesi gerektiğidir - tekrar, bu hizmet için bir güvenlik ağıdır ve başka bir şey yoktur.


Yeni etiketler üç adımda nasıl dağıtılır:

  1. Yenisini container:tagdepoya yükle
  2. Yenisini referans alan yeni bir görev tanımı oluşturun tag
  3. Yeni görev tanımına referans vermek için hizmetinizi güncelleyin
    • Burada dikkatli ol! Eğer varsa minimum healthyayarlı 0%diğer bazı cevaplar önerdiği gibi, sen aws yeni bir görev tanımı dağıtmak amacıyla tüm hizmet öldürmek için tam yetki veriyoruz. Yuvarlanma / kademeli dağıtımı tercih ediyorsanız, minimum seviyenizi bir şeye ayarlayın >0%.
    • Alternatif olarak, senin ayarlamak minimum healthyiçin 100%ve sizin maximum healthybir şey için >100%servis dağıtmak için izin yeni (kullanıcılarınıza etkisini en aza indirmek) eskileri kapalı öldürmeden önce görevleri.

Bu noktadan itibaren, servisiniz yeni bir görev belirlediğinizi otomatik olarak tanır ve yapılandırdığınız minimum/ maximumsağlıklı eşikleri temel alarak bunu dağıtmaya çalışır .


güzel, teşekkürler, diğer cevaplardan daha iyi
Olegzandr Denman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.