在 Amazon VPC 的架構裡最讓人碎碎唸的一個架構:NAT instance。
Amazon VPC 分成 Public Network 與 Private Network。
前者的 Public Network,裡面的機器除了會有 Private IP 外,需要申請 Public IP (可以是隨機分配,也可以是 Elastic IP) 透過 Intenet Gateway (沒有 NAT 功能) 連外,這邊問題比較小,因為 Routing Table 設一下就好了,High Availability 以及 Scalablility 的問題 AWS 會自己解決掉。
後者 Private Network 因為需要自己架設 NAT instance,所以要自己處理 High Availability 以及 Scalability 問題,由於把機器丟在後面,前面用 ELB 是蠻常見的架構,AWS 一直沒推出 NAT service 讓人感覺很疑惑...
目前一般在處理 Private Network 的 HA NAT 架構是參考「 High Availability for Amazon VPC NAT Instances: An Example 」這篇文章,但這篇文章的作法有點複雜。
我可以接受有一些 downtime 時間以及一些小狀況,相對的,我想要換取極低的管理成本。
研究了一陣子,最後決定的作法是受到「 An Alternative Approach to “HA” NAT on AWS 」這篇的啟發,這篇也只講了很簡單的概念,實際上還是要自己研究。
目前是做在 us-west-2 (Oregon) 的 1b 與 1c 兩個 AZ 上。下面討論時就不說明這點了。
規劃的想法是 1b 與 1c 兩個 AZ 各建立一個 auto scaling group,透過 auto scaling 各跑一台 NAT instance 處理自己 AZ 的 NAT traffic (所以不是手動跑)。然後我不想要自己建 image 寫太多 hard code 進去,最好是現成的用一用就好 XD
所以有幾個重點:
http://169.254.169.254/
上取得對應的 IAM Role 權限,所以都不需要寫太多 hard code 的東西進去。 機器開起來以後希望做幾件事情:
所以就有兩個重點,一個是 userdata,其中粗體是要修改的 route table id:
#!/bin/bash ROUTE_TABLE_ID=rtb-1a2b3c4d INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) aws ec2 modify-instance-attribute / --region us-west-2 / --instance-id "${INSTANCE_ID}" / --no-source-dest-check aws ec2 replace-route / --region us-west-2 / --route-table-id "${ROUTE_TABLE_ID}" / --destination-cidr-block 0.0.0.0/0 / --instance-id "${INSTANCE_ID}" || / aws ec2 create-route / --region us-west-2 / --route-table-id "${ROUTE_TABLE_ID}" / --destination-cidr-block 0.0.0.0/0 / --instance-id "${INSTANCE_ID}"
最前面事先抓 instance_id,然後修改 Source/Destination 檢查,最後面的指令是先試著 ReplaceRoute,如果失敗就 CreateRoute (注意到 shell 的 ||
操作)。
另外的重點是 IAM Role,這台機器對應的 IAM Role 權限要開三個:
{ "Statement": [ { "Action": [ "ec2:CreateRoute", "ec2:ReplaceRoute", "ec2:ModifyInstanceAttribute" ], "Effect": "Allow", "Resource": "*" } ] }
拿 t2.medium 測試,burst 可以到 200Mbps 左右,應該還算夠用?反正不夠用就自己挑其他機器開吧 XD