ECS AWS Cloud Map DNSクエリとAPIの検出タイミング検証

AWS Cloud MapはDNSクエリとAPI(DiscoverInstances)でリソース検出できる
Amazon ECSでタスク入れ替わったときのそれぞれの検出タイミングを検証

## 検証する環境
### aws構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481044/309790cd-bb74-a6c4-7b3d-dfa82de79fa1.png)
EC2からCloud MapのDNSクエリとAPIでECSタスク検出する
Cloud Map APIはPrivate Link経由で叩く

以下各リソースの設定値
- Cloud Map名前空間
    - インスタンスの検出: "API呼び出しとVPCのDNSクエリ"
    - TTL: 15秒
- ECSサービス
    - 必要なタスク: 2
    - 最小実行タスク: 100%
    - 最大実行タスク: 200%
    - サービス検出
        - "Amazon ECS タスク状態の伝達を有効にする": 有効
        - DNSレコード
            - DNSレコードタイプ: A
            - TTL: 15秒
- ECSタスク定義
    - CPU: 0.25/vCPU
    - メモリ: 1GB/
    - ヘルスチェック
        - コマンド: `CMD-SHELL,curl -f http://localhost || exit 1`
- EC2インスタンス
    - AMI: Amazon Linux 2023
    - インスタンスタイプ: t3.medium
- VPCエンドポイント
    - サービス名: com.amazonaws.ap-northeast-1.data-servicediscovery

### アプリケーション
#### サーバー
簡易的な"Hello, World!"を返すWebサーバー
```dockerfile:Dockerfile
FROM nginx:latest
RUN apt-get update && apt-get install -y curl
EXPOSE 80
CMD ["sh", "-c", "echo 'Hello, World!' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]
```

#### クライアント
digと[aws CLI discover-instances](https://docs.aws.amazon.com/cli/latest/reference/servicediscovery/discover-instances.html)で検出したECSタスクのIPアドレスを出力し続ける

```bash:bash
#!/bin/bash

namespace="cloudmap.demo"
service="hello-world"

for i in {1..500}; do
    echo "🍊 ${i}"
    echo "-------- DNS --------"
    dig +short $service.$namespace
    echo "--- Cloud Map API ---"
    aws servicediscovery discover-instances --namespace-name "$namespace" --service-name "$service" --health-status HEALTHY --query 'join(`\n`, Instances[].Attributes.AWS_INSTANCE_IPV4)' --output text
    echo ""
    sleep 1
done
```

### 検証
#### 強制デプロイ
EC2上でクライアントコード実行中にECSサービスでrolling updateを想定して新しいデプロイを強制し、新規ECSタスクが検出できるまでのタイミングを見る

```
🍊 38
-------- DNS --------
10.0.18.77
10.0.128.144
--- Cloud Map API ---
10.0.18.77
10.0.128.144

🍊 39
-------- DNS --------
10.0.128.144
10.0.18.77
--- Cloud Map API ---
10.0.18.77
10.0.128.144

🍊 40 <----------------------- Cloud Mapが先に既存ECSタスクを検出しなくなる
-------- DNS --------
10.0.18.77
10.0.128.144
--- Cloud Map API ---


🍊 41
-------- DNS --------
10.0.128.144
10.0.18.77
--- Cloud Map API ---


🍊 42
-------- DNS --------
10.0.18.77
10.0.128.144
--- Cloud Map API ---


🍊 43
-------- DNS --------
10.0.128.144
10.0.18.77
--- Cloud Map API ---


🍊 44
-------- DNS --------
10.0.18.77
10.0.128.144
--- Cloud Map API ---

🍊 45
-------- DNS --------
10.0.128.144
10.0.18.77
--- Cloud Map API ---

🍊 46
-------- DNS --------
10.0.18.77
10.0.128.144
--- Cloud Map API ---

🍊 47
-------- DNS --------
10.0.128.144
10.0.18.77
--- Cloud Map API ---

🍊 48 <----------------------- Cloud Mapが新規ECSタスクを検出し始め、DNSは新規ECSタスクを2つとも検出する
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---
10.0.24.121

🍊 49
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---
10.0.24.121

🍊 50 <----------------------- Cloud Mapが新規ECSタスクを2つ検出し終える
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---
10.0.24.121
10.0.131.65

🍊 51
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---
10.0.131.65
10.0.24.121
```
<br>
<br>
<br>

#### タスク全停止
EC2上でクライアントコード実行中に起動中ECSタスクを2つとも停止し、その後立ち上がった新規ECSタスクが検出できるまでのタイミングを見る

```
🍊 5
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---
10.0.24.121
10.0.131.65

🍊 6
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---
10.0.24.121
10.0.131.65

🍊 7 <----------------------- Cloud Mapが既存ECSタスクを検出しなくなる
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---
10.0.131.65

🍊 8
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---


🍊 9
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---


🍊 10
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---


🍊 11
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---


🍊 12
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---


🍊 13
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---


🍊 14
-------- DNS --------
10.0.24.121
10.0.131.65
--- Cloud Map API ---


🍊 15
-------- DNS --------
10.0.131.65
10.0.24.121
--- Cloud Map API ---


🍊 16 <----------------------- DNSが既存ECSタスクを検出しなくなる
-------- DNS --------
--- Cloud Map API ---


🍊 17
-------- DNS --------
--- Cloud Map API ---


🍊 18
-------- DNS --------
--- Cloud Map API ---


🍊 19
-------- DNS --------
--- Cloud Map API ---


🍊 20
-------- DNS --------
--- Cloud Map API ---


🍊 21
-------- DNS --------
--- Cloud Map API ---


🍊 22
-------- DNS --------
--- Cloud Map API ---


🍊 23
-------- DNS --------
--- Cloud Map API ---


🍊 24 <----------------------- DNSが新規ECSタスクを2つとも検出する
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 25
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 26
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 27
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 28
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 29
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 30
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 31
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 32
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 33
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 34
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 35
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---


🍊 36
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---


🍊 37
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---
10.0.153.161

🍊 38 <----------------------- Cloud Mapが新規ECSタスクを検出し始める
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---
10.0.153.161

🍊 39
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---
10.0.153.161

🍊 40
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---
10.0.153.161

🍊 41 <----------------------- Cloud Mapが新規ECSタスクを2つ検出し終える
-------- DNS --------
10.0.153.161
10.0.94.226
--- Cloud Map API ---
10.0.94.226
10.0.153.161

🍊 42
-------- DNS --------
10.0.94.226
10.0.153.161
--- Cloud Map API ---
10.0.153.161
10.0.94.226
```

### 結果
Cloud Map APIよりDNSの方が検出が早く、ダウンタイムが起きにくい