はじめに
本記事は、Elastic Stack Advent Calendar 20日目の記事です。
Elasticsearch 初学者ですが、枠が空いていたため投稿させていただきます。
最初に、一点謝ります。
当初、Elasticsearch のトラブルシューティング記事を執筆する予定でしたが、
推敲をしているうちに Elasticsearch との関係性が低い記事になってしまいました。
Elastic ネタを楽しみにされていた方、本当にすみません。
(記事の後半に Elasticsearch に関連する内容も記載してはいます。)
直前で投稿を辞退するのもご迷惑かと思ったので、このまま投稿いたします。
本記事のサマリー:EC2 に ping を通す方法
先日、AWS 上の EC2 インスタンスへの ping 疎通でつまづいたので、どなたかの役に立てばと思い記事にします。
結論から言うと、EC2 に ping をしたい時は、セキュリティーグループの設定から ICMPプロトコルを追加する必要があります。
発生した問題
以下のようなEC2インスタンスがあります。(AMI は Amazon Linux 2 を利用)
ポイントは以下2点
上記2つの設定により、この EC2 には ローカルマシンから SSH 経由でアクセスすることができます。
(写真では Tera Term からログインできています)
また、インスタンスに以下のコマンドを流して Apache をインストールすると、ブラウザから Apache の初期ページを表示することもできます。
$ sudo yum -y install httpd
$ sudo systemctl start httpd.service
しかし、ここで謎なことが。
ローカルPCのコマンドプロンプト(ターミナル)を開いて、EC2 インスタンスに ping してみると…
あれ、ping が疎通しない…
疎通確認のための ping なのに…
WEB ページ見れているのに、なぜ??
セキュリティーグループにて、ポートをフルオープンにしてもだめでした…うーん??
原因と解決策
ping は、TCP/IPプロトコルではなく、ICMPプロトコルを使用しています。
そのため、ping の疎通をするためには、EC2のセキュリティーグループ設定にて、ICMPプロトコルを許可する設定が必要になります。
※ HTTP, SSH, POP3, FTP など、身近なものは全てTCP/IPプロトコルなので、てっきりTCPポートを全てあければ大丈夫だろうと思っていました。
「セキュリティーグループを編集」の画面から、インバウンドルールにて「すべてのICMP - IPv4」を追加して保存します
補足:Elasticsearch でのトラブルシューティングの話
「Elastic Stack Advent Calendar なのに Elasticseach ネタじゃない!」と怒られそうなので、この記事の執筆理由となった Elasticsearch のトラブルについても記載しておきます。かなり初心者的な設定ミスです。
発生したトラブルの内容
個人学習としてEC2を立て、そこにApacheとElasticseachをインストールしました。
セキュリティーグループにて、HTTP(80)とElasticsearch(9200,9300)のポートをあけたものの、
ローカルPCからは、HTTPリクエストしか通らない現象がありました。(Elasticsearch のAPIが叩けない...)
期待していたこと
ローカルPCから Elasticsearch の REST API で検索クエリを投げて、検索結果が受信できる。
$ curl -XGET 'http://<パブリックIPアドレス>:9200/my_index/my_index/1'
{"_index":"my_index","_type":"my_index","_id":"1","_version":2,"_seq_no":1,"_primary_term":1,"found":true,"_source":
{
user_name : "John Smith",
date : "2017-10-15T15:09:45",
message : "Hello Elasticsearch world."
}
実際の現象
API を呼び出すと、Connection refused になる。
$ curl -XGET 'http://<パブリックIPアドレス>:9200/my_index/my_index/1'
curl: (7) Failed to connect to <パブリックIPアドレス> port 9200: Connection refused
確認したこと1
HTTP アクセスは問題ない模様(Apacheは動いている) → セキュリティーグループの設定にミスは無さそう。
$ curl <パブリックIPアドレス>:80
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd%22%3E
...(以下略)
※ブラウザからもapacheの画面は表示される。
http://<パブリックIPアドレス>/
確認したこと2
ping が通らない → えっ!? じゃあなぜ HTTP は通ったの?
$ ping <パブリックIPアドレス>
Request timeout for icmp_seq 0
...(以下略)
確認したこと3
ローカルPCのファイアウォール設定はオープンにしたが変わらない。
確認したこと4
インスタンス上のシェルから、Elasticsearch サービスが起動していることも確認済み。
$ sudo lsof -i -n -P
java 3203 elasticsearch 189u IPv6 21148 0t0 TCP [::1]:9300 (LISTEN)
java 3203 elasticsearch 190u IPv6 21155 0t0 TCP 127.0.0.1:9300 (LISTEN)
java 3203 elasticsearch 191u IPv6 21196 0t0 TCP 127.0.0.1:9200 (LISTEN)
java 3203 elasticsearch 198u IPv6 21195 0t0 TCP [::1]:9200 (LISTEN)
確認したこと5
インスタンス上で Elasticsearch の API を叩くと、期待通りのレスポンスが正常に表示される。
→ ローカルPCからのみ API が叩けない。
原因と解決策
私は当初、上記の問題が EC2 上の設定ミスだと思っていました。
ですが、時間をかけて調べた結果、2つの問題が組み合わさっていたことがわかりました。
ping が疎通しない点
これは本記事で記載したとおり、ping が ICMP プロトコルであり、セキュリティーグループの設定でつぶされていたためでした。
ローカルマシンから Elasticsearch API を呼び出せなかった点
Elasticsearch はデフォルトでインターネットからのAPIアクセスを閉じているという理由でした。
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html
上記ドキュメントの通り、network.host
の項目を変更することで、インターネット経由でもアクセスできるようになります。
具体的には、インスタンスに対して、以下のコマンド操作と yml ファイルを編集したことで、
ローカルPCからでも API を操作できるようになりました。
$ sudo systemctl stop elasticsearch.service
$ sudo vim /etc/elasticsearch/elasticsearch.yml
ここで、network.host: 0.0.0.0 に変更
$ sudo systemctl start elasticsearch.service
Elasticsearch の有識者の方には当たり前すぎる初期設定なのでしょうが、初学者の私はかなり苦労したトラブルでした。
(日曜日が丸々つぶれました )
他の学習者の方の参考になればと思い、ここに解決メモとして残させていただきます。
もう少し器用にトラブルシューティングをしていかねばとつくづく思います。。 頑張ります。
注意事項
- 本記事では、EC2のセキュリティーグループや
network.host
のソースを0.0.0.0/0
で設定していますが、
実際には適切な IP 制限をかけてセキュリティーを担保しましょう。