はじめに
AWS AppMesh記事第2弾。
前回の記事の続き。
今回は、前回記事のフロント側サービス(サービスA)にも AppMesh を適用して、バックエンド通信も含めて統合することを目指す。
前回に引き続き、本記事を書いている 2021/1/2 時点で AWS AppMesh はまだまだ発展途上なサービスであり、情報が変わる可能性があることはご了承いただきたい。
バックエンドサービス通信編で目指す構成
前回の構成を以下のように変更する。
- 前回の構成
- 今回の構成
サービスAは後続のサービスBに HTTP リクエストを転送する機能を持ったプロキシである前提だ。
今回は、サービスBは特に触らず、サービスAについて変更を行っていく。
AppMesh のサービスAに関連した項目の設定
基本的にサービスBに行った変更とは大きく変わらない。
ECS に関連した変更は前回と同じであるため、今回は割愛する。
※サービスAはロードバランサ配下にいるため、その設定は削除しない。
AppMesh に関連したリソースを以下のように変更する。
今回も、aws_appmesh_virtual_service
と aws_appmesh_virtual_node
を作成する。
メッシュそのものは、サービスA/Bで共通であるため今回は作成しない。
resource "aws_appmesh_virtual_service" "service_a" {
name = "${aws_service_discovery_service.service_a.name}.${aws_service_discovery_private_dns_namespace.internal.name}"
mesh_name = aws_appmesh_mesh.trial.id
spec {
provider {
virtual_node {
virtual_node_name = aws_appmesh_virtual_node.service_a.name
}
}
}
}
resource "aws_appmesh_virtual_node" "service_a" {
name = local.service_a_appmesh_virtualnode_name
mesh_name = aws_appmesh_mesh.trial.id
spec {
listener {
port_mapping {
port = 80
protocol = "http"
}
health_check {
protocol = "http"
path = "/healthcheck"
healthy_threshold = 2
unhealthy_threshold = 2
timeout_millis = 2000
interval_millis = 5000
}
}
backend {
virtual_service {
virtual_service_name = aws_appmesh_virtual_service.service_b.name
}
}
service_discovery {
aws_cloud_map {
namespace_name = [サービスディスカバリの名前空間]
service_name = [サービスAのサービス名]
}
}
logging {
access_log {
file {
path = "/dev/stdout"
}
}
}
}
}
ポイントは
backend {
virtual_service {
virtual_service_name = aws_appmesh_virtual_service.service_b.name
}
}
の部分で、この設定によりバックエンド通信をプロキシ経由に変更する。
動かしてみる
これで、NLB のパブリックドメインに対して curl でトラフィックを入れてみると、サービスB側の情報が返却されるだろう。
その上で、サービスAの CloudWatch Logs を確認すると、以下の2つのアクセスログが出力されていることが分かる。
[2021-01-02T11:20:33.732Z] "GET / HTTP/1.1" 200 - 0 413 3 3 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "service-b.appmesh-trial.internal" "xxx.xxx.xxx.xxx:80"
[2021-01-02T11:20:33.730Z] "GET / HTTP/1.1" 200 - 0 413 5 5 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "appmesh-trial-svc-a-nlb-230cfbfddd423b72.elb.ap-northeast-1.amazonaws.com" "127.0.0.1:80"
また、サービスB側のログにも以下が出力されている。
[2021-01-02T11:20:33.734Z] "GET / HTTP/1.1" 200 - 0 413 0 0 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "service-b.appmesh-trial.internal" "127.0.0.1:80"
マスクしているが、xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
には同じ値が入っていて、トラフィックを一意に識別することができる。
また、X-Ray のサービスマップは以下のように変わる。
分かりにくいが、下がサービスA、上がサービスBだ。
サービスBにも Client から線が延びているのは、ヘルスチェックのトラフィックが計上されているためだ。
エンドユーザトランザクションはサービスA側からしか入れていない。
このように簡単にサービスマップを後付けで作ることができるのも AppMesh のポイントだろう。