Amazon Time Sync Serviceについてのまとめ ～EC2からPTP/NTPで使うには～

# 1. 目的
この記事では、AWS EC2上でAmazon Time Sync Service(ATSS)を使用する方法や周辺知識をまとめます。まずATSSの特徴をまとめたうえで、EC2インスタンスを使って、実際にATSSを使用して時刻同期を行う方法を、NTP、PTPそれぞれのプロトコルに対してまとめます。
ただし、この記事ではLinux系のOS以外については対象外としています。
# 2. Amazon Time Sync Service
Amazon Time Sync Service(ATSS)は、AWS内で時刻を同期するためのシステムで、具体的には各リージョンに配置されたNTPサーバーです。すべての情報が公開されているわけではないものの、以下のような特徴があります。
- 各NTPサーバーはリンクローカルアドレス内（IPv4：169.254.169.123）にある：
実際にStratum0のサーバー（原子時計）がどこにあるかはわからないものの、AWSは各リージョン内に高精度のStratum2やStratum3のNTPサーバーを持っており、これがATSSの核となっています。
これらのNTPサーバーはリンクローカルアドレス内にあるため、
１）EC2インスタンスからは、インターネットを経由せず接続できる
２）VPC外からはアクセスできない
という特徴があり、これらによって高精度の同期を実現しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636063/bf871d36-c27c-bbc9-b179-06a84b50901c.png)

- 主要なLinuxディストリビューションのAMIにはデフォルトでATSSを参照する仕組みがある：
後述しますが、主要なLinuxディストリビューションはchronyを使ってATSSのNTPサーバーを参照するようにデフォルトで設定されています。したがって、単にNTPで時刻を同期したいだけである場合は、**何もしなくてもよい**です。
- デフォルトのプロトコルはNTP
ある種当然ですが、EC2はNTPを使ってATSSのサーバーと時刻同期を行います。前述の通り、ATSSのサーバーとの間はインターネットを通さず接続できるため、精度高く同期できるように設計されています。
- PTPも利用可能
上記の通り、インターネット接続の必要がないことや、同期がリージョン内で済むことから、通常は閉じたネットワークで利用されることの多いPTPもAWSでは利用可能です。ただし、PTPを利用するには
１）特殊なNICが必要である
２）中継するネットワーク機器すべてがPTPに対応している必要がある
ため、以下のリージョン内の以下のインスタンスタイプでしか利用できません。
    - リージョン:
US East (N. Virginia), US East (Ohio), Asia Pacific (Malaysia), Asia Pacific (Tokyo), Europe (Stockholm)
    - インスタンス:
General purpose: M7a, M7g, M7gd, M7i, M8g
Compute optimized: C7a, C7gd, C7i, C8g
Memory optimized: R7a, R7g, R7gd, R7i, R8g, U7i-6tb, U7i-8tb, X8g


# 3. NTPでの同期方法
前述の通り、NTPによる時刻同期はデフォルトで設定済みです。これを確認するには、例えば、us-east-2(Ohio)/t2.micro/Ubuntu-22.04 LTSを起動した状態で
```bash
chronyc sources -v
```
を実行し、chronyが参照するNTPサーバソースを確認すると、以下のように参照しているNTPソース一覧が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636063/f4b79007-b2f6-2279-6b32-3a2be4ef5b4d.png)
上記の**169.254.169.123**はATSSのDNSサーバーのIPアドレスなので、デフォルトでこのサーバーが参照されていることがわかります。


（参考）
Ubuntuではこの参照先は/etc/chrony/chrony.confによって設定されており、AWSの主要AMIではデフォルトで以下のように設定されています。
```:/etc/chrony/chrony.conf
(前略)
# Include configuration files found in /etc/chrony/conf.d.
confdir /etc/chrony/conf.d
(後略)
```
このコンフィグによって、/etc/chrony/conf.dにあるファイルもコンフィグに含めるように指定されています。そして、該当ディレクトリには以下のファイルがあります
```: /etc/chrony/conf.d/00-cpc.conf
## CLOUD_IMG: This file was created/modified by the Cloud Image build process
server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4
```
これらのコンフィグによって、169.254.169.123（ATSSのNTPサーバー）が参照されるようになっています。
# 4. PTPでの同期方法
前述の通り、PTPは
- リージョン:
US East (N. Virginia), US East (Ohio), Asia Pacific (Malaysia), Asia Pacific (Tokyo), Europe (Stockholm)
- インスタンス:
General purpose: M7a, M7g, M7gd, M7i, M8g
Compute optimized: C7a, C7gd, C7i, C8g
Memory optimized: R7a, R7g, R7gd, R7i, R8g, U7i-6tb, U7i-8tb, X8g

でのみサポートされています。したがって、以下のステップを踏んでも、上記リージョン＆＆インスタンスでない限り使えないことに注意が必要です。なお、手順は以下の2つのWebサイトにも説明がありますが、**これに従うだけでは使えなかったので注意が必要です。**

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configure-ec2-ntp.html#ptp-hardware-clock-requirements

https://github.com/amzn/amzn-drivers/tree/master/kernel/linux/ena#linux-kernel-driver-for-elastic-network-adapter-ena-family



1. 環境
今回は、us-east-2(Ohio)/c7i.large/Ubuntu-22.04 LTSを使用しています。このフローもこの環境に対応したものです。OSが異なる場合は異なる対応が必要です。

1. ドライバのコンパイル
amzn-driversが提供しているElastic Network Adapter (ENA)をコンパイルしてロードします。Ubuntuのバージョンが3.13.0-31未満の場合、コンパイル時の環境変数として、カーネルのABIが必要になるため
    ```:バージョンの取得
    uname -r
    ```
    を実行し、バージョンを取得します。
例：
    ```
    3.13.0-29-generic
    ```
    を取得した場合は、29がABIになります。これを後述の\<ABI\>の部分に代入して使います。
    ```:コンパイル
    sudo apt-get update
    sudo apt install linux-headers-$(uname -r)
    sudo apt-get install make gcc
    git clone https://github.com/amzn/amzn-drivers.git
    cd kernel/linux/ena
    ENA_PHC_INCLUDE=1 make [UBUNTU_ABI=<ABI>]
    ```
    
1. ドライバのロード
以下のコマンドでコンパイルしたドライバに差し替えます。
    ```:ドライバのロード
    sudo rmmod ena && sudo insmod ena.ko phc_enable=1
    ```
    ここまで完了すると、PTPハードウェアクロックが登録され、PTPによる時刻同期を開始できるようになります。登録が成功している場合、/dev/ptp0というディレクトリができているので、
    ```
    ls /dev/ptp0
    ```
    等でディレクトリの存在を確認できれば成功です。
1. 参照サーバの追加＋chronyの再起動
NTPの項でも説明した通り、chronyのコンフィグは/etc/chrony/chrony.confに記載されています。このファイルの任意の行に
    ```:参照方法の追加: /etc/chrony/chrony.conf
    refclock PHC /dev/ptp0 poll 0 delay 0.000010 prefer
    ```
    を追加することで、PTP Hardware Clock（PHC）を使用した参照が追加され、PTPでの同期を開始できます。さらに、以下のコマンドでchronyを再起動します。
    ```:chronyの再起動
    sudo systemctl restart chronyd
    ```
    この時点でPTPでの同期が開始されます。実際に
    ```
    chronyc sources
    ```
    を実行すると、以下の通り”PHC0”としてPTPで同期が行われていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636063/315e8605-dd3f-d371-6548-21e6aa4da453.png)

# 5. まとめ
- Amazon Time Sync Service (ATSS)は、各リージョン内にある高位のNTPサーバーを使用することで高精度の時刻同期を達成するためのフレームワーク
- ATSSはリンクローカルアドレス内にあるため、VPC内から高速で安定した通信を実現しており、このために安定した時刻同期を達成できている
- 主なAMIをもとにしたEC2インスタンスはデフォルトでNTPでATSSのサーバーと同期している
- 特定のリージョン・インスタンスタイプでは、マニュアル操作を行えばPTPでのより高精度な同期も行える

# 6. 参考


https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configure-ec2-ntp.html#ptp-hardware-clock-requirements

https://github.com/amzn/amzn-drivers/tree/master/kernel/linux/ena#linux-kernel-driver-for-elastic-network-adapter-ena-family