Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWSマネージドサービスを利用した流量制御機能の実装

 AWSマネージドサービスを利用した流量制御機能の実装

AWSを利用した流量制御機能に関して解説します。

nttdata_dccs

August 31, 2018
Tweet

More Decks by nttdata_dccs

Other Decks in Technology

Transcript

  1. © 2018 NTT DATA Corporation September/2018 NTT DATA Corporation Data

    Center & Cloud Services Division Flow Control Using AWS Managed Services
  2. © 2018 NTT DATA Corporation 2 目的 オンプレミスからAWSへの移行を実施するにあたり、 オンプレミス環境で導入している流量制御機能と同等の機能をAWSマネージドサービスを利用し、 AWS環境に実装する方式を検討する。

    概要 流量制御機能概要 オンプレミス環境では、F5社のBIP-IPのiRules機能を利用し、流量制御機能を実装。 性能試験を元にシステム内の負荷が高くなるコネクション数を洗い出し、そのコネクション数を閾値とし、 閾値を超えた場合、新規コネクションにはBIG-IP内のSorryページを表示させ、既存コネクションは、 継続してサイト利用できる。 新規要件 システム拡張に対応できるように流量制御機能も柔軟に拡張できること。 ⇒AWS マーケットプレイスで提供されるBIP-IP Virtual Editionは、Active-Active構成が組めないため、 流量制御サーバにHAproxy、閾値判定/流量制御実行にCloudWatchとLambdaを利用し、実装。
  3. © 2018 NTT DATA Corporation 3 システム構成図 AWS Lambda Amazon

    CloudWatch Amazon SNS HAproxy 流量制御 サーバ Web サーバ 流量制御実行フロー概要 本書では、WebサーバのCPU使用率を流量制御発動 の閾値とした。 ①CloudWatchにおいて、Webサーバ(EC2)の標準 メトリクスであるCPU使用率にアラーム設定し監視。 ②CloudWatchのアラームの設定閾値を超えたら SNSにLambda実行のトピックを送信。 ③Lambda関数にて流量制御サーバ内に実装した 流量制御発動/解除をスクリプトを実行。 上記方式により、Webサーバの負荷状態にあわせ 流量制御発動/解除を自動で実行可能となる。 各機能の実装方式の詳細は、次ページ以降に記載。 ① ② ③ AZ-A AZ-C Internet HAproxy 流量制御 サーバ Frontend ELB Internet ALB Backend ELB Internal ALB Amazon EC2 Systems Manager
  4. © 2018 NTT DATA Corporation 4 流量制御サーバ設定(通常時) 流量制御サーバ ・RHEL 7.5

    ・HAProxy 1.7 (参考:http://www.haproxy.org/) ・AWS SSMエージェント (参考: https://docs.aws.amazon.com/ja_jp/systems- manager/latest/userguide/what-is-systems- manager.html) ※流量制御発動/解除のスクリプト実行に使用 EC2(流量制御サーバ) HAProxy Frontend Backend 通常通信用 Backend 流量制御通信用 流量制御用 Sorryコンテンツ 接続元 Whitelist 接続先 Whitelist Internet ALB Internal ALB Internet ユーザ 流量制御用 Cookie付与 通常通信用 Config 流用制御用 Config 通常通信用Configと流量制御用Configを用意し、 シンボリックリンクでConfigを切り替え流量制御の発動/解除を実施する。 発動/解除の切替は、リロードで実施するため、オンラインで切替可能。 通常時の通信は、 HAproxyの通常通信用のBackendを経由し、Internal ALBに流れる。 Backendを経由する際に、流量制御用のcookieが付与される。 cookieは、流量制御発動時、流量制御対象とするかの判断に使用。 Web サーバ
  5. © 2018 NTT DATA Corporation 5 流量制御サーバ設定(通常時) 通常通信用Config(抜粋) resolvers awsdns

    nameserver dns1 xxx.xxx.xxx.xxx:53 resolve_retries 3 timeout retry 1s hold other 30s hold refused 30s hold nx 30s hold timeout 30s hold valid 10s frontend web-proxy-in bind *:80 maxconn 30000 timeout client 300s monitor-uri /monitor/AliveChk_Simple.html default_backend web-proxy-out backend web-proxy-out timeout server 300s cookie test_limit insert nocache indirect preserve httponly server webserver “Backend ELB DNS名”:80 maxconn 20000 cookie 0 check resolvers awsdns port 80 inter 5s fall 3 rise 1 frontendの設定 全ての通信はbackendに流れる。 DNS設定 Backendの通信先がALBのDNS名となるため、 定期的な名前解決を実施。 Backendの設定 流量制御用のcookie(test_limit)を付与。 全ての通信はBackend ELBに流れる。 通常時のWebサーバへのアクセス結果 流量制御用のcookie(test_limit)が付与される。
  6. © 2018 NTT DATA Corporation 6 流量制御サーバ設定(流量制御時) Internet ALB Internal

    ALB Internet 回遊中 ユーザ Web サーバ EC2(流量制御サーバ) HAProxy Frontend Backend 許可通信用 Backend 流量制御通信用 流量制御用 Sorryコンテンツ 流量制御用 Cookie確認 通常通信用 Config 流用制御用 Config 接続元 Whitelist 接続先 Whitelist 新規 ユーザ バックエンドサーバのリソース不足等により、それ以上の新規アクセスを受け付けたくない場合、 流量制御用Configを有効にする。 流量制御発動時、流量制御用のcookieを持つ回遊中のユーザーは継続してWebサーバにアクセス可能。 流量制御用のcookieを持たない新規ユーザは、HAproxy内の流量制御通信用のBackendに誘導され、 Sorryコンテンツが返される。 ※接続元Whitelistで許可されたIPアドレスや接続先Whitelistで許可されている通信(特定のURL)は、 流量制御対象外とすることもできる。
  7. © 2018 NTT DATA Corporation 7 流量制御サーバ設定(流量制御時) 流量制御用Config(抜粋) frontend web-proxy-in

    bind *:80 maxconn 30000 timeout client 300s monitor-uri /monitor/AliveChk_Simple.html acl flow-control cookie(test_limit) -m reg .+ default_backend web-proxy-out use_backend flow-control if !flow-control backend web-proxy-out timeout server 300s server webserver “Backend ELB DNS名”:80 maxconn 20000 check resolvers awsdns port 80 inter 5s fall 3 rise 1 backend flow-control timeout server 300s errorfile 503 /opt/haproxy/etc/error/sorry.html frontendの設定 cookie有無を確認するaclを設定し、 aclにマッチしない(cookie無)通信は、 backend flow-control に流れる。 Backendの設定(cookie有) 通信はBackend ELBに流れる。 流量制御時のHAproxyログ(抜粋) Sep 5 13:35:49 localhost haproxy[2106]: Proxy hpstats started. Sep 5 13:35:49 localhost haproxy[2106]: Proxy web-proxy-in started. Sep 5 13:35:49 localhost haproxy[2106]: Proxy web-proxy-out started. Sep 5 13:35:49 localhost haproxy[2106]: Proxy flow-control started. Sep 5 13:35:49 localhost haproxy[1303]: Stopping proxy hpstats in 0 ms. Sep 5 13:35:49 localhost haproxy[1303]: Stopping frontend web-proxy-in in 0 ms. Sep 5 13:35:49 localhost haproxy[1303]: Stopping backend web-proxy-out in 0 ms. Sep 5 13:35:49 localhost haproxy[1303]: Proxy hpstats stopped (FE: 0 conns, BE: 0 conns). Sep 5 13:35:49 localhost haproxy[1303]: Proxy web-proxy-in stopped (FE: 946 conns, BE: 0 conns). Sep 5 13:35:49 localhost haproxy[1303]: Proxy web-proxy-out stopped (FE: 0 conns, BE: 5 conns). Sep 5 13:35:49 localhost haproxy[2112]: Health check for server web-proxy-out/webserver succeeded, reason: Layer4 check passed, check duration: 3ms, status: 3/3 UP. Sep 5 13:37:37 localhost haproxy[2112]: xxx.xxx.xxx.xxx:48972 [05/Sep/2018:13:37:37.064] web- proxy-in web-proxy-out/webserver 0/0/3/8/11 304 137 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1“ Sep 5 13:37:56 localhost haproxy[2112]: xxx.xxx.xxx.xxx:48976 [05/Sep/2018:13:37:56.933] web- proxy-in flow-control/<NOSRV> 0/-1/-1/-1/0 503 318 - - SC-- 0/0/0/0/0 0/0 "GET /favicon.ico HTTP/1.1" Backendの設定(cookie無) HAproxy内のsorry.htmlを返す。 cookie有通信:web-proxy-in ⇒ web-proxy-out cookie無通信: web-proxy-in ⇒ flow-control
  8. © 2018 NTT DATA Corporation 8 ① ② CloudWatch アラーム設定

    CloudWatchには、WebサーバのCPU使用率に対し、以下の2つのアラームを設定する。 ①Alerm-FlowControl_close: 50%以上の場合、流量制御を発動するためのSNSトピック(SNSTopic_FlowControl_close)を送信。 ②Alerm-FlowControl_open: 20%以下の場合、流量制御を解除するためのSNSトピック(SNSTopic_FlowControl_open)を送信。
  9. © 2018 NTT DATA Corporation 10 Lambda設定 Lambdaでは、流量制御サーバ上のスクリプトを実行するPythonプログラムを指定する。 実装にあたり、インスタンスIDや認証情報などの固有情報を必要としない汎用的なプログラムとなるよう以下の方式とした。 ▪Pythonプログラムの実行対象をタグで指定。

    ①流量制御サーバ用EC2にタグ(キー:HAproxy、値:target)を追加。 ▪Systems Managerの利用。 サーバへの認証情報を保持する必要がないようSystems Manager経由でスクリプトを実行。 ①Lambda関数に以下のポリシーを許可した実行ロールを設定。 ・AmazonSSMFullAccess ・AmazonEC2FullAccess ・CloudWatchLogsFullAccess ②流量制御サーバにSSMエージェントを導入。 Lambda関数内で実行している流量制御サーバ上のスクリプトの役割は以下のとおり。 ①checkConf.sh 流量制御発動/解除状態を標準出力(発動時:close、解除時:open)する。 ②proxyOpenClose.sh ・引数にopenを指定:HAproxyのconfigのシンボリックリンクを通常通信用に変更し、サービスをリロード。 ・引数にcloseを指定 HAproxyのconfigのシンボリックリンクを流量制御用に変更し、サービスをリロード。
  10. © 2018 NTT DATA Corporation 11 Lambda設定 import boto3 import

    time ec2 = boto3.client('ec2',region_name='ap-northeast-1') ssm = boto3.client('ssm',region_name='ap-northeast-1') def lambda_handler(event, context): target=[{ 'Key': 'tag:HAproxy', 'Values': ['target'] }] #HAproxyの流量制御状態確認 check = ssm.send_command( #InstanceIds = instances, Targets=target, DocumentName = "AWS-RunShellScript", Parameters = { "commands": [ "/opt/infra/script/bin/checkConf.sh" ], "executionTimeout": ["30"] }, ) command_id = check['Command']['CommandId'] time.sleep(2) res = ssm.list_command_invocations( CommandId = command_id, Details = True ) invocations = res['CommandInvocations'] status = invocations[0]['Status'] if status == "Failed": print("RunCommand実行エラー") account = invocations[0]['CommandPlugins'][0]['Output'] print("status: "+account) #流量制御状態切替 if account == "open¥n": ssm.send_command( #InstanceIds = instances, Targets=target, DocumentName = "AWS-RunShellScript", Parameters = { "commands": [ "/opt/infra/script/bin/proxyOpenClose.sh close" ], "executionTimeout": ["30"] }, ) print("open状態からclose状態に切り替えました") elif account=="close¥n": print("すでにclose状態です") elif account=="error¥n": print("異常終了しました") Lambdaには、2つ関数を設定する。 ①FlowControl_close:流量制御発動用のスクリプトを実行。 ②FlowControl_open:流量制御解除用のスクリプトを実行。 以下にFlowControl_closeで実行するサンプルプログラムを示す。
  11. © 2018 NTT DATA Corporation 12 最後に 本書の方式は、キャンペーンサイトやECサイトなど急激なアクセス増加が発生するシステムにおいて有効である。 実際に、AWS上に構築された大手ECサイトにおいて類似の流量制御方式の導入実績もあり、効果を発揮している。 また、AutoScalingと併用することで大きな効果が期待できる。

    本方式のメリットは、メトリクスを閾値としてるため、流量制御の発動条件を柔軟に設定できることである。 カスタムメトリクスを利用すれば、発動条件の指定の幅は大きく広がる。 発動の判断を同種のサーバ郡の全体のリソース状況としたいケースも考えられる。 CloudWatch Metric Mathで作成したメトリクスにアラーム設定ができれば、容易に実装が可能となる。 ※2018年9月時点で提供されていないため、今後のサービス拡張に期待したい。 参考 (CloudWatch Metric Math): https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/using-metric-math.html