前幾天公司 Data team 的人跑來說他們的 AWS EMR 跑不起來 … 頭先是卡在 booting 不會動 …
不會動之前有在 VPC 下用 DHCP Options Sets 設定 DNS Resolver,因為 Cloud Hub 的架構下 DNS Resolver 省不了 … 但是總有一些坑要踩。
EMR booting failed
首先先提的是卡 booting 這個問題,這個其實在 AWS DHCP Options Sets 裡面就有提到在用 EMR 時要注意的問題 .. 可是當時沒有意會出來。
Services that use the Hadoop framework, such as Amazon EMR, require instances to resolve their own fully qualified domain names (FQDN). In such cases, DNS resolution can fail if the domain-name-serversoption is set to a custom value. To ensure proper DNS resolution, consider adding a conditional forwarder on your DNS server to forward queries for the domain region-name.compute.internal to the Amazon DNS server. For more information about launching an Amazon EMR cluster into a VPC, see Setting Up a VPC to Host Clusters in the Amazon EMR Developer Guide.
裡面其實很清楚的提到,如果你使用自定的 domain-name-servers 的話就很有可能會讓 EMR 在解析 DNS 時失敗,至於是解析什麼 Domain !?? 裡面也有提到是 ${region-name}.compute.internal,像我如果在 Tokyo 這個 Region 的話,預設 domain-name 就是 ap-northeast-1.compute.internal,可是到底跟這個什麼關係 ?!
實測的結果是 EMR 在 booting 的時候會去解析 EMR EC2 的 Private DNS
ip-172-16-0-117.ap-northeast-1.compute.internal
這個 Domain name 只能在兩個地方解析的到
- 169.254.169.254
- Subnet 中內建的 DNS (第三個 IP) ,詳情參考「AWS 內 VPC 與 Subnet 規劃、理解」
那怎麼辦 !? DNS Resolver 的功用就在於把 ap-northeast-1.compute.internal 這個 domain forward 到 169.254.169.254 這樣就解析的到了 !!!
EMR Hadoop start failed
解了第一個 booting 的問題後,又發生了第二個 Hadoop 啟動失敗的問題
ERROR org.apache.hadoop.hdfs.server.datanode.DataNode (DataNode: [[[DISK]file:/mnt/hdfs/]] heartbeating to /172.16.9.119:8020): Initialization failed for Block pool BP-2077993335-172.16.9.119-1515060115584 (Datanode Uuid null) service to /172.16.9.119:8020 Datanode denied communication with namenode because hostname cannot be resolved (ip=172.16.9.99, hostname=172.16.9.99):
從 Log 訊息看起來 … 很好又是 DNS 解析的問題,看起來 Hadoop 在啟動的時候需要 query hostname,但是上面應該已經解了阿 !!??
問題出在於 Hadoop 要能”反解” EC2 的 IP,WTF …
有兩個解法:
- 拿掉 Hadoop 的 check ip-rever 設定,在 hdfs-site.xml 加上:
<property> <name>dfs.namenode.datanode.registration.ip-hostname-check</name> <value>false</value> </property>
這樣就會動了,但是身為工程師用這樣的解法有點技術債的感覺,所以又出現了第二個作法:
- 把需要解析的 IP 段 forward 給 169.254.169.254 反解
第二個作法看起來是比較根解而且合理的作法。