ネットワーキング

効果的な Cloud NAT モニタリングのための 6 つのベスト プラクティス

cloud nat.jpg

※この投稿は米国時間 2021 年 2 月 9 日に、Google Cloud blog に投稿されたものの抄訳です。

分散アプリケーションを構築するすべてのユーザーにとって、Cloud クラウド ネットワーク アドレス変換(NAT)は強力なツールです。NAT を使用すると、スケーラビリティと安全性を保ちつつ、Compute Engine および Google Kubernetes Engine(GKE)のワークロードを、外部 IP を使用している外部アクセスにさらすことなくインターネット リソースにつなげることができます。

Cloud NAT はプロキシレス設計を特徴とし、Andromeda SDN レイヤに NAT を直接実装します。そのため、ワークロードのパフォーマンスに影響を及ぼすことなく、さまざまな VM、リージョン、VPC に無理なくスケールできます。

さらに、Cloud NAT をプライベート GKE クラスタと組み合わせると、インターネットから分離された安全なコンテナ化ワークロードが有効になりますが、引き続き外部 API エンドポイントとの通信やパッケージ更新のダウンロードを行い、外向きインターネット接続を使用するその他のユースケースに対応することはできます。

とても優れたツールですが、どのように始めればよいでしょうか?たとえば、モニタリングはインフラストラクチャ プラットフォームに欠かせません。ワークロードを Cloud NAT にオンボードする際は、Cloud NAT をモニタリングして、外向きインターネット接続に影響が出始める前に、問題を早期に発見できるようにすることをおすすめします。

Cloud NAT を使用しているお客様をサポートした経験から、デプロイをモニタリングするためのベスト プラクティスをいくつかご紹介します。各ベスト プラクティスを Cloud NAT の効果的な使用にお役立ていただければ幸いです。

ベスト プラクティス 1: Cloud NAT の容量を事前に計画する

Cloud NAT は基本的に、多数のインスタンスに外部 IP アドレスを「拡張」することで機能します。これを行うために、外部 IP ごとに利用可能な 64,512 個の送信元ポート(有効な 65,536 個の TCP / UDP ポートから最初の 1,024 個の特権ポートを引いた数と等しい)をすべてのスコープ内インスタンスに分割します。そのため Cloud NAT ゲートウェイに割り当てられた外部 IP アドレスの数に応じて、ポートと外部 IP の観点から Cloud NAT の容量を事前に計画する必要があります。

可能な限り、Cloud NAT の外部 IP 自動割り当て機能を使うようにしてください。この機能は大半の標準的なユースケースに適しています。Cloud NAT の制限と割り当てにより、手動で設定した外部 IP アドレスの使用が制限される場合がある点にご注意ください。

Cloud NAT のキャパシティ プランニングを定める重要な変数が 2 つあります。

  1. Cloud NAT ゲートウェイを利用するインスタンスの数

  2. インスタンスごとに割り当てるポートの数

2 つの変数の積を 64,512 で割ると、Cloud NAT ゲートウェイに割り当てる外部 IP アドレスの数が求められます。

((インスタンス数) x (インスタンスあたりのポート数)) ÷ 64512 == 外部 IP の数

 

手動割り当てを使用する必要がある場合は、求めた外部 IP アドレスの数が重要です(自動割り当ての制限を超えた際には追跡することも重要です)。

外部 IP の容量をモニタリングするために有用な指標は、nat_allocation_failed NAT GW 指標です。この指標は、障害がないことを示す 0 を維持する必要があります。この指標にどの時点でも 1 以上が記録される場合は障害が発生していることを意味し、NAT ゲートウェイに割り当てる外部 IP アドレスを増やす必要があることを示しています。

ベスト プラクティス 2: ポート使用率をモニタリングする

ポート使用率は追跡すべき非常に重要な指標です。上述のベスト プラクティスで詳しく説明したとおり、Cloud NAT の主要なリソースは外部 IP とポートのペアです。インスタンスが最大ポート使用率に達すると、インターネットへの接続が切断される可能性があります(ワークロードから Cloud NAT ポートを使用する対象の詳細については、こちらの説明をご覧ください)。

Cloud Monitoring では、次のサンプル MQL クエリを使って Cloud NAT のポート使用率を確認できます。   

  fetch gce_instance
| metric 'compute.googleapis.com/nat/port_usage'
| group_by 1m, [value_port_usage_mean: max(value.port_usage)]
| every 1m
| top 25, max(val())

インスタンスごとのポート割り当てが最大ポート使用率に近づいている場合は、インスタンスごとに割り当てるポートの数を増やすことを検討してください。

ベスト プラクティス 3: Cloud NAT で切断が発生する原因をモニタリングする

特定のシナリオで、Cloud NAT が送信元ポートの割り当てに失敗して接続できない場合があります。こうしたシナリオの最もよくある原因は、インスタンスのポートが不足していることです。この場合、dropped_sent_packets_count 指標に「OUT_OF_RESOURCES」タイプの切断と表示されます。インスタンスごとに割り当てられるポートの数を増やすことで、切断が発生しないようにすることができます。

もう 1 つのシナリオはエンドポイント非依存性による切断です。このケースでは、エンドポイント非依存性を適用することで Cloud NAT が送信元ポートを割り当てられなくなります。この場合は「ENDPOINT_INDEPENDENCE_CONFLICT」タイプの切断と表示されます。

次の MQL クエリを Cloud Monitoring ダッシュボードに追加すると、これらの切断を追跡することができます。

  fetch gce_instance
| metric 'compute.googleapis.com/nat/dropped_sent_packets_count'
| align rate(1m)
| every 1m
| group_by [metric.reason],
    [value_dropped_sent_packets_count_aggregate:
       aggregate(value.dropped_sent_packets_count)]

「ENDPOINT_INDEPENDENCE_CONFLICT」タイプの切断回数が増えている場合は、エンドポイントに依存しないマッピングを無効にするか、こちらの方法のいずれかを試して発生率を減少させましょう。

ベスト プラクティス 4: Cloud NAT ロギングを有効にし、ログベースの指標を活用する

Cloud NAT の Cloud Logging を有効にすると、問題を積極的に検出できるだけでなく、トラブルシューティングのための付加的な情報が得られます。ロギングを有効にする方法は、こちらの手順でご確認いただけます。

ロギングを有効にすると、ログベースの指標を作成し、これらのログを使用してパワフルな指標を構築することができます。

たとえば、次のコマンドと YAML 定義ファイルを使用して、送信元 / 宛先、IP / ポート / プロトコル、ゲートウェイ名でグループ化された指標として NAT 割り当てイベントを公開します。次のベスト プラクティスでは、各種指標を使用する方法について確認していきます。

  gcloud beta logging metrics create nat_gw --config-from-file=metric.yaml
Created [nat_gw].
  metric.yaml
  description: CloudNAT gateway allocation metrics
filter: |
  resource.type="nat_gateway" 
labelExtractors:
  allocation_status: EXTRACT(jsonPayload.allocation_status)
  dest_ip: EXTRACT(jsonPayload.connection.dest_ip)
  dest_port: EXTRACT(jsonPayload.connection.dest_port)
  gateway_name: EXTRACT(jsonPayload.gateway_identifiers.gateway_name)
  protocol: EXTRACT(jsonPayload.connection.protocol)
  region: EXTRACT(jsonPayload.endpoint.region)
  src_ip: EXTRACT(jsonPayload.connection.src_ip)
  src_port: EXTRACT(jsonPayload.connection.src_port)
  vm_name: EXTRACT(jsonPayload.endpoint.vm_name)
  zone: EXTRACT(jsonPayload.endpoint.zone)
metricDescriptor:
  labels:
  - key: allocation_status
  - key: gateway_name
  - key: src_port
  - key: vm_name
  - key: zone
  - key: dest_ip
  - key: region
  - key: dest_port
  - key: src_ip
  - key: protocol
  metricKind: DELTA
  name: projects/[PROJECT_ID]/metricDescriptors/logging.googleapis.com/user/nat_gw
  type: logging.googleapis.com/user/nat_gw
  unit: '1'
  valueType: INT64
name: nat_gw

ベスト プラクティス 5: 上位のエンドポイントとその切断をモニタリングする

Cloud NAT の 2 つのタイプ(「ENDPOINT_INDEPENDENCE_CONFLICT」と「OUT_OF_RESOURCES」)では、同一の外部 IP とポートのペアに多数の同時接続があると、切断される回数が増加します。通常よりも切断が増えている原因のエンドポイントを特定することが、非常に有効なトラブルシューティング手段になります。

このデータを公開するには、前のベスト プラクティスで説明したログベースの指標を使用できます。次の MQL クエリは、切断の原因になっている上位の宛先 IP とポートをグラフ化するものです。

  fetch nat_gateway
| metric 'logging.googleapis.com/user/nat_gw'
| filter (metric.allocation_status == 'DROPPED')
| align rate(1m)
| every 1m
| group_by
    [metric.gateway_name, metric.dest_ip, metric.dest_port, metric.protocol],
    [value_nat_gw_aggregate: aggregate(value.nat_gw)]

結果のグラフの例は次のようになります。

この情報をどう扱えばよいでしょうか?こうしたエンドポイントへの集中接続をできるだけ多くのインスタンスに分散させることが理想的です。

それができない場合は、もう 1 つの軽減方法として、別の Cloud NAT ゲートウェイを通じてエンドポイントにトラフィックをルーティングします。そのためには、トラフィックを異なるサブネットに配置し、別のゲートウェイに関連付けます(インスタンスごとにポート割り当てを増やします)。

最後に、外部 IP と関連付けたインスタンスを通じてこの種のトラフィックを処理することで、こうした Cloud NAT の切断を軽減することができます。

なお GKE を使用している場合は、送信元 NAT トラフィックを無効にして特定の IP に限定するよう ip-masq-agent を調整し、競合の可能性を減らすことができます。

ベスト プラクティス 6: 正規化されたエラー率のベースラインを設定する

これまでに取り上げたすべての指標は無名数であり、ご使用の環境にとって意味を持つ場合とそうでない場合があります。1 秒あたり 1,000 回の切断が、トラフィック パターンによっては懸念の原因になる場合もあれば、まったく問題にならない場合もあります。

トラフィック パターンを踏まえると、切断が発生したとしても、それはユーザー エクスペリエンスに影響しない程度の通常の状態であるという可能性もあります。これはエンドポイント非依存性で切断されたインシデントに特に関係があり、無作為かつまれなケースといえます。

ベスト プラクティス 4 で作成したものと同じログベースの指標を利用し、次の MQL クエリを使用して、ポート割り当ての総数で数値を正規化できます。

  fetch nat_gateway :: logging.googleapis.com/user/nat_gw 
 | filter resource.region = 'us-west1'
 | every 1m
 | group_by [metric.gateway_name],
         ( sum(if(metric.allocation_status == 'DROPPED', val(), 0)) / sum(val()) )*100

切断指標の正規化は、ある切断回数が、トラフィック レベルの尺度でどの程度の意味を持つかを把握するうえで役立ちます。また、「正常な」レベルの切断回数のベースラインを設定し、切断回数が異常なレベルになったときに簡単に検出することもできます。

Cloud NAT のモニタリングを徹底する

Cloud NAT を使用すると、外部 IP からの外部アクセスのリスクにさらされることなく、分散型、ハイブリッド型、マルチクラウド型のアプリケーションを構築することができます。Cloud NAT を心配なくご利用になれるよう、上述のベスト プラクティスをぜひ実践してください。ページャーを作動させることなくパケットが流れ続けます。詳しくは、Cloud NAT の概要をご確認いただくか、さまざまな Cloud NAT のログと指標のオプションをご検討ください。Compute EngineGKE のチュートリアルで Cloud NAT をお試しください。

-戦略的クラウド エンジニア Edwin Chiu

-カスタマー エンジニア兼ネットワーキング スペシャリスト Ghaleb Al-Habian