Amazon Linux で yum に失敗する

Amazon Linuxを仕事で使っていると、誰もが一度は通る道。

インターネットには接続できるのに、Amazon Linux上でyumコマンドのどれを実行してもタイムアウトになってしまうことがある。

yumが使えないという場合の大半の事象がこれで良く聞かれる上に結構汎用的なパターンなので、検索で引っかかるようになってくれるといいな。

条件

大体、Amazon LinuxVPN接続したVPC内で利用する場合。

原因

Amazon Linuxyumリポジトリが受け付けるリクエストは、AWSのIGWから出た通信である必要があるため。言い換えると、Amazon Linuxにデフォルトで設定されているyumリポジトリは(当たり前だが)AWSで提供されているインフラ以外で動作するLinuxからのyumを許可していない。

一般に、上記の条件でVPN接続をしている場合、直接IGWを経由してインターネットに出ているのではなく、VPNの接続元のルータを経由して(IGWを経由せずに)インターネットに接続するルーティングが行われていることが多い。

対策

yumリポジトリに接続するサーバーがIGWから通信を行うようにすれば良い。
この時にNATインスタンス、あるいはHttpProxyインスタンスを立てて、それを利用すると良い。

(Proxyの方法を選ぶ場合、/etc/yum.confにProxyの設定が必要)

AWSのネットワーク設計的には、IGWと直接接続する public subnet *1 と IGWと直接接続しない private subnet に分けることを推奨しているので、public subnetにNATを立てて、Amazon Linuxを(NATへのルーティングが行われた)private subnetに立てるようにすれば良い。

Proxyを立てる場合には、private subnetが完全にインターネットから孤立していると以下に書いてあることが起きるので、とりあえずyumはできないがインターネットに(VPN経由で)接続できる環境で起動して、/etc/yum.confにProxyの設定を書き加えて利用すればよい。

おまけ

確実ではないけれど、自分が経験した内容を1つ。

Amazon Linuxはcloud-initの中でyumを使うなど、インターネットに接続できる前提の設定が色々と行われている(っぽい)ので、インターネットに完全に接続できない環境でローンチすると、起動に無茶苦茶時間が掛かっているように見える。
(sshdのサービス起動優先度はcloud-initのサービス起動優先度より低いので、cloud-initのタイムアウト処理が行われるまでsshdが起動せずに、中に入って確認できない事象が続く)

その上、起動時のUserDataに渡した内容を処理するのはcloud-initの最後の方で、インターネットにつながらず、cloud-initの先の方の処理がエラーになるとUserDataに書いた処理が実行されない。

少なくとも、自分がshellを書いて渡した場合はそうだった。

ので、インターネットに直接接続できない環境にAmazon Linuxを立てる場合は相当に工夫しなくてはいけない。 Proxyを設定しようとUserDataでパラメータを渡しても、そのシェルを実行してくれないからである。

自分は素のAmazon Linuxを直接起動するのではなく、一度IGWとNATごしに接続されている環境でProxyの設定を行った後リリース用のAMIを作成して、それをリリースしているのだけれども、private subnetにAmazon Linuxを立てる場合は皆どのようにしているものだろうか。

何か良い方法を知っている人がいれば、ご教授下さい。

*1:言い換えるとDMZ