2020年8月8日土曜日

AppMeshを試す(1)


前回

これまでの関連記事は、下記のとおり



今回


Meshの外→内、内→外へアクセスしながら、X-RAYのサービスマップなどを確認してみます。


サービスマップの初期状態


環境構築直後に、CloudWatch→ServiceLens でサービスマップを見てみます。
api01のヘルスチェックだけ表示されています。


[MEMO]
  • bffのヘルスチェックも表示されるかと思ったが表示されない。
    アクセスログに記録もない。SRVだから?(原因不明)

Meshの外(NATインスタンス)からアクセス


SSMのセッションマネージャでNATインスタンスにログインして作業します。


1. bff

bff にアクセスしてみます。
bff は SRVレコードなので、DNS名で直接、URLは叩けません。
まず、dig でIPアドレスとポートを調べて、curl でたたきます。
$ dig srv bff.blue21.local

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.64.amzn1 <<>> srv bff.blue21.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34313
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;bff.blue21.local.              IN      SRV

;; ANSWER SECTION:
bff.blue21.local.       60      IN      SRV     1 1 5000 7d4759d5-1f5a-4ab8-9064-a2b56527daef.bff.blue21.local.

;; Query time: 2 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Fri Aug  7 08:27:19 2020
;; MSG SIZE  rcvd: 107

$ dig 7d4759d5-1f5a-4ab8-9064-a2b56527daef.bff.blue21.local

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.64.amzn1 <<>> 7d4759d5-1f5a-4ab8-9064-a2b56527daef.bff.blue21.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23054
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;7d4759d5-1f5a-4ab8-9064-a2b56527daef.bff.blue21.local. IN A

;; ANSWER SECTION:
7d4759d5-1f5a-4ab8-9064-a2b56527daef.bff.blue21.local. 60 IN A 10.0.11.62

;; Query time: 2 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Fri Aug  7 08:27:47 2020
;; MSG SIZE  rcvd: 87

$ curl -v http://10.0.11.62:5000/debug
*   Trying 10.0.11.62...
* TCP_NODELAY set
* Connected to 10.0.11.62 (10.0.11.62) port 5000 (#0)
> GET /debug HTTP/1.1
> Host: 10.0.11.62:5000
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 2
< x-amzn-trace-id: Root=1-5f2d1329-0af148ca0c9d56c8461d30f2
< server: envoy
< date: Fri, 07 Aug 2020 08:39:05 GMT
< x-envoy-upstream-service-time: 4
<
* Connection #0 to host 10.0.11.62 left intact
ok

/debug をたたくと、リクエストヘッダをログに出力するので、見てみます。


サービスマップは下図のとおり。


2. api01

api01 にアクセスしてみます。api01が表示されます。
$ curl -v http://api01.blue21.local/debug
*   Trying 10.0.11.86...
* TCP_NODELAY set
* Connected to api01.blue21.local (10.0.11.86) port 80 (#0)
> GET /debug HTTP/1.1
> Host: api01.blue21.local
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
< server: envoy
< date: Fri, 07 Aug 2020 08:54:07 GMT
< content-type: application/json
< content-length: 127
< x-amzn-trace-id: Root=1-5f2d16af-02db5147085572f59e40f0c3
< x-envoy-upstream-service-time: 4
<
{"msg":"Content-Length,Host,User-Agent,Accept,X-Forwarded-Proto,X-Request-Id,X-Amzn-Trace-Id,X-Envoy-Expected-Rq-Timeout-Ms,"}

/debug をたたくと、リクエストヘッダをログに出力するので、見てみます。


サービスマップは、下図のとおり。


3.api02

api02 にアクセスしてみます。
ping は ApiGateway 自体が持ってるヘルスチェック用URLです。(Amazon API Gateway の重要な注意点を参照)
ドメイン違いでCNAMEを使用しているので、SSL証明書エラーにならないように -k をつけて curl で叩きます。
$ curl -v -k https://api02.blue21.local/ping
*   Trying 54.175.4.32...
* TCP_NODELAY set
* Connected to api02.blue21.local (54.175.4.32) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.execute-api.us-east-1.amazonaws.com
*  start date: Nov 20 00:00:00 2019 GMT
*  expire date: Dec 20 12:00:00 2020 GMT
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x12fcd10)
> GET /ping HTTP/2
> Host: api02.blue21.local
> User-Agent: curl/7.61.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< date: Fri, 07 Aug 2020 09:19:39 GMT
< content-length: 18
<
* Connection #0 to host api02.blue21.local left intact
Healthy Connection
こんどは、lambdaを実行してみます。
JWT認証でアクセス制限しているので、トークンが必要です。
dashbord画面に表示されているトークンを使用します。


Authorization ヘッダに token を指定して api02 を実行します。
api02.blue21.local ではアクセスできないので、CNAMEに設定したApiGatewayのエンドポイントでアクセスします。
$ dig api02.blue21.local
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.64.amzn1 <<>> api02.blue21.local;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10854;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:
;api02.blue21.local.            IN      A

;; ANSWER SECTION:
api02.blue21.local.     25      IN      CNAME   xn5hjukf38.execute-api.us-east-1.amazonaws.com.
xn5hjukf38.execute-api.us-east-1.amazonaws.com. 25 IN A 54.152.147.167
xn5hjukf38.execute-api.us-east-1.amazonaws.com. 25 IN A 3.212.43.185

;; Query time: 0 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Fri Aug  7 09:36:43 2020
;; MSG SIZE  rcvd: 128

$ curl -v -H'Authorization: eyJra...CZ0Xw' -XPOST https://xn5hjukf38.execute-api.us-east-1.amazonaws.com/protect
*   Trying 54.175.4.32...
* TCP_NODELAY set
* Connected to xn5hjukf38.execute-api.us-east-1.amazonaws.com (54.175.4.32) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.execute-api.us-east-1.amazonaws.com
*  start date: Nov 20 00:00:00 2019 GMT
*  expire date: Dec 20 12:00:00 2020 GMT
*  subjectAltName: host "xn5hjukf38.execute-api.us-east-1.amazonaws.com" matched cert's "*.execute-api.us-east-1.amazonaws.com"
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x68bd10)
> POST /protect HTTP/2
> Host: xn5hjukf38.execute-api.us-east-1.amazonaws.com
> User-Agent: curl/7.61.1
> Accept: */*
> Authorization: eyJra...CZ0Xw
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< date: Fri, 07 Aug 2020 09:39:38 GMT
< content-type: application/json
< content-length: 15
< apigw-requestid: Q5ImMicTIAMESfg=
<
{"status":"ok"}

サービスマップは、下図のとおり。
これは、LambdaのX-RAYトレースを有効にしているので表示されています。
(AppMeshは関係ない)


[MEMO]
  • CloudMapをパブリックゾーンにして、ApiGatewayをカスタムドメインにすればSSL証明書のエラーは解消できると思われる。

Mashの内(ECSサービス)からアクセス


SSMのセッションマネージャでECSインスタンスにログインして作業します。


ログイン後 "sudo su -" を実行してrootにスイッチし
bffコンテナ内からアクセスしてみます。
[root@ip-10-0-11-248 ~]# docker ps | grep bff
3a0109fc8eda        544509011205.dkr.ecr.us-east-1.amazonaws.com/blue21/bff_flask                   "python3 app.py"         2 hours agoUp 2 hours                                 ecs-Blue21Bff00PoC-19-bff-96f092e989c891ce1700
[root@ip-10-0-11-248 ~]# docker exec -it 3a0109fc8eda bash

1.api01

curlでapiをたたきます。
[root@ip-10-0-11-62 app]# curl -v http://api01.blue21.local/debug
* About to connect() to api01.blue21.local port 80 (#0)
*   Trying 10.0.11.86...
* Connected to api01.blue21.local (10.0.11.86) port 80 (#0)
> GET /debug HTTP/1.1
> User-Agent: curl/7.29.0
> Host: api01.blue21.local
> Accept: */*
>
< HTTP/1.1 200 OK
< server: envoy
< date: Fri, 07 Aug 2020 10:03:37 GMT
< content-type: application/json
< content-length: 127
< x-amzn-trace-id: Root=1-5f2d26f9-b9aa9520e83ca30b1dda4f83
< x-envoy-upstream-service-time: 6
<
{"msg":"Content-Length,Host,User-Agent,Accept,X-Forwarded-Proto,X-Request-Id,X-Amzn-Trace-Id,X-Envoy-Expected-Rq-Timeout-Ms,"}

サービスマップは下図のとおり。
bffからapi01をたたいたことがわかる。


2. api02

curl で api02 をたたきます。
[root@ip-10-0-11-62 app]# curl -v -XPOST -H'Authorization: eyJra...3BEg' https://xn5hjukf38.execute-api.us-east-1.amazonaws.com/protect
* About to connect() to xn5hjukf38.execute-api.us-east-1.amazonaws.com port 443 (#0)
*   Trying 52.5.195.105...
* Connected to xn5hjukf38.execute-api.us-east-1.amazonaws.com (52.5.195.105) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*       subject: CN=*.execute-api.us-east-1.amazonaws.com
*       start date: Nov 20 00:00:00 2019 GMT
*       expire date: Dec 20 12:00:00 2020 GMT
*       common name: *.execute-api.us-east-1.amazonaws.com
*       issuer: CN=Amazon,OU=Server CA 1B,O=Amazon,C=US
> POST /protect HTTP/1.1
> User-Agent: curl/7.29.0
> Host: xn5hjukf38.execute-api.us-east-1.amazonaws.com
> Accept: */*
> Authorization: eyJra...3BEg
>
< HTTP/1.1 200 OK
< Date: Fri, 07 Aug 2020 10:19:51 GMT
< Content-Type: application/json
< Content-Length: 15
< Connection: keep-alive
< Apigw-Requestid: Q5OfNghHIAMEPHQ=
<
{"status":"ok"}

サービスマップは下図のとおり。
bff からapi02にアクセスされたことはわからない。


[MEMO]
  • api02.blue21.local でアクセスできないのでAppMeshの設定は失敗だった。
  • ApiGatewayは、HTTP APIではなく、Rest APIにしてX-RAYトレースを有効にすれば、bff と連結して見えたかもしれない。

3.google

試しに、google にアクセスしてみたがアクセスできなかった。

[root@ip-10-0-11-62 app]# curl -I https://www.google.com
curl: (35) SSL received a record that exceeded the maximum permissible length.

[MEMO]