Azureの可用性ゾーンの少し深めの話

Azureかなり理解した気になっていましたが、可用性ゾーンを考慮した設計が全然できていなかったので初心者です。Azure全然わからん。

本記事の内容はドキュメントを読めば大体書いてある内容ですが、書いてなかったりすることも書いてあるかもしれません。


可用性ゾーン（Availability Zones）について
-----------

可用性ゾーンについて完全に理解している人は多いと思いますが、私の理解も兼ねて書きます（誤ってたらこっそり編集リクエストください）。

### 可用性ゾーンとは

https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#availability-zones

Azureにおいては、1つのリージョンに1つ以上のゾーンが存在し、その中に1つ以上のデータセンターが存在しているという設計になっています。
（なお、データセンターの電源、冷却、およびネットワークインフラストラクチャは独立しており、この部分の障害が別のデータセンター影響を与えないように作られている。）

複数のゾーンを組み合わせて使うことで可用性(Availability)を向上できる仕組みになっています。そのことから「可用性ゾーン（Availability Zones）」と呼ばれています。

例えば、東日本には3つのゾーンが存在しており、[公開情報](https://azure.microsoft.com/ja-jp/global-infrastructure/geographies/#geographies)では、東京と埼玉に存在します。なので3つのゾーンのうち1つは東京と埼玉のいずれかに存在するでしょう。
なので、適切に運用できていれば、東京のあるゾーンが何らかの理由でダウンしても埼玉のゾーンが無事であればサービスを存続できるはずというわけですね！(~~ほんとぉ？~~)

### 可用性ゾーンは物理的な位置を決められない

なお、選択できるゾーンの番号(ゾーン1,ゾーン2,ゾーン3)はサブスクリプション毎に振られた論理的な番号です。
実際にどのゾーンを指し示すのかはサブスクリプション毎に違います。AWSのゾーンIDみたいですね。

~~ソースは・・・どこかで見た気がするんですが、見つかりませんでした・・・別で書きます。~~


(2022/06/06 追記): ドキュメントに書いてありました。[2021年12月頃に追記されていました](https://github.com/MicrosoftDocs/azure-docs/commit/580748c38190f17d2218d7e9691bc107f9625cb5#diff-b83237cb02d7097ceaea051147272ad69be2553e85417fc21c55caedd8a37ee0R33)。

https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#availability-zones

> Each data center is assigned to a physical zone. Physical zones are mapped to logical zones in your Azure subscription. Azure subscriptions are automatically assigned this mapping at the time a subscription is created.

このソースを見つけられず、サブスクリプション違いの同ゾーン番号のVM間のレイテンシを見る事でこの挙動を確認したのでリンクを載せておきます。

https://qiita.com/fukasawah/items/7acd651425029cd52558

### 可用性ゾーンの障害範囲どこまで？

https://docs.microsoft.com/ja-jp/azure/architecture/high-availability/building-solutions-for-high-availability

> 各ゾーンは、独立した電源、冷却、ネットワークを備えた1つ以上のデータセンターで構成されています。

ここまでいくと「東日本が何らかの理由で喪失する場合もあるのでは？」という話も出てきます。「隕石が降ってきて東日本が消失したら・・・？」とか言い出す人もいます。そのときは地理冗長を検討することとなります。



可用性ゾーンを活かす設計を考え続ける
----------------------

可用性ゾーン、素晴らしいですね。
しかし、Azureはそういった仕組みを責任もって提供してくれているだけで、仕組みを使って設計するのはユーザの責任です。
設計がダメだと可用性ゾーンのメリットは享受できなくなります。それはユーザの責任です。

「可用性ゾーンを活かす」はある意味、呪縛になります。1つでも満たないところがあるとそこが単一障害点になり得るからです。

クラウドサービスは良くも悪くもアップデートしていきます。2021年はゾーン冗長の対応したサービスも多くありましたが別に乗り換えまではサポートしてくれません。サービスを検討するときは可用性ゾーンを使えるか・ゾーン冗長に対応しているか、コストの影響はいくらか、そもそも可用性が必要かを常に求められるでしょう。



### 西日本は可用性ゾーンに対応していない => 2025/03/21 対応開始

~~2022/03/08時点ではゾーンが1つしかないので、可用性ゾーンを選択するなどのことができません。
東日本では対応しているリソースも当然対応できないので注意しましょう。~~

2025/03/24 追記: またパブリックIPやStorageAccountなどの一部のリソースですが、西日本でも可用性ゾーンが使えるようになり始めています。

ドキュメントに可用性ゾーンに対応したリージョンが上がっています。

https://learn.microsoft.com/ja-jp/azure/reliability/regions-list


### 可用性ゾーンの「ゾーンなし」とは何か

例えば「パブリックIPアドレス」を作るときに指定できます。さて、どういう意味でしょうか？

これ、ドキュメントに詳しく書かれていないようで「ナニコレ？」となる人はいたと思いますが、資格をお持ちの方におかれましては当たり前のようにご存じなのかもしれません。

GitHubでもどういう意味？っていうissueが上がっていました。

- https://github.com/MicrosoftDocs/azure-docs/issues/69949
- https://github.com/MicrosoftDocs/azure-docs/issues/39091

[issueの答え](https://github.com/MicrosoftDocs/azure-docs/issues/39091#issuecomment-533731989)によると「ゾーンなしはランダムでゾーンを選ぶ（決め方はあるので厳密にはランダムではないがAzureユーザからは推測できない）」という感じですね。
サポートに聞いたところ、同様の回答でした。また「ゾーンなし」という特殊な「ゾーン」が存在するわけでもないとのことでした。

とりあえず動かしたり、可用性ゾーンのメリットを取る必要が明らかにない場合に選ぶぐらいがよいでしょう。




### 「ゾーン冗長」を知る


https://docs.microsoft.com/ja-jp/azure/architecture/high-availability/building-solutions-for-high-availability#zonal-vs-zone-redundant-architecture

これも、ドキュメントにある通りですが「ゾーン冗長」に対応したリソースが存在しています。
要は「ゾーン冗長」となっているリソースは「可用性ゾーンを分けて配置するには・・・」と考えなくて良いリソースになります。

例えばパブリックIPです。

https://docs.microsoft.com/ja-jp/azure/virtual-network/public-ip-addresses#standard

Public IP Address(SKU=Standard)で、複数ゾーンが存在するリージョンにおいて「ゾーン冗長(zone-redundant)」というものが選べます。
私も良くわかっていませんが、Azureの内部ネットワークのルーティングの仕組みにより、いずれかのゾーンでトラフィックを受け付けることができるようになるようです。

なおゾーン冗長なPublic IP Addressは、SKUがStandardでしか有効にできない上に、作成したPublic IP Addressは対応したリソースにしか使えません。Azure LoadBalancer(SKU=Standard)は対応していますが、Azure LoadBalancer(SKU=Basic)は対応できません。

ただ、各ゾーン毎にPublic IPを1つ、合計3つ用意して、Traffic Managerで分散して、Load BalancerのフロントエンドIP構成を3つ用意して・・・と、やらなくてよくなります。逆をいえば特定のゾーンに振り分けるといったことはできなくなります。（これがデメリットになることは無いと思いますが。）


「ゾーン冗長」に対応しているリソースは他にもあります。

例えば、Azure StorageのZRSを使った場合はゾーン冗長なリソースとなっていますが、内部はTrafficManagerで振り分けをしているだけです。

https://jpaztech.github.io/blog/storage/introduction-of-azure-storage-redundancy/

2021年9月頃にAzure Functionもゾーン冗長のサポートがアナウンスされていましたが、多分一緒だと思います（未確認）


### ゾーン間の通信のデメリットを知る

可用性ゾーンに対応するのは良いことばかりではありません。

- レイテンシ増加（同一ゾーン＜別ゾーン＜別リージョン）
- 将来的にゾーン間の通信は別途料金がかかる（後述）

主にレイテンシ増加です。これが問題になるかどうかはアプリケーションによります。シビアな場合は必ず**設計前に**計測しましょう。

ちなみに2021/05/31頃の東日本→西日本のリージョン間の月平均のレイテンシが8msだそうです。
https://docs.microsoft.com/en-us/azure/networking/azure-network-latency#may-2021-round-trip-latency-figures

別で測りましたが、東日本内の別ゾーン間は3ms弱でした。


### 可用性ゾーンを活かせないサービスを知る

一応、可用性ゾーンもしくはゾーン冗長に対応したサービスの一覧があります。結構あります。

https://docs.microsoft.com/ja-jp/azure/availability-zones/region-types-service-categories-azure#available-services-by-category

https://docs.microsoft.com/en-us/azure/availability-zones/az-region#zone-resilient-services

逆に言うと、ここに無いのは「対応しているかわからないサービス」となります。こういうところが厳しいですね。


その中で対応していそうでしていないものがありました。NAT Gatewayです。(2022/02/28時点)

NAT GatewayはSNATを行えるマネージドサービスで、内部から外部に出ていくときのIPをNAT Gatewayに集約するときなどに使います。NAT Gatewayはゾーンを指定することができますが、**1か所のみ**です。
また、NAT Gatewayはサブネットに紐づける必要があるため、どうしても1Subnet-1NAT Gatewayという関係になります。しかしSubnetはゾーンを意識しないのでこの制約は相性が悪いと言えます。[フィードバックはあり認識はしているようで今後のアップデートで対応する可能性はあります](https://feedback.azure.com/d365community/idea/3c5a1b30-8b26-ec11-b6e6-000d3a4f0789)が、現状は適切に分散させる方法はなさそうです。


蛇足ですが、SNATが必要な場合、どれを選べばよいかという指標について、下記のドキュメントを見ると2番目のNAT GatewayがBestとなっていますが、可用性ゾーンの観点ではNGといえます。最近、図付きになり「よさそう」感が高まっていますが可用性ゾーンの観点ではNGです。

https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections#scenarios

さらに蛇足ですが、Azure Load Balancer(SKU=Standard)を使う場合、Azure Load BalancerにはSNATのような機能を持っており、上記のゾーン冗長パブリックIPに対応しているので使えなくはないかもしれません。VMやVMSSでの運用をしている場合はこれを使うのも手でしょう。

これらの他のSNATの手段については日本の中の人の記事が詳しいです。

https://jpaztech.github.io/blog/network/snat-options-for-azure-vm/

「やだやだ！可用性も取りたい！SNATも欲しい！」と駄々をこねると、現状では[仮想アプライアンスを置く](https://docs.microsoft.com/ja-jp/azure/architecture/reference-architectures/dmz/nva-ha)かAzure Firewallを使うことになり、お高くつきます。安く収めたいとなると、Azure LoadBalancerをSNATのために置くことになります。

ほとんどSNATの話になっちゃっていますが、こんな感じで可用性ゾーンに対応していない場合もあり、どうするかを探るか、妥協したりしないといけません。




### 可用性ゾーン間の転送料金の課金について（いつから？何が対象か？）

現時点では無料ですが、将来的には有料になる可能性があります。

~~2021/08/15時点ではBandwidthの料金ページには以下のように、2022/07/01から請求すると書かれています。~~

https://azure.microsoft.com/ja-jp/pricing/details/bandwidth/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/66631ea7-8747-94c2-ea67-46c57b22aeed.png)

追記: 2022/06/17時点では2023/07/01からに変わっています。

ただInternetArchiveで見たところ、2019/08頃は課金対象だったが、2019/12の時点では無料となり、それが引き伸ばしになっているようです。

<details>
<summary>InternetArchiveの履歴で確認した引き伸ばされている様子</summary>

- 2019/08/27 時点では課金対象だった（？）
    - https://web.archive.org/web/20190827223931/https://azure.microsoft.com/en-us/pricing/details/bandwidth/
- 2019/12/16 時点では無料（2020/1から請求開始と書かれている）
  - https://web.archive.org/web/20191216182111/https://azure.microsoft.com/en-us/pricing/details/bandwidth/
- 2020/04/26 時点では無料（2020/7から請求開始と書かれている）
  - https://web.archive.org/web/20200426173144/https://azure.microsoft.com/en-us/pricing/details/bandwidth/
- 2020/07/20 時点では無料（2021/2から請求開始と書かれている）
  - https://web.archive.org/web/20200720063231/https://azure.microsoft.com/en-us/pricing/details/bandwidth/
- 2021/02/28 時点では無料（2021/7から請求開始と書かれている、FAQの表題に年月が入るようになった）
  - https://web.archive.org/web/20210228162359/https://azure.microsoft.com/en-us/pricing/details/bandwidth/
- 2021/05/29 時点では無料（2022/7から請求開始と書かれている）
  - https://web.archive.org/web/20210529225831/https://azure.microsoft.com/en-us/pricing/details/bandwidth/

</details>

対象については、上記の料金ページのFAQにかかれている以下の内容になります。

> ### 2022 年 7 月 1 日から Availability Zones のデータ転送の測定による課金の対象となるのは、どの種類のデータ転送ですか?
> 以下の可用性ゾーンのデータ転送が課金対象です。
>
> - ある可用性ゾーンにデプロイされた VNet リソースから同一 VNET 内の別の可用性ゾーンにある別のリソースへのデータ転送 (イングレスとエグレス両方)
>
> 以下の可用性ゾーンのデータ転送は課金対象外です。
>
> - 同一の可用性ゾーン内にある VNet リソース間のデータ転送
> - 同一の Azure リージョン内にある VNet リソースとパブリック IP アドレス間のデータ転送
> - 可用性ゾーン間でピアリングされた VNet にある VNet リソース間のデータ転送。このデータ転送は、VNet ピアリング料金に従って課金されます。
>
> #### 同じリージョン内での Azure サービス間のデータ転送は課金されますか?
> いいえ。たとえば、同じリージョン内の Azure SQL Database の場合、追加のデータ転送費用はかかりません。

「VNetリソース」という単語がまた聞きなれない上に「VNet自体も(Azureの)リソースなんだからVNet自体を指すんじゃないか」とか誤解を招くと思うんですが、一応ドキュメントではちょろちょろと出てきます。

- https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-faq#what-does-the-vnet-service-endpoint-protect---vnet-resources-or-azure-service

サポートに確認したところ「Azure Virtual Network(VNet)上に構成されたリソース」を指すものとみて良いようです。例えば、VirtualMachineで使うNICやApplicationGatewayとかですね。なので、ApplicationGateway→VirtualMachine間の通信でゾーンを跨いだ場合は該当します。

- Azure SQL DatabaseやStorage Accountに対するサービスエンドポイント接続時の通信は？
    - 一応上記のFAQにある通り該当しません。該当しないとサポートからお返事をもらっています。
- AppServiceなどVNET統合した後の通信はどうなるのか？
    - 該当しないとサポートからお返事をもらっています。VNETリソース間に該当しないからだそうです。

ではLoadBalancer→VirtualMachine間はどうなのかというと不明です。私はApplicationGatewayとは異なりLoadBalancerはVNETに紐づかないリソースなので該当しないと思っています。「同一の Azure リージョン内にある VNet リソースとパブリック IP アドレス間のデータ転送」に該当すると思います。ゾーンが異なるPublic IPを紐づけたVMは該当しないので、それと一緒です。

「「思ってます」じゃなくてサポートに聞けよ。試せよ」という感じなんですが、一々ドキュメント見て触れられていないことを確認してから、聞くのが面倒で面倒で・・・AWSのFAQぐらいの内容でいいから書いてほしい・・・

ちなみにPublic IPのゾーンと異なるゾーンのVMを作って紐づけることができます。Portal上からIP選択時にフィルタされて選択できないので作れないのですが、CLIではできました。（ゾーンを跨ぐオーバーヘッドが発生するしそれぞれのゾーンで障害があると影響を受けるより弱い構成になるので何も良いこともないですが。）