這篇是延伸前篇遇到的 TinyProxy 問題,所以延伸出來把 Monitor 和 Autoscaling 做完。
這篇會以 CloudWatch 為主軸,然後搭配 Autoscaling 來做到 scale-in/out,話說本來 Autoscaling 就是這樣做,只是這篇會以 Custom Metrics 的方向來實作。
實作目標:
- 把 TinyProxy 的 3128 port connection/Memory 丟到 CloudWatch,當觸發 Alarm 後開始 Auto Scaling 增減 instance。
這篇實作會用到以下服務及費用 (Tokyo):
- EC2
- 照 EC2 type 定價
- CloudWatch Dashboard
- 一個 dashboard 每月 3 美金
- CloudWatch Alarms
- 一個 Alarms 每月 0.10 美金
- CloudWatch Custom Metric
- 一個自定義 Metric 每月 0.30 美金 (適用於 10,000 個自定義 Metric 以下)
- 每 1,000 個 PutMetricData 0.01 美金
- Auto Scaling
- 不收費
**在看這篇以前,你必須要有基本的 Autoscaling 概念,不然講到 Autoscaling 和 CloudWatch 的搭配可能會有點霧煞煞。
首先你會有一台要 Publish Data 的 EC2 (TinyProxy),並且擁有 AWS CLI,以下都會透過 AWS CLI 來 Publish Data。
CloudWatch Publish Custom Metrics
先說在 AWS document 裡面就有提到 Publish Custom Metrics 作法,也有 mon-script 工具 (但只有 CPU、Memory、Disk)
Dimensions 以 Instance-Id, Inatsance-Type 的 Metrics (適合”監控記錄”)
可以參考 shazi7804/ec2-publish-metrics-cloudwatch.sh 來做到自動化。
以 Port 3128 為例,要 Publish Custom Metrics 其實超簡單,只要一行指令:
$ aws cloudwatch put-metric-data --metric-name ConnectUsage-3128 \ --namespace TinyProxy \ --unit Count \ --value $(ss|grep 3128|wc -l) \ --dimensions InstanceId=i-0123456789,InstanceType=t2.nano \ --region ap-northeast-1
簡單概要每個參數的用意,在 User Guide 有詳細定義 Amazon CloudWatch Concepts:
- –metric-name 這個 data 被定義的名稱。
- –namespace 要存在哪個 namespace,會放在 CloudWatch 的 custom namespace,不會和 AWS 原有的 namespace 混在一起,用 slash / 分隔。
- –unit 這個 data 的度量單位,這個項目 API 有詳細定義可用的值 MetricDatum。
- –value 數值,必須為”數字”,定義在 MetricDatum。
- –dimensions 資源的對象,但在這個案例我會判別為兩種 Instance、Autoscaling,如果你想用來觸發 Alarm 就要在同一個 dimensions (作為 Autoscaling alarm 不適合用動態的 dimensions,如 Instance-Id, Instance-Type)
- –region 就 Region。
Dimensions 以 AutoScalingGroupName 的 Metrics (適合 alarm Autoscaling)
可以參考 shazi7804/asg-publish-metrics-cloudwatch.sh 來做到自動化。
把 dimensions 換成 AutoScalingGroupName=asg-proxy
$ aws cloudwatch put-metric-data --metric-name ConnectUsage-3128 \ --namespace TinyProxy \ --unit Count \ --value $(ss|grep 3128|wc -l) \ --dimensions AutoScalingGroupName=asg-proxy \ --region ap-northeast-1
這樣你每個 Instance 就都會畫在同一張 Metrics,由於不會隨著 Instance 動態變更,就可以設定 CloudWatch Alarm ,透過 put-metric-alarm 來跑自動化,但如果一次性的建立 Management Console 會比較快 …
還有 Memory,一樣的用法,用 free 來取已使用的 percent,只要 value 的結果為 “數值” 就可以被接受。
$ aws cloudwatch put-metric-data --metric-name MemoryUsage \ --namespace TinyProxy \ --unit Percent \ --value $(free | grep Mem | awk '{printf(100-$4/$2*100)}') \ --dimensions AutoScalingGroupName=asg-proxy \ --region ap-northeast-1
CloudWatch Alarms
Step 1. 找到你的 Metrics
Step 2. 設定 Alarm 的水平,如果你的 AutoScaling 沒有先設好 Policy 這邊就無法透過 Actions 來指定(選不到 policy)。
Auto Scaling
建好 Alarm 之後你就可以在 Autoscaling 的 Create a simple scaling policy 選到剛剛建立的 Alarm
這樣 Autoscaling 的 Scaling Policies 就可以針對單一 Metrics 做 scale-out/in
上面兩種 Publish Custom Metrics 方式再搭配 cronjob 來實現持續畫圖
CloudWatch Dashboard
做完之後當然要用 Dashboard 來弄一個 “人看的” 來展示一下成果,Dashboard 近期也釋出 API,所以也能跑自動化了 ..
Dashboard 的顯示方式分為四種
針對這四種我的使用習慣是:
- Line 用來統計多個指標在同一張圖時用到 (可以清楚呈現很多條曲線)
- Stacked area 單一指標的起伏
- Number 只想看當下的結果 (Memory、DiskUsage … etc)
- Text 註解或標題,但蠻佔位置的。
修改任何 Dashboard 的東西都必須要按 “Save dashboard” (很常忘記阿 .. Orz)
在 Dashboard 預設是 5 min 更新一次,如果你需要頻繁的更新結果可以改為最小 1 min,當更新時間內有多筆 insert data 的話預設是取平均值 (Average),但有些狀況就不適用,要自行修改。
結語:
CloudWatch 除了上述提到的以外,還有 CloudWatch Events / Rules / Logs / Filter,CloudWatch 在 AWS 中與其他服務的串接也很緊密,還有一番功夫要研究 …