今天來介紹 ECS 的 deployment~
ECS 預設的 deployment 方式是 Rolling Update,中文稱為「滾動式更新」,是不斷將現有 container 替換成新版本 container 的機制。這個機制可以做到 zero downtime 的 deployment。
Rolling Update 需要 Load Balancer 做流量的切換:開啟新的 container 後要把流量導到新的 container,停止送 request 給舊 container 並等舊 container 消化完正在處理的 request。
等舊 container 消化 request 的過程稱為 draining(排水),draining 的時間可以在 ALB 的 target group 設定,具體要設定多少則要看實際 request 的最大時間多長。
在 rolling update 中,有兩個 ECS service 參數會影響 deployment 的過程:minimumHealthyPercent 以及 maximumPercent 。
task desired count * maximumPercent
取最接近的較小整數值是 deployment 期間處在 RUNNING
跟 PENDING
的 task 的數量的最大值。假設 task desired count 設 3,maximumPercent 設 200,最大的 RUNNING 與 PENDING 的 task 數量是 3 * 200% = 6。
如果 desired count 是 2,而 maximumPercent 設 150,那麼 deployment 一開始的時候只會先多生一個新的 task(2 * 150% = 3),等到其中一個舊 task 停止後,才會再產生一個新的 task。
task desired count * minimumHealthyPercent
取最接近的較大整數值是 deployment 期間必須維持 RUNNING 的 task 最小數量。設定這個值可以確保 deployment 期間 ECS service 是有 task 運作,讓 service 不會中斷、沒有 downtime。假設 desired count
設 3,minimumHealthyPercent
設 100,在 deployment 期間就會維持至少 3 個 running task。
另外這個設定也讓 deployment 可以不使用額外的資源就能 deploy。例如把 minimumHealthyPercent 設為 50、desired count 設為 4,deployment 會先關掉 2 個舊的關掉,再利用釋放出來的 resource 去 deployment 新的 task。當然這麼做的話 service 會有短暫的時間能處理的 request 量會下降。
用兩個例子來說明 ECS deploy 過程跟兩個參數的影響。第一個例子的 desired task 數量是 2、minimumHealthyPercent 設為 100、maximumPercent 是 200。
開始 deploy 的時候因為 max 是 200,pending + running 的 task 最大數量是 2 * 200% = 4,所以可以啟動兩個新的 task,一開始它們會是 pending 狀態。v2 的 task 變成 running 後,ECS 會把 v1 的 task 變成 draining 狀態,準備移除它。draining 就是等 task 身上的 request 通通處理完畢,ALB 不會再把 request 傳給 draining 的 task,所以只要等目前的 request 處理完畢就能關閉 task。最後留下兩個新版本的 running task,deploy 完畢。
第二個比較複雜的例子,這個例子的 desired task 數量是 2、minimumHealthyPercent 設為 100、maximumPercent 則是 150。
現在 max 是 150,pending + running 最多可以有 2 * 150% = 3 個。開始 deploy 時先啟動一個 v2 task,等它到 running 時讓一個 v1 task 進入 draining。draining 的 v1 task 停止後,會有一個 v1 跟一個 v2 的 running task,這時候再啟動一個 v2 task。第二個 v2 task 進入 running 後,再讓 v1 task 進入 draining。等到 v1 task 停止後,剩下兩個 v2 running task,完成 deploy。
這樣的 deploy 過程比較長,但是可以使用比較少的 infrastructure 資源進行 deploy。同時運作的 task 最多只會有 3 個,所以可以用比較小台或比較少台機器跑 ECS service 的 task 們。
rolling update deployment 的過程中,會有一段時間是新舊 task 同時存在的。雖然 service 是 zero downtime,但如果新舊版有相容性問題,application 還是可能在 deployment 過程中發生錯誤。
例如一個前後端分離的架構,backend 是 ECS service、frontend 是架設在 S3 的 SPA(single page application)。ECS service 跟 s3 的 deployment 彼此是獨立的,可能發生 frontend 已經是 v2,但依然有 task 是 v1。如果 v2 的 frontend 使用 v2 才有的 backend API,request 被導到 v1 的 task 就會出錯。
要處理 deployment 過程中新舊版相容性的問題,需要使用另一種 deploy 模式:Blue/Green deployment。