- まえがき
- 目的
- 前提
- 環境
- やること
- やらないこと
- 構成
- 踏み台サーバーの作成
- パブリックサブネットに配置されているEC2インスタンスを別サブネットに移行する
- NATゲートウェイの作成
- ELBの作成
- 構築
まえがき
こちらの記事の続編です。 techhotoke.hatenablog.com
目的
VueとSpringで作成したプロジェクトの構築手順の備忘録。 備忘録のため、詳細な説明を省略している部分があります。
前提
環境
やること
- 踏み台サーバーの構築
- AWIの取得
- NATGatewayの作成
- ELBの作成
やらないこと
構成
踏み台サーバーの作成
踏み台サーバーとは?
- プライベートサブネットに配置したサーバーにアクセスするための手法 メリット
- 外部から各サーバーに直接アクセスできないので、セキュリティの向上につながる
- 外部通信に対するアクセス制御の対象を踏み台サーバーに限定できるため運用負荷を軽減できる デメリット
- サーバーが一台増えるので管理コストが上がる
構築
- EC2インスタンスをpublic-subnet-aに新たに作成(手順省略)
- ElasticIPアドレスを新規作成し、上記手順で作成したEC2インスタンスに関連づける
- 既存のセキュリティグループのSSH接続で割り当てられているIPアドレスを上記で作成したものに変更する
- ここまで設定したら、確認として既存のEC2インスタンスに直接ログインできないことを確認する
- SSH ポートフォワーディングを使って踏み台サーバーを経由してWebサーバーにログインする
- 新規ウィンドウでターミナルを開き、
ssh -i ~/.ssh/tms-dev-keypair.pem ec2-user@localhost -p 10022
コマンドでWebサーバーにアクセスする ls
コマンドなどアプリケーションのソースが存在することを確認できたら完了
SSH ポートフォワーディングとは?
SSHコネクション上で任意のポートへの通信を特定ポートへ転送する機能です。これはSSHの機能で、sshコマンドにポートを転送するオプションがデフォルトで備わっています。異なるサーバー間でセキュリティやネットワークの設定によって直接アクセスができない場合に利用されます。
- ローカルポートフォワード: クライアントユーザーや稼働するソフトウェアから見た、自らのコンピュータまたは端末 リモートホスト…ローカルのクライアントから見た、ネットワークで接続する先のコンピュータまたは端末 サーバーを中継して、クライアントのポートをリモートホストのリモートポートに転送します。
ssh -L {port}:{remotehost}:{remoteport} {server}
- リモートポートフォワード: クライアント…ユーザーや稼働するソフトウェアから見た、自らのコンピュータまたは端末 リモートホスト…クライアントから接続するホストから見た、ネットワークで接続する先のコンピュータまたは端末 クライアントを中継して、サーバーのポートをリモートホストのリモートポートに転送します。
ssh -R {port}:{remotehost}:{remoteport} {server}
パブリックサブネットに配置されているEC2インスタンスを別サブネットに移行する
今回はAMIを作成して、そこからEC2インスタンス立ち上げていきます。
AMIとは?
- ソフトウェア構成 (オペレーティングシステム、アプリケーションサーバー、アプリケーションなど) を記録したテンプレート。EC2の元となるイメージ的なもの
- 独自でカスタムしたAMIを書き出し、それを利用することで、冗長構成の構築、復旧作業などが比較的簡単に行える
AMIの作成
- 該当のWebサーバーからイメージを作成を選択
- 適当な名前とタグをつけて(現在日時を入れると後々混乱しなくて良いです)作成
- リンクをクリック
- イメージからインスタンスを起動を選択
- Protected-aのサブネットに配置
- 既存のセキュリティグループからweb-appを選択
- インスタンスを作成
- 作成したインスタンスに踏み台サーバーの作成で行ったことと同じ設定を施す
- Webサーバーにアクセスできることを確認する
- Webサーバーにアクセスしたら、下記コマンドなどを使って外部のネットワークに接続できなくなっていることを確認する
wget https://ja.wordpress.org/latest-ja.tar.gz
- 処理が行われずタイムアウトすると思われるので、そうなれば完了です
添付画像のようなWARNINGが発生したので、対処方法をまとめておきます
- SSHでは初回接続時に接続先ホストの公開鍵を保存しておき、次回接続時にホスト鍵を比較して前回と同じホストに接続したかを確認するような仕組みになっています。そのため、IPアドレスの振り直しやOS再インストールなどでホスト鍵が変わってしまった場合、エラーメッセージが出てSSH接続が失敗してしまいます。
- 中間者攻撃対策に備わっている機能だと思います
中間者攻撃とは二者間の通信を特別なソフトウェアなどの不正な手段を用いて傍受、盗聴して内容を取得するといったもの
対処
NATゲートウェイの作成
※STSのエラーが発生し、あまりにもイライラしたのでInteliJに乗り換えました。なのでここからInteliJを使用して開発していきます。
NATゲートウェイとは?
- NAT(Network Address Transration):プライベートIPアドレスをグローバルIPアドレスに変換する技術
- インターネットからプライベートサブネットへのアクセスはできなくなる
- NATGateWayはAWSが提供するNATの機能を実現するためのサービス
- サブネットの設定、ElasticIPアドレスの設定によってNATの機能を簡単に実現することが可能
- ベストプラクティスとしては、異なるアベイラビリティゾーンごとに NATGateWayを設置して、冗長構成を実現する(NATGateWayが設置されたアベイラビリティゾーンに障害が発生した場合のセーフティネットとして)
構築
NATゲートウェイ
NATゲートウェイ用のサブネットを作成する
- ルートテーブルを作成
- ルートテーブルにルート
0.0.0.0/0
、NAtゲートウェイを選択して作成 - protectedサブネットの関連づけを行う
- 踏み台サーバー経由でインスタンスにログインする
wget https://ja.wordpress.org/latest-ja.tar.gz
コマンドなどを実行してインターネットにアクセスできることを確認
ELBの作成
ELBとは?
- 負荷分散のサービス。ロードバランサーの役割を担うサービス
- ELBは自動でスケーリングされる
- ひとつのELBを設置することで、アベイラビリティーゾーンごとにELBが配置されているような構成になる
- ELBの種類
- ALB:アプリケーション層で使用。パスベースルーティングを行う(URL含まれるパスに応じて接続するサーバーを切り替える)
- NLB: トランスポート層で使用。Webサーバー以外の負荷分散に使われる。
- CLB:旧世代なので使用は非推奨
ELBについて
- インターネット向けと内部
- インターネット向け:インターネットから通信が可能
- 内部:インターネットから通信不可
- 後から変更できないので注意
- リスナー
- どのような通信を受付け、どこに転送するかの設定
- パスベースルーティングはこの転送先の設定で行うことができる
- アベイラビリティゾーンとサブネット
- セキュリティグループ
- 仮想ファイアウォールのこと
- ターゲットグループ
- 負荷分散の大賞サーバーをまとめたグループ
- ヘルスチェック
- スティッキーセッション
- 同じユーザーからきたリクエストを同じターゲット(サーバー)に転送する
- クッキーを使用して、同じターゲットに転送する
構築
- ELBを検索し、機能からロードバランサーを選択
- ロードバランサーを作成を選択
- Application Loadbalancerを選択
- Internet向けを選択(記事執筆時では、UIが英語な感じになっていたので、画像を添付します)
- 該当のVPCを選択
- セキュリティグループを新規作成(HTTP通信ポート80と8080[おそらくTomcatの接続で使うので]をインバウンドルールに設定)
- public-subnet-a及びcをMappingする
- HTTPポート80/8080をリスナーに追加
- ターゲットグループを新規作成し、適当な名称をつけてデフォルト設定のままターゲットの作成に進む
- web-app-protectedをターゲットに選択して作成
- 画像のようにセッションの維持設定を行う
- ロードバランサー作成画面に戻り、リスナーのfoward先に作成したターゲットを選択
- ロードバランサーの作成を選択
- 踏み台サーバ経由でインスタンスにログインした状態で、
./gradlew bootRun
を実行してアプリケーションを起動 - ロードバランサーに割り当てられたDNSとアプリケーションのポート番号でアクセス
- こうなった。Damn...
502BadGatewayの対処
- 公式が主にこのような原因が考えられると教えてくれてます(親切)
引用: Application Load Balancer のトラブルシューティング - Elastic Load Balancing
まずはEC2に原因があるのかALBに原因があるのか切り分けたいので、ALBのログを取得できるようにしていきたいと思います。
ALBのアクセスログを有効化して、
S3の添付画像のパスの形式でログが保存されているので、そちらをダウンロードします
ログには以下のような情報が記載されているようです。
http 2022-01-09T13:33:03.219781Z app/tms-dev-alb-public/af018ae04d93b735 14.11.32.1:16804 10.0.10.54:80 -1 -1 -1 502 - 637 1077 "GET http://tms-dev-alb-public-1362974723.ap-northeast-1.elb.amazonaws.com:8080/favicon.ico HTTP/1.1" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - - arn:aws:elasticloadbalancing:ap-northeast-1:187609072069:targetgroup/tms-dev-tg-public/f25101ace9787ef1 "Root=1-61dae40f-4edfd59f2cd80e0a78d44d6c" "-" "-" 0 2022-01-09T13:33:03.192000Z "forward" "-" "-" "10.0.10.54:80" "-" "-" "-"
ログを見ると、ロードバランサーが502を返し、ターゲットからの応答が無いようなので、ロードバランサーの問題ということが分かりました。 また、バックエンドからではなく、ELBから502が返ってきていることが分かりました。
つまり、ELBのどこかしらの設定に問題がありそうなので、探してみると
セキュリティグループはpublicなので問題なさそう。
ターゲットグループはHTTP80番ポートを受けて、ターゲットには対象のprotectedサブネットに配置したEC2インスタンスが指定されているので問題なさそう(EC2インスタンス接続の際に80ポートは使わないので削除しました)
リスナーのポートを確認すると。。。8080が登録されていなかったので、8080を以下のように追加。
ELBのDNS名:ポート/アプリケーションのルートパス
でアクセスすると、アクセスできました!
今回はここまでとなります。
お付き合い頂きありがとうございます。 次回はDBをRDSに移行していきます。