9. ネットワーク#
VLANの自動化はラボで3週間稼働していた。3台のスイッチ、ベンダーごとに1台ずつ、すべてのワークフローが通過した。チームは自信を持っていた。最初の本番実行で、800台のキャンパススイッチのうち23台が失敗した。すべてHPEだった。すべて、誰もドキュメント化していなかったファームウェアバージョンを実行していた。
PlaybookはVLAN設定をプッシュした後、各デバイスからのエラーレスポンスを確認していた。モダンなHPEファームウェアでは、すでに存在するVLANはエラーコードduplicate-vlanを返す。この古いファームウェアバージョンでは、同じ条件がvlan-existsを返した。Playbookはduplicate-vlanをべき等シグナルとして扱うように書かれていた。つまり「これはすでに存在している、問題ない」という意味だ。vlan-existsを処理するようには書かれていなかったので、そのレスポンスを失敗として扱った。HPEフリートの3分の1が失敗を報告した。ロールバックはクリーンに実行された。ネットワークチームが実際に設定されたスイッチとそうでないスイッチを手動で監査する間、アプリケーションチームのチケットはさらに3時間オープンのままだった。
自動化は間違っていなかった。ネットワークに、誰もドキュメント化していなかった意見があったのだ。
6ヶ月後、同じチームはBuilding Bを反映したcontainerlabトポロジーを持っていた: 24台のスイッチ、一致するベンダーイメージ、HPEノードはSource of Truth (SoT)に記録された本番ファームウェアバージョンにロックされていた。そのトポロジーに対するVLANワークフローの最初のテスト実行で、8台のHPEノードがまさにそのエラーコードで失敗した。チームはHPEアダプターのべき等レスポンスのリストにvlan-existsを追加した。再実行: 24台のノードすべてが通過した。本番デプロイメント: 800台のスイッチ、ゼロの失敗。
違いは良いコードではなかった。現実を反映したテスト環境だった。
本章ではパート2を通じて常に暗黙的だったブロックを扱う: ネットワーク自体だ。これまで構築してきたすべてのビルディングブロックは自動化チームによって設計され、ドキュメント化されたインターフェースに従って動作する。ネットワークは受け継いだものだ。それには癖があり、多様なインターフェースがあり、ファームウェアの不整合があり、ベンダー、プラットフォーム、ソフトウェアの世代によって異なる機能がある。第9章は2つの問いを扱う: 自動化を確実にするためにネットワークに何が必要か、そして本番に触れる前に自動化ロジックをどう安全に検証するか?
9.1. 基礎#
9.1.1. コンテキスト#
第3章では、NAF Frameworkの7つのブロックの1つとしてネットワークを導入した: 自動化チームが「所有」しない唯一のブロック(ネットワークエンジニアリングのスコープにある)。彼らはそれを設定し、観察し、そのインテントをモデル化するが、オペレーティングシステム、データモデル、またはAPIインターフェースは構築しなかった。その依存関係は、その上のプラットフォームのすべての設計決定を形作る。
第5章ではExecutorの書き込みパスを詳しく扱った: 自動化ロール、パラメーター化されたタスク、べき等チェックがどう機能するか。第5章が所与とするのは、もう一方のデバイスが信頼性があり一貫したインターフェースを公開しているということだ。第9章はその仮定が成立するかどうか、そして成立しない場合に何をするかを扱う。
第6章ではCollectorの読み取りパスを扱った: gRPC Network Management Interface (gNMI)ストリーミングテレメトリ、SNMPポーリング、データ正規化パイプライン。第9章ではそれらのパスのデバイス側の前提条件を扱う: コレクターが一貫して読み取れるために、ネットワークデバイスについて何が真でなければならないか。
第9章はパート2を締めくくる。前の6章は自動化プラットフォームを構築した: インテントを保存する場所、それを実行する方法、結果を観察する方法、すべてを調整するエンジン、コンシューマーに公開するサーフェス。本章ではプラットフォームが常に指し示していたものを扱う。
9.1.2. ゴール#
3つのゴールがネットワークブロックの自動化プラットフォームへの貢献を定義する:
ネットワークインフラのフルスペクトルを理解してナビゲートする。 大規模な自動化プラットフォームはキャンパススイッチ、データセンターファブリック、クラウドVPC、Kubernetesオーバーレイ、オーバーレイコントローラー、レガシー機器を同時に扱う場合がある。各タイプは異なるプログラム可能なインターフェースを公開する。プラットフォームは単一の最小公倍数の抽象化に崩壊せずにそれらすべてを処理しなければならない。
本番に触れる前に自動化ロジックを検証し、新しいネットワークアーキテクチャの設計をサポートする。 シミュレーション環境は2つの目的を果たす: 本番インシデントで数時間かかる代わりにラボで数分のコストでロジックエラー、インターフェースコントラクト違反、デバイス固有の癖を捕捉する本番前ゲート、そして新しいネットワークアーキテクチャがハードウェアが注文される前に探索され検証される設計環境。
ネットワークが進化しても自動化プラットフォームを安定させる。 新しいベンダーが追加される。ファームウェアバージョンが変わる。新しいインフラタイプが到来する。プラットフォームはネットワークが変わるたびにすべてのワークフローにアドホックなパッチを当てるのではなく、抽象化戦略を通じてこの変化を吸収するように設計されなければならない。
9.1.3. 柱#
3つの柱がこれらのゴールを支える。機能ごとに1つずつだ:
- ネットワークインフラスペクトルとプログラム可能なインターフェース: プラットフォームが自動化しなければならないネットワークタイプの全範囲、および各タイプがExecutorとCollectorに公開するインターフェース。
- シミュレーションとテスト環境: 本番前検証のためのツールチェーン。異なるラボ環境タイプがどこに適合するか、第7章のSagaパターンとどう接続するか、そしてどうスケールするか。
- 抽象化戦略: 基礎のネットワークが変化してもベンダー、プラットフォーム世代、インターフェースプロトコルに関係なく自動化プラットフォームが安定したままでいられる構造的アプローチ。
9.1.4. スコープ#
スコープ内:
- ExecutorとCollectorがネットワークデバイスに到達するインターフェース。NETCONFとgNMIはどちらも設定とテレメトリ操作をサポートする。ユースケースごとの選択は運用上の強みに依存し、プロトコルの排他性には依存しない。プロトコルはしばしばブロック間で共有され、操作タイプが異なる。
- 本番前に自動化を検証するテスト環境と方法論
- マルチベンダーおよびマルチプラットフォームの異種性を管理するための抽象化戦略
- 自動化設計へのクラウド、Kubernetes、オーバーレイネットワーキングの影響
スコープ外:
- 設定生成とテンプレートレンダリング(Source of Truth (SoT)、第4章)
- 実行メカニクス: 自動化ツーリングがタスクをどう実行するか(Executor、第5章)
- テレメトリ収集パイプライン: メトリクスが時系列データベースにどう流れるか(Observability、第6章)
境界は一貫している: 第9章はプラットフォーム側ではなく、各インターフェースのネットワーク側をカバーする。
9.2. 機能#
ネットワークブロックはNAFフレームワークの中で自動化プラットフォームがコントロールしない唯一のビルディングブロックだ。ネットワークが許す限りにおいてのみ、ネットワークとインターフェースできる。前の5章でのすべての設計決定、インテントをどう保存するか、実行をどう動かすか、テレメトリをどう収集するか、ワークフローをどう調整するか、コンシューマーにどうサービスするか、は最終的に接続先のネットワークデバイスが何をサポートしているかという問いに行き着く。本章はその制約を直接検討する。
graph LR
subgraph ゴール
direction TB
A1[ネットワークインフラの全スペクトルをナビゲートする]
A2[本番前に自動化を検証する]
A3[ネットワークが進化しても平台を安定させる]
end
subgraph 柱
direction TB
B1[ネットワークインフラスペクトルとプログラム可能なインターフェース]
B2[シミュレーションとテスト環境]
B3[抽象化戦略]
end
subgraph 機能
direction TB
C1[プログラム可能なインターフェース]
C2[シミュレーションとテスト環境]
C3[抽象化戦略]
end
A1 --> B1 --> C1
A2 --> B2 --> C2
A3 --> B3 --> C3
classDef row1 fill:#eef7ff,stroke:#4a90e2,stroke-width:1px;
classDef row2 fill:#ddeeff,stroke:#4a90e2,stroke-width:1px;
classDef row3 fill:#cce5ff,stroke:#4a90e2,stroke-width:1px;
class A1,B1,C1 row1;
class A2,B2,C2 row2;
class A3,B3,C3 row3;
9.2.1. プログラム可能なインターフェース#
ネットワークは本質的に異種だ。それは1つのものではない。年月をかけて蓄積されたインフラタイプのスペクトラムで、しばしば異なるチームによって並行して構築され(所有権と組織的境界は第13章で探求される)、それぞれ独自のインターフェースモデル、抽象化レベル、自動化の成熟度を持つ。モダンな自動化プラットフォームはキャンパススイッチ、データセンターファブリック、クラウドVPC、オーバーレイコントローラー、Kubernetesクラスター、サービスプロバイダーWANインフラ、ハイパースケーラー管理フォワーディングプレーンを同時にまたがれる。プラットフォームはそれらすべてを処理しなければならない。インフラタイプが利用可能なインターフェースを決定する。自動化プラットフォームは均一なインターフェースを要求するのではなく、その現実に適応する。
9.2.1.1. ネットワークインフラスペクトラム#
これは会社の性質に応じて取り組まなければならない可能性がある、さまざまなネットワークインフラシナリオの高レベルの概説だ:
キャンパスとブランチのスイッチングは、パート2を通じて例として使ったコアシナリオだ: マルチベンダーの物理スイッチ(Cisco、Arista、HPE、Extreme)。モダンなキャンパス機器はCommand Line Interface (CLI)、NETCONF、gRPC Network Management Interface (gNMI)を同時に公開する。自動化の成熟度は過去5〜7年の機器では高く、10年前のファームウェアをまだ実行しているレガシー機器ではまばらだ。
データセンターファブリックのトポロジーは通常リーフスパインで、多くの場合より小さなベンダーセットから: Arista、Cisco Nexus、または自動化ネイティブなオープンネットワーキングプラットフォーム。インターフェースの均一性はキャンパスより高く、変更管理はより厳格だ。EVPN/VXLANオーバーレイはファブリックの上に管理プレーンを追加し、個々のデバイスインターフェースとは別の独自のAPIを持つ場合がある。SONiCベースのプラットフォーム(Cisco 8000、Nvidia Spectrum)はハイパースケーラーの影響を受けたDCデプロイメントでますます存在感を示している。その設定インターフェースはCLIやNETCONFではなく構造化データベースで、抽象化戦略セクションでさらに扱う。
サービスプロバイダーとWANインフラ(キャリアグレードルーター、MPLSネットワーク、セグメントルーティングファブリック)は独自の自動化の課題を持つ: スケール、プロトコルの複雑さ、コントロールプレーン設定とトラフィックエンジニアリングポリシーの二重の懸念。NETCONFとYANGモデルはこの分野で確立されている。Cisco IOS-XRやJunosなどのベンダーは成熟したYANGカバレッジを持つ。自動化プラットフォームは多くの場合、個々のデバイスではなくコントローラー(SR-PCE、Crosswork、NSO)をターゲットとする。
クラウドネットワーキング: AWS VPC、Azure VNet、GCP VPCなど。結果整合性セマンティクスを持つREST API。「設定をプッシュして」同期確認を待つという概念がない。Executorは非同期操作を処理する: 作成、ポーリング、確認。インフラストラクチャアズコードツーリングがこのモデルに自然に適合する。自動化プラットフォームは異なる整合性モデルを考慮しなければならず、同期的な適用と確認のセマンティクスを仮定してはならない。
SD-WANとオーバーレイネットワーク(Cisco SD-WAN、Versa、VMware VeloCloud)はコントローラー管理だ。自動化ターゲットはコントローラーAPIであり、個々のデバイスではない。物理的なアンダーレイはまだ存在するが、オーバーレイの抽象化を通じて完全に管理される。これは実行とオブザーバビリティの両方に影響する: Executorはコントローラーにポリシーを書き込む。トラフィック、パス選択、ポリシー施行に関するテレメトリも物理アンダーレイデバイスからではなく、コントローラーのノースバウンドインターフェースを通じて流れる。
KubernetesネットワーキングのCNIレイヤーはデバイスモデルを完全に反転させる。ネットワークはKubernetes APIオブジェクトを通じて定義される: NetworkPolicy、Services、Ingress、Cilium、Calico、FlannnelなどのCNIプラグインからのカスタムリソース。デバイスは自動化ターゲットとして消える。Kubernetes APIがインターフェースだ。ネットワークポリシーはコードであり、デバイス設定ではない。これが他が収束しつつあるモデルだ: 宣言的なインテント、コントローラー調整状態、直接のデバイスアクセスなし。
DPUとSmartNIC(Nvidia BlueField、Intel IPU、Marvell Octeon)はネットワーク処理がどこで起こるかのシフトを表す。モダンなデータセンターでは、DPUはネットワーク機能をオフロードするためにすべてのサーバー上でCPUと並んでインストールされる: VXLANカプセル化、暗号化、ファイアウォールポリシー施行、ロードバランシング、マイクロセグメンテーション。これらの機能をホストCPUとネットワークアプライアンスからSmartNICファームウェアにオフロードする。自動化への影響: 「ネットワークデバイス」はもはやラック内のスイッチやルーターだけではない。以前は専用のネットワークアプライアンスAPIを通じて管理されていた機能が、DPU管理プレーンとそのベンダーSDKを通じて管理されるようになった。標準のNETCONFやgRPC Network Management Interface (gNMI)ツーリングがまだクリーンに到達できない新しいインターフェースカテゴリーだ。
オープンネットワーキング(SONiC、DENT、OPX)はコモディティハードウェア上でNetwork Operating System (NOS)ソフトウェアを実行する。SONiCの設定インターフェースはYANG構造化スキーマを持つRedisデータベースで、CLIやNETCONFとは構造的に異なり、設計からプログラム的だ。ハイパースケーラーの影響を受けたデータセンターと大規模エンタープライズDCデプロイメントにますます存在する。SONiCは最初から自動化のために設計されたという点で注目に値する: インターフェースは構造化データベースで、プログラム的アクセスのために適応されたCLIではない。
仮想ネットワーク機能は多くの環境で物理インフラと共存する。ポリシー定義のパスを通じてトラフィックを挿入するソフトウェアファイアウォール、アプリケーションクラスターにわたるトラフィック分散を管理する仮想ロードバランサー、ソフトウェアベースのBGPルートリフレクター: これらはすべてベンダーREST APIからNETCONFまでさまざまな管理インターフェースを使う自動化ターゲットだ。しばしば同じSoTとExecutorを使って物理インベントリと並んで管理されるが、そのインターフェースモデルが物理デバイスと異なるため別のアダプターパスが必要だ。
ワイヤレスコントローラー(Cisco DNA、Aruba Central、Juniper Mist)はコントローラーベースで、自動化ターゲットはコントローラーAPIだ。VLANプロビジョニングがキャンパスシナリオのように有線スイッチポートと並んでワイヤレスSSIDに拡張されるときはいつでも関連する。
要点はすべてのインフラタイプを網羅的に列挙することではない。非自明なネットワークを自動化するプラットフォームは複数のタイプを同時に扱うということを確立することだ。ExecutorとCollectorは各操作を正しいインターフェースタイプにルーティングしなければならない。Source of Truth (SoT)は個々のインターフェースより上のレベルでインテントをモデル化しなければならない。ネットワークの複雑さはプラットフォームが吸収するために構築された設計上の制約だ。
9.2.1.2. インターフェースタイプ#
各インフラタイプは自動化プラットフォームに1つ以上のインターフェースタイプを公開する。同じ物理スイッチが3つすべてを同時に公開する場合がある。プラットフォームは利用可能なものに適応し、信頼性、構造、スケールを反映する優先順位を持つ。どのインターフェースタイプも普遍的な要件ではない。正しい選択はデバイスがサポートするものと操作が必要とするものに依存する。
- Secure Shell (SSH)上のCommand Line Interface (CLI) は普遍的で、レガシーで、壊れやすい。スクリーンスクレイピングとテキスト解析はファームウェアが出力フォーマットを変更したり新しいフィールドを追加したりすると壊れる。エラーコードはベンダー間やファームウェアバージョン間で一貫していない。CLIは古い機器には依然として唯一のオプションだ。推奨は使用を最小限にし、代替がないデバイス(最後の手段)以上のものに依存するワークフローを構築しないことだ。インターフェースの説明の設定は次のようになる:
interface GigabitEthernet0/1
description uplink-to-core- NETCONF は構造化され、トランザクション的で、機能するときは正確だ。アトミック操作とロールバックをサポートし、そのデータモデルは機械で解析可能だ。トランスポートレイヤーは一般的に信頼性が高く、ギャップがあるのはデータモデルレイヤーだ。ベンダーのYANGモデルの品質は大きく異なる: デバイスはNETCONFサポートを主張するが、プラットフォームが必要とする機能のモデルが不完全またはプロプライエタリな場合がある。IETFとOpenConfigのYANGモデルはインテントレイヤーを標準化し、ベンダーネイティブのYANGモデルがギャップを埋める。NETCONF経由の同じインターフェースの説明:
<config>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet0/1</name>
<description>uplink-to-core</description>
</interface>
</interfaces>
</config>- RESTCONF はNETCONFのHTTPベースの同等物で、同じYANGモデルを使うがREST セマンティクスで公開される。NETCONFのXML/SSHトランスポートよりHTTPツーリングに慣れているチームに有用だ。データモデルは同じで、トランスポートだけが異なる。ベンダーサポートはNETCONFより均一でない。RESTCONF経由の同じインターフェースの説明:
PATCH /restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet0%2F1
Content-Type: application/yang-data+json
{
"ietf-interfaces:interface": {
"name": "GigabitEthernet0/1",
"description": "uplink-to-core"
}
}- gRPC Network Management Interface (gNMI)とgNOI はgRPC Remote Procedure Call (gRPC)ベースのプロトコルだ。gRPC Network Management Interface (gNMI)はテレメトリと設定の読み書きを処理し、gNOIは操作コマンドを処理する。モダンでスケールに優しい。ベンダーサポートはAristaとより新しいCiscoプラットフォームでは成熟しており、HPEとレガシー機器ではまばらだ。第6章ではgNMIをCollectorの観点からカバーした。第9章ではデバイス側の前提条件を扱う: デバイスはプラットフォームがターゲットとするOSバージョンでgNMIサブスクリプションをサポートしなければならない。SONiCを実行するNvidia SpectrumスイッチはgNMIをCONFIG_DBインターフェースと並んでネイティブに公開し、設定とテレメトリの両方で最も自動化に適したプラットフォームの1つとなっている。gNMI SetRequest経由の同じインターフェースの説明:
path: /interfaces/interface[name=GigabitEthernet0/1]/config/description
value: "uplink-to-core"- ベンダーREST API(eAPI、NX-API、Cumulus NVUEなど)は機械可読だが、ベンダー間で標準化されていない。特定の操作に対してNETCONFやgNMIが欠如しているか不完全な場合のギャップフィラーとして有用だ。Nvidia CumulusスイッチはNVUE(一貫したJSONスキーマを持つ構造化REST API)を主要なプログラマティックインターフェースとして公開し、AristaとCisco NexusはeAPIとNX-APIをそれぞれNETCONFの代替として公開する。これらをベンダー中立プラットフォームの基盤としてではなく、アダプターレイヤーの関心事として扱う。Arista eAPI(HTTPS上のJSON-RPC)経由の同じインターフェースの説明:
{
"jsonrpc": "2.0",
"method": "runCmds",
"params": {
"version": 1,
"cmds": [
"interface GigabitEthernet0/1",
"description uplink-to-core"
],
"format": "json"
},
"id": "1"
}- クラウドとコントローラーAPI は結果整合性を持つRESTパターンに従う。非同期操作モデルは回避すべき制限ではなく、設計要件だ。SD-WAN、ワイヤレス、DPU管理プレーンでは、コントローラーAPIが多くの場合唯一の利用可能なインターフェースだ。AWS VPCへの説明の追加はパターンを示している: 非同期的に提出されたタグ付きリソースの更新で、変更が適用されたことの同期的な確認がない:
POST https://ec2.eu-west-1.amazonaws.com/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AWS4-HMAC-SHA256 ...
Action=CreateTags
&ResourceId.1=vpc-0a1b2c3d4e5f67890
&Tag.1.Key=Description
&Tag.1.Value=uplink-to-core
&Version=2016-11-15- Kubernetes API は宣言的でコントローラー調整され、ベンダー間で一貫している。NetworkPolicy、Services、CNIカスタムリソースが自動化ターゲットだ。直接のデバイスアクセスはなく、APIサーバーが唯一のインターフェースだ。
app-paymentsサービスのネットワーク分離ポリシー:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-payments-isolation
namespace: production
spec:
podSelector:
matchLabels:
app: app-payments
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: app-payments- SONiC CONFIG_DB(Redis) はSONiCベースのプラットフォームのネイティブインターフェースだ。OS上に重ねられたプロトコルではなく、OSの独自の設定ストアだ: YANG構造化スキーマを持つRedisデータベース。自動化はJSONエントリをCONFIG_DBに直接書き込む。SONiCの内部
orchagentデーモンがインテントをハードウェアフォワーディングテーブルに調整する。gNMIはテレメトリ読み取りのために並行して利用可能だ。これはCLI、NETCONF、またはRESTとはアーキテクチャ的に異なる: インターフェースはデータストア自体だ。セクション9.2.3.4でこれを詳しく扱う。config loadで適用されるJSONパッチ経由でCONFIG_DBに書き込まれた同じインターフェースの説明:
{
"PORT": {
"Ethernet0": {
"description": "uplink-to-core",
"admin_status": "up"
}
}
}9.2.1.3. デバイスごとのインターフェース選択#
デバイスが複数のインターフェースを公開する場合、プラットフォームは操作タイプごとに1つを選択し、その選択を一貫して維持しなければならない。Command Line Interface (CLI)、NETCONF、gRPC Network Management Interface (gNMI)を同時に公開するキャンパススイッチは、ワークフローやエンジニアの好みによって異なるミックスアンドマッチアプローチではなく、決定を必要とする。
推奨階層、操作タイプごとに適用。gRPC Network Management Interface (gNMI)とNETCONFはどちらも設定の書き込みとテレメトリの読み取りをサポートする。以下の優先順位は運用上の強みを反映しており、プロトコルの排他性ではない:
- テレメトリ収集にはgRPC Network Management Interface (gNMI)が優先(ストリーミングサブスクリプション、構造化、スケールに優しい。gNMI Setは設定パスとしても有効)
- 設定にはNETCONFが優先(トランザクション的、ロールバック可能。NETCONFのgetとget-configは状態読み取りに同様に有効)
- 特定の機能でNETCONFが不完全な場合のフォールバックとしてRESTCONFまたはベンダーREST API
- レガシー機器のみの最終手段としてCommand Line Interface (CLI)
ExecutorがインターフェースNeed: Idempotency、または少なくとも「すでに存在する」と「失敗」を区別する信頼性の高いエラーコード、構造化エラーレスポンス、適用後の状態検証機能。HPEのvlan-exists対duplicate-vlanの問題はまさに第2の条件の失敗だった: エラーコードのセマンティクスがファームウェアバージョン間で変わったのだ。
Collectorが必要とするもの: 構造化読み取り、ストリーミングテレメトリサブスクリプション、オブザーバビリティレイヤーがデバイスごとのパーサーを必要としないように一貫したデータモデル。gRPC Network Management Interface (gNMI)はサポートされているところでは優先されるサブスクリプションプロトコルだ: 構造化されており、階層的で、デバイスでスキーマ検証され、SNMPエラの収集を支配したデバイスごとのテキスト解析を排除する。しかし構造化されたタイムリーなデータを提供するサブスクリプションメカニズムはどれも同じ機能を果たす。SNMPポーリングはgNMIが利用できないレガシーデバイスには依然として有効だ。Syslogはログベースのオブザーバビリティのために構造化イベントを提供する。OpenTelemetry(OTel)は追跡する価値がある新興標準だ: 元々はアプリケーションオブザーバビリティのために設計されたが、ネットワークテレメトリ、メトリクス、トレースのベンダー中立トランスポートとして採用が増えている。Collectorのプロトコル選択はデバイスがサポートするものの関数だ。オブザーバビリティレイヤーはどのトランスポートが使われたかを知る必要はない。
Source of Truth (SoT)はプラットフォームが操作するすべてのデバイス属性の意図された状態を記録する: 意図されたVLAN設定、意図されたBGPネイバー関係、意図されたインターフェースの説明、そして意図されたOSバージョン。OSバージョンはここで特別な言及に値する。設定ドリフト検出だけでなく、アダプターパス選択自体に影響するからだ: 同じベンダーのファームウェアがリリース間で異なる動作をするとき、ExecutorはOSバージョンで分岐する。これはOSバージョンの特殊ケースではない。プラットフォームが管理するすべての属性に適用される同じインテント対現実のパターンだ。目的のOSバージョンは運用チームが承認したもので、実行中のバージョンはObservabilityが観測するものだ。それらが乖離するとき、その乖離はシグナルだ: デバイスは計画されたアップグレードで遅れているか、計画外の変更が起きた。プラットフォームは進めるかブロックするかを決定するために両方のデータポイントを必要とする。
この区別は実際的に重要だ。SoTはデバイスがAOS-CX 10.13を実行すべきと言っている。Collectorはそれが10.12.1006を実行していると報告する。プラットフォームには2つのオプションがある: OSバージョンが調整されるまで実行をブロックするか、10.12アダプターパスを使って進むか。正しい答えはチームの変更管理ポリシーに依存するが、プラットフォームは決定を行うために両方のデータポイントを必要とする。SoTはインテントを提供し、オブザーバビリティは現実を提供する。
9.2.2. シミュレーションとテスト環境#
ネットワークは本番インフラだ。アプリケーションバックエンドとは異なり、デフォルトでテスト対象のステージングサーバーはない。その構築がこの機能の仕事だ。
ネットワーク自動化のテストはアプリケーションコードのテストより常に難しかった。ネットワークは自動化チームがコントロールしない多くのコンポーネントを持つ分散システムだ: ピアリングポイントで隣接するAS、上流のトランジットプロバイダー、顧客管理のCPE、ワイヤレスクライアント、第三者が運用するクラウドインフラ。ルーティングポリシーの変更をテストするサービスプロバイダーは、フルな動作を検証するためにトランジットプロバイダーからのモックBGPピアを起動できない。WANフェイルオーバーワークフローをテストするエンタープライズはMPLSプロバイダーがどう応答するかをコントロールできない。このセクションで説明するシミュレーション環境は最善の利用可能な代替物だ: チームがコントロールするものを再現し、コントロールできないものの限界を受け入れ、バグが実際に存在するロジックレイヤーの検証に集中する。
第2章のテストピラミッド(ユニット、統合、エンドツーエンド)はここで直接適用される。ユニットテストは個々の自動化モジュールをモックデバイスレスポンスで単独で検証する。統合テストは多段階の相互作用を検証する: SoT APIが期待されるデータ構造を返す、Executorがそれを正しく変換する、デバイスレスポンスが正しく処理される。エンドツーエンドテストは実際のネットワークデバイスのように動作するものに対してフルワークフローを検証する。シミュレーション環境はエンドツーエンドレイヤーだ。
9.2.2.1. 環境タイプ#
適切な環境はテストが何を検証する必要があるかに依存する。ルーティンCI/CDパイプラインに適した低忠実度、低コストの環境から、本番信頼性テストへの投資に値する高忠実度環境まで、スペクトラムがある。
| 環境タイプ | 起動時間 | コントロールプレーン | データプレーン | CI/CDへの適合性 | 使うとき |
|---|---|---|---|---|---|
| コンテナベースのエミュレーション | 秒単位 | あり | なし | ネイティブ | 自動化ロジック、インターフェースコントラクト検証、ワークフローテスト |
| VMベースのエミュレーション | 分単位 | あり | あり | 限定的 | プロトコル相互運用性、設計検証、フルNOS動作テスト |
| 物理ハードウェアラボ | なし(常時稼働) | あり | あり | 手動 | ハードウェア固有の動作、パフォーマンステスト、エミュレートできないシナリオ |
| デジタルツイン | 継続的同期 | あり | 実装による | カスタム | 本番忠実度テスト。実際の本番トポロジーと状態に対して自動化を検証 |
コンテナベースのエミュレーションは仮想リンクで接続された軽量なネットワークOSイメージをコンテナとして実行する。トポロジーの起動は秒単位だ。ルーティンCI/CDの実際のデフォルト: 自動化チームはすべての変更でコンテナ化されたトポロジーに対して同じワークフローコードを実行し、本番前にロジックエラーを捕捉する。データプレーン動作は再現されないが、コントロールプレーン動作と管理インターフェース動作は自動化ロジックのテストに十分だ。
VMベースのエミュレーションはフルNOSイメージを仮想マシンとして実行する。より広いベンダーカバレッジ、データプレーンを含むより現実的なNOS動作を提供し、プロトコル設計テストとマルチベンダー相互運用性シナリオに適している。トレードオフ: より高いリソースコスト、より遅い起動、自動化パイプラインとの限定的な統合。ルーティンのコミットレベルテストには実用的でない。
物理ハードウェアラボは多くの大規模組織が維持している: 実際のスイッチとルーターのラックで、多くの場合本番アーキテクチャパターンをミラーリングしている。ハードウェア固有の動作、パフォーマンステスト、エミュレーションがデバイス動作を正確に再現しないシナリオに対して最高の忠実度を提供する。コストは重大: 資本投資、電力とスペース、ラボトポロジーを本番アーキテクチャと同期させておく運用オーバーヘッド。本番パターンからドリフトしたラボは誤った確信を与える。価値は本物だが、メンテナンスの規律が課題だ。
デジタルツインは本番トポロジーのライブレプリカで、SoT(同じデバイスモデル、トポロジー、現在の意図された設定)とObservabilityからの現在の状態を供給される。デジタルツインは近似ではなく、本番が今実際にどう見えるかを反映する。運用コストは重大: デジタルツインと本番の間の同期を維持するには継続的な調整が必要だ。成熟度レベルの投資であり、すでにスケールでプラットフォームを検証していて最高レベルの本番前信頼度が必要なチームに適している。
コンテナベースのエミュレーションはほとんどのチームにとって実践的な出発点だ。秒単位で起動し、CI/CDパイプラインにネイティブに統合し、ほとんどの自動化ユースケースで使用されるモダンなキャンパスとデータセンター機器をカバーする。この環境を構築する投資は防止する最初のインシデントで回収される。
9.2.2.2. コンテナベースおよびVMベースのエミュレーションのためのツールチェーン#
コンテナベースのエコシステムには異なる役割を持つツールがいくつかあり、しばしば混同される:
containerlab はコンテナベースのネットワークOSイメージをインスタンス化して接続する。Roman Dodinによって作成され、ネットワーク自動化コミュニティ全体で広く採用されたcontainerlabはコンテナベースのネットワークラボのデファクト標準になっている。Dockerコンテナ(Arista cEOS、FRR、SONiC、VyOSなど)を直接オーケストレートし、トポロジーファイルに定義された仮想リンクで接続する。containerlabはトポロジーを起動し、数秒で稼働中のラボを提供する。最小限の3ノードトポロジーファイルは次のようになる:
チームがスケールするにつれて、単一のマシンでcontainerlabを実行することがボトルネックになる。clabernetesはcontainerlabトポロジーをKubernetesクラスター全体に分散し、複数のシミュレーション実行を並列で可能にし、プラットフォームの成長に合わせてチームが本番前ゲートをスケールできるようにする。
name: building-b-sim
topology:
nodes:
cisco-1:
kind: ceos
image: ceos:17.9.4
arista-1:
kind: ceos
image: ceos:4.31.2F
hpe-1:
kind: vr-aoscx
image: vrnetlab/vr-aoscx:10.12.1006
links:
- endpoints: ["cisco-1:eth1", "arista-1:eth1"]
- endpoints: ["arista-1:eth2", "hpe-1:eth1"]- netlab はcontainerlabの上でトポロジー定義を抽象化する。Ivan Pepelnjak によって作成されたnetlabはエンジニアが接続方法ではなくトポロジーが達成すべきことを記述できるようにする: 「これらの3つのノードがBGPを実行する」「これらのノードは同じVLANにある」。netlabはその記述を解釈し、ベンダーごとの初期デバイス設定を持つcontainerlabトポロジーファイルにレンダリングする。これをラボの宣言的な記述として考える: エンジニアがサービスを定義し、netlabがインフラ定義を生成する。本番ネットワークモデルを反映するトポロジーに対して自動化ロジックをテストすることが目標の場合、netlabが正しい出発点だ。containerlabがそれをインスタンス化する。同じ3ノードシナリオの最小限のnetlabトポロジー:
nodes:
cisco-1:
device: iosxe
image: ceos:17.9.4
arista-1:
device: eos
hpe-1:
device: aoscx
links:
- cisco-1:
arista-1:
- arista-1:
hpe-1:
vlans:
app-payments:
id: 210
links: [ cisco-1, arista-1, hpe-1 ]vrnetlab はコンテナベースとVMベースのエミュレーションをつなぐ。一部のベンダーはネイティブなコンテナイメージを提供しない。vrnetlabはベンダーVMイメージをコンテナ内にラップし、containerlabトポロジー内で使用可能にする。これによりVMベースのプラットフォームに切り替えることなく、containerlabの環境でCisco IOS-XRやJunosデバイスに対してテストする方法だ。
EVE-NG と**GNS3** は広いベンダーカバレッジ、GUIベースのトポロジー設計、データプレーンフォワーディングを含むフルNOS動作を提供するVMベースのエミュレーションプラットフォームだ。トレードオフ: より高いリソース使用量、より遅い起動、CI/CD統合が限定的。プロトコルと設計テスト、レガシープラットフォーム、マルチベンダー相互運用性シナリオに適している。
Cisco Modeling Labs は部分的なCI/CD統合のためのREST APIを持つCiscoの商用VMラボプラットフォームだ。管理された共有ラボでIOS-XE、IOS-XR、NX-OS VMへのアクセスが必要なCisco中心の環境に適している。
9.2.2.3. 検証フレームワーク#
デバイスが特定のインターフェースプロトコルまたはYANGパスを正しくサポートすることを検証することは、第5章(実行)と第6章(オブザーバビリティ)で説明した作業の一部だ: 実行章は本番ワークフローで依存する前に設定インターフェースを検証することをカバーする。オブザーバビリティ章は収集パスを検証し、サブスクリプションが期待されるフォーマットでデータを返すことを確認することをカバーする。
1つのシナリオがシミュレーションコンテキストで特定の扱いに値する: ウェーブ検証。シミュレーションが通過した後、フルの本番スコープにコミットする前に、一部のチームは最初のウェーブに対して構造化された検証パスを実行する。pyATS はリッチなパースと状態比較を持つ構造化デバイスインタラクションテストを書くためのテストフレームワークを提供する。Robot Framework はネットワーク固有のライブラリを持つより広いキーワード駆動テスト自動化フレームワークだ。どちらもチームが期待される変更後の状態を実行可能なアサーションとしてエンコードできるようにする: VLAN 210がウェーブ1にデプロイされた後、すべてのスイッチにVLAN 210が存在することを確認し、インターフェースの関連が正しいことを確認し、オブザーバビリティレイヤーが期待される状態を見ることを確認する。これはセクション9.2.2.4に直接つながる: 次のウェーブに進む前にシミュレーション実行の通過から本物の運用上の確信を分離する構造化検証レイヤー。
デプロイメント後のVLAN存在を確認する最小限のpyATSテスト:
from pyats import aetest
class VlanValidation(aetest.Testcase):
@aetest.test
def verify_vlan_exists(self, device):
output = device.parse('show vlan brief')
assert 210 in output['vlans'], f"VLAN 210 missing on {device.name}"
@aetest.test
def verify_vlan_name(self, device):
output = device.parse('show vlan brief')
assert output['vlans'][210]['name'] == 'app-payments'NAPALMライブラリを使用したRobot Frameworkでの同じチェック、明示的なセットアップと読みやすいキーワード名を持つ:
*** Settings ***
Library Collections
Library napalm WITH NAME NAPALM
*** Variables ***
@{DEVICES} cisco-1 arista-1 hpe-1
*** Test Cases ***
VLAN 210 Is Present On All Switches After Deployment
FOR ${hostname} IN @{DEVICES}
Connect And Check VLAN ${hostname} 210 app-payments
END
*** Keywords ***
Connect And Check VLAN
[Arguments] ${hostname} ${vlan_id} ${vlan_name}
NAPALM.Open ${hostname}
${vlans}= NAPALM.Get VLANs
Dictionary Should Contain Key ${vlans} ${vlan_id}
Should Be Equal ${vlans}[${vlan_id}][name] ${vlan_name}
[Teardown] NAPALM.Close9.2.2.4. 本番前Sagaゲートとしてのシミュレーション#
第7章はSagaパターンを説明した: 各ステップが後のステップが失敗した場合に実行される対応する補償アクションを持つ多段階ワークフロー。SagaはProductionでの障害を処理する。シミュレーションはSagaが始まる前のステップを追加する: まずシミュレーション環境に対してワークフローを実行する。シミュレーション実行が失敗した場合、本番の変更は発生しない。シミュレーションが通過したときのみワークフローは本番ターゲットに進む。
flowchart LR
SoT["SoTエクスポート(トポロジー + OSバージョン)"]
Lab["シミュレーション環境(containerlabトポロジー)"]
Workflow["ワークフロー実行(本番と同じコード)"]
Pass{通過?}
Prod["本番実行(オーケストレーター: フルスコープ)"]
Fix["調査と修正(本番への影響なし)"]
SoT --> Lab --> Workflow --> Pass
Pass -- はい --> Prod
Pass -- いいえ --> Fix --> Workflow
これが本番前ゲートだ: 本番のSagaスコープが始まる前の最初のチェックとしてのシミュレーション。シミュレーションでの障害は、本番のデバイスに触れる前に捕捉される。
実際の実装:
- SoTはターゲットスコープのトポロジー定義をデバイスごとのOSバージョンを含めてエクスポートする。
- シミュレーション環境は一致するベンダーイメージでインスタンス化され、OSバージョンはSoTの意図された状態に一致するようにピン留めされる。
- 本番で実行されるのと同じワークフローがまずシミュレーションターゲットに対して実行される。
- シミュレーションで失敗するステップは、本番実行が進む前に調査をトリガーする。
プログレッシブロールアウトウェーブ
シミュレーションの通過は本番スコープ全体への一度のデプロイを意味しない。大規模なロールアウトでは、シミュレーションは次のウェーブが進む前に各ウェーブに独自の検証チェックを持つ、徐々に大きくなるウェーブのシリーズの最初のゲートだ。これは重要なデプロイメントへの信頼を得るための私のお気に入りのパターンの1つで、ソフトウェア開発の一般的なカナリアパターンに似ている。
100のデータセンターに新しいワークフローをデプロイするチームは次のように構造化するかもしれない: シミュレーション(仮想トポロジー)→1つのパイロットサイト→2サイト→4→8→16→残りのサイト。各ウェーブは展開前に前のウェーブでワークフローが正しく動作したことを検証する。ウェーブ4がシミュレーションが捕捉しなかった障害(ハードウェア固有の動作、サイト固有の状態)を表面化した場合、ロールアウトは停止し、問題が修正され、ウェーブシーケンスは失敗の時点から再開する。
flowchart LR
Sim["シミュレーション"] --> W1["ウェーブ1(1サイト)"] --> W2["ウェーブ2(2サイト)"] --> W3["ウェーブ3(4サイト)"] --> W4["ウェーブN(フルスコープ)"]
W1 -- 失敗 --> Fix["調査と修正"]
W2 -- 失敗 --> Fix
W3 -- 失敗 --> Fix
Fix --> Sim
オーケストレーターがウェーブの進行を制御する。SoTはサイト、建物、またはデバイスグループごとに各ウェーブをスコープする。ウェーブ間の検証ゲートは明示的なワークフローステップだ: オーケストレーターは進む前にオブザーバビリティレイヤーに期待された状態をチェックする。このパターンはスコープが100のデータセンターでも800のキャンパススイッチでも適用される: 原則は予見できない障害の爆発半径を制限しながら各成功したウェーブで信頼を構築することだ。
シミュレーションの限界: コンテナイメージはすべてのファームウェア動作を再現しない。コンテナイメージは通常最新のNOSコードを実行する。古いファームウェア固有の癖は、イメージが特定のバージョンにピン留めされていない限り再現できない場合がある。シミュレーションはロジックエラー、インターフェースコントラクト違反、Yet Another Next Generation (YANG)モデルのギャップ、トポロジーレベルの障害を捕捉する。本番で遭遇するすべての可能なデバイス状態がテストされたことを保証しない。目標はゼロリスクではなく、大幅なリスク削減だ。
スノーフレーク問題: シミュレーションは本番ネットワークが一貫したアーキテクチャパターンに従うときに最も信頼性が高い。それぞれ固有の状態と履歴を持つ数百の個別にカスタマイズされた設定を持つネットワークは、シミュレーションで正確に表現することがより難しい。これが自動化アーキテクチャの原則(標準化された設計パターン、ゴールデンテンプレート、SoT駆動の設定)がテストをより効果的にする理由の1つだ: よく設計されたネットワークはよりシミュレーション可能だ。シミュレーションの価値はそれが表すネットワーク設計の品質とともに増す。この繰り返し可能性を構築するには、自動化エンジニアだけでなくネットワークエンジニアとの緊密なパートナーシップが必要だ: どのサイトが本当に同一でどれが隠れた例外を持っているかを理解するネットワークエンジニアが、シミュレーションを代表的にできる人物だ。シミュレーションの品質はネットワーク設計規律と自動化プラットフォームの共同出力だ。
9.2.3. 抽象化戦略#
ネットワークは本質的に異種で、ベンダーが異なるという意味だけではない。スケールで動作する自動化プラットフォームは物理スイッチング、クラウドインフラ、オーバーレイコントローラー、サービスプロバイダーWANインフラ、レガシー機器を同時にまたがる。それぞれが異なる言語を話す。自動化プラットフォームは新しいインフラタイプが追加されるたびに再構築されるべきではない。
このセクションは変化の下で壊れるのではなく変化を吸収するように自動化レイヤーを設計することについてだ: 今日の異種性を処理するだけでなく、来年追加されるインフラタイプのために設計する。
モダンな自動化プラットフォームは複数のインフラドメインを同時にまたがる。これをクリーンに処理するアーキテクチャは、オペレーターが大規模エンタープライズ、WATとカスタマーエッジを同時に管理するサービスプロバイダー、またはクラウドネットワーキングオーバーレイと並んでデータセンターファブリックを実行するハイパースケーラーであっても適用される。重要なポイント: ExecutorはCollectorと同じデバイスインターフェース(物理機器にはgNMI/NETCONF、クラウドとコントローラーにはREST)を通じて書き込み、読み取るので、インターフェースプロトコルはブロックごとの別々の設計選択ではなく、両方のブロックの共有関心事だ。
flowchart LR
SoT["信頼できる情報源"]
Orch["オーケストレーター"]
Obs["オブザーバビリティ"]
subgraph Physical["物理ドメイン"]
PhysIF["ネットワークインターフェース(NETCONF/gNMI)"]
PhysNet["キャンパス、DCファブリック、WAN機器"]
PhysIF --- PhysNet
end
subgraph Cloud["クラウドドメイン"]
CloudIF["ネットワークインターフェース(非同期REST)"]
CloudNet["クラウドVPC / ネットワーキング"]
CloudIF --- CloudNet
end
subgraph Overlay["オーバーレイドメイン"]
OvIF["ネットワークインターフェース(コントローラーAPI)"]
OvNet["SD-WAN / MPLS PCE / オーバーレイ"]
OvIF --- OvNet
end
SoT --> Orch
Orch -->|Executor書き込み| PhysIF
Orch -->|Executor書き込み| CloudIF
Orch -->|Executor書き込み| OvIF
PhysIF -->|Collector読み取り| Obs
CloudIF -->|Collector読み取り| Obs
OvIF -->|Collector読み取り| Obs
SoTは統一されたサービスモデルとしてすべてのトポロジータイプにわたるフルインテントをモデル化する。Orchestratorはネットワークドメインごとのブランチを含む。ExecutorはSoTデータに基づいて正しいアダプターにルーティングする。オブザーバビリティはすべてのレイヤーにまたがり、基礎インフラタイプに関係なく同じデータパイプラインを供給する。
重要なアーキテクチャ規律: 分岐はSoTではなくExecutorとOrchestratorで起こる。SoTはサービスの単一インテントモデルを保持する。そのインテントが異なるインフラタイプでどう実現されるかはExecutorの関心事だ。
9.2.3.1. 異種性の次元#
抽象化戦略を選択する前に、その戦略が吸収しなければならない異種性の軸を理解すると助けになる。すべての異種性が同じ種類の問題ではない。
| 次元 | 何が変わるか | プラットフォームの設計上の応答 |
|---|---|---|
| マルチベンダー物理 | CLIシンタックス、YANGモデル、エラーコードがベンダーごとに異なる | アダプターパターン: ベンダーごとに1モジュール、SoTからの同じ入力スキーマ |
| ファームウェア世代(同じベンダー) | インターフェース動作がベンダー名を変えずにOSバージョン間で変わる | SoTが意図されたOSバージョンを追跡し、動作が異なる場合Executorがバージョンで分岐 |
| 物理対クラウド | 物理: 同期適用。クラウド: 非同期REST、結果整合性 | Executorがインフラタイプごとに操作モデルを処理、SoTが統一インテントを保持 |
| 物理対オーバーレイ | SD-WAN/EVPNコントローラーが物理アンダーレイを抽象化、自動化ターゲットはコントローラーAPI | Executorが操作をコントローラーにルーティング、デバイスに直接ではない。Collectorはコントローラーのテレメトリから読み取る |
| エッジ対コア | 同じアーキテクチャ、異なるリスク許容度と変更速度 | 同じプラットフォームブロック、異なるワークフロー設定、承認ゲート、ロールアウトウェーブサイズ |
各行はプラットフォームがSoTにエンコードすることを要求せずに処理しなければならない差異の軸だ。インテントモデルは統一されたまま。ExecutorとOrchestratorがバリエーションを吸収する。以下のセクションの戦略はどうするかを扱う。
9.2.3.2. ExecutorとCollectorのアダプターパターン#
最も一般的な出発点で最も広く実装されている戦略。ベンダーごとに1つの自動化モジュールで、すべてがSoTから同じ入力データ構造を受け取る。SoTはベンダー中立のインテントを保存する。Executorのアダプターレイヤーが実行時にベンダーごとに変換する。同じ原則がCollectorに適用される: ベンダーまたはプロトコルごとに1つの収集モジュールで、すべてがオブザーバビリティパイプラインに正規化されたデータ構造を提供する。gNMIを話すベンダーは1つのアダプターを使い、SNMPポーリングやプロプライエタリRESTを必要とするベンダーは別のものを使う。オブザーバビリティレイヤーは上流の収集方法に関係なく同じデータスキーマを見る。
flowchart LR
SoT["SoTインテント(ベンダー中立): vlan_id=210, vlan_name=app-payments"]
Exec["Executor"]
CiscoA["Ciscoアダプター: IOS-XE NETCONF"]
AristaA["Aristaアダプター: eAPI / EOS"]
HPEA["HPEアダプター: NETCONF + OSバージョンエラー処理"]
CiscoD["Cisco Catalyst"]
AristaD["Arista 7050"]
HPED["HPE Aruba 6300"]
CollGNMI["コレクター: gNMIアダプター"]
CollSNMP["コレクター: SNMPアダプター"]
Obs["オブザーバビリティパイプライン(正規化スキーマ)"]
SoT --> Exec
Exec --> CiscoA --> CiscoD
Exec --> AristaA --> AristaD
Exec --> HPEA --> HPED
CiscoD --> CollGNMI --> Obs
AristaD --> CollGNMI
HPED --> CollSNMP --> Obs
構築に実用的でよく理解されている。デバイスインベントリが多様化するにつれてメンテナンスの負担が増す: 新しいベンダーまたはOSバージョンごとに新しいまたは更新されたアダプターが必要だ。アダプターパターンは定義されたベンダーセットにはうまくスケールするが、大きく頻繁に変化するデバイスカタログをサポートしなければならない場合は面倒になる。
9.2.3.3. コミュニティおよびインダストリー主導のYANGモデル#
2つの業界団体がベンダーごとのアダプター作業を減らすベンダー中立のYANGモデルを公開している。IETFモデル(RFCやインターネットドラフトとして公開)は基礎的なデータ構造を定義する: ietf-interfaces、ietf-routing、ietf-bgp。OpenConfigモデルは、よりオペレーション重視のスキーマと速いイテレーションサイクルを持つオペレーターコンソーシアム(Google、AT&T、Deutsche Telekомなど)によって開発されており、同様の領域をカバーする。どちらも自動化プラットフォームが標準モデルに対して一度インテントを書き、準拠するすべてのデバイスで機能することを期待できる。
インターフェースを定義するYANGモジュールは次のようになる(ietf-interfacesから簡略化):
module ietf-interfaces {
container interfaces {
list interface {
key "name";
leaf name { type string; }
leaf description { type string; }
leaf enabled { type boolean; default true; }
}
}
}同じ構造がOpenConfig(openconfig-interfaces)とベンダーネイティブモデルにも現れるが、異なるパス、異なるリーフ名、異なるデフォルトセマンティクスを持つ。YANGモジュールはスキーマを定義し、プロトコル(NETCONFまたはgNMI)がデータを転送し、アダプターレイヤーが標準とベンダーの現実の間をマッピングする。
OpenConfigの実際の現実: ベンダーの実装は完全性が異なる。デバイスはOpenConfigサポートを主張するが、プラットフォームが必要とするモデルのサブセットのみを実装する場合がある: 読み取りは機能するが書き込みは機能しない、またはインターフェースモデルは機能するがBGPモデルが欠落している。
欠落したパスを超えて、より陰険な問題は一貫性のないデータだ。デバイスがOpenConfigパスの値を返すが、間違った単位で、異なるタイプで、またはnullであるべきフィールドがベンダー固有のデフォルトで埋められている。SAMPLEモードで機能するgRPC Network Management Interface (gNMI)サブスクリプションが、同じデバイスのON_CHANGEモードでサイレントに失敗する場合がある。
これらはまれなエッジケースではない。本番でOpenConfigに依存するマルチベンダープラットフォームを運用する日常の現実だ。標準は紙の上では機能するが、ベンダーの実装は標準が排除することになっていたのと同じデバイスごとの調査を必要とする。OpenConfigはその作業を大幅に削減するが、排除しない。本番の自動化で新しいOpenConfigパスに依存する前に、デバイス固有のテストを計画する。
YANGモデルファミリーについての注記
Yet Another Next Generation (YANG)モデルの3つのファミリーが本番ネットワークで共存しており、どれをターゲットとするかを選ぶためにその区別を理解することが重要だ:
- IETFモデルはIETF標準プロセスを通じて開発され、RFCまたはインターネットドラフトとして公開される。基礎標準だ:
ietf-interfaces、ietf-routing、ietf-bgp。採用は広いが遅い。プロセスは徹底的だが数年かかる。ベンダーの実装は公開から2〜4年後に到着することが多い。 - OpenConfigモデルはOpenConfigコンソーシアム(Google、AT&T、Deutsche Telekомなどのオペレーター主導グループ)によって開発される。OpenConfigはIETFより速くイテレーションし、よりオペレーション重視だ。IETFモデルと同じ機能領域の多くをカバーするが、異なるスキーマ設計の選択をする。ほとんどの本番gNMIデプロイメントはOpenConfigパスを使用する。
- ベンダーネイティブモデルは各ベンダー独自の拡張だ:
cisco-ios-xe-native、junos-conf-root、arista-eos-augments。これらは標準モデルがカバーしない機能を公開し、IETFとOpenConfigが扱う共通分母機能を超えた何かに対しては多くの場合必要だ。Nokiaは極端なケースだ: SR OS上のほぼすべての運用データはNokia固有のYANGモデル(nokia-conf、nokia-state)を通じてのみアクセス可能だ。標準モデルは薄い表面をカバーし、ベンダーネイティブモデルはそのプラットフォームでの意味のある自動化には必須だ。
抽象化は機能アクセスのコストで均一性を買う。すべてのベンダーに標準モデルに相当するものがないプロプライエタリな機能がある。OpenConfigを使うチームは選択しなければならない: 機能を無視するか、ベンダー拡張を追加するか、ベンダー固有のオーバーライドパスを維持するか。クリーンな答えはない。実際には、ほとんどの自動化作業は標準モデルでよくカバーされている機能(VLAN、BGP、インターフェース)に集中する。プロプライエタリな機能は重要だが、コアユースケースになることはまれだ。標準は採用の遅れとともに到着する: ベンダーがIETFモジュールを公開から2〜4年後に実装し、より新しいプラットフォームのみに実装する場合がある。均一なサポートを仮定するのではなく、SoTに記録されたOSバージョンで機能使用を制御する。
9.2.3.4. SONiCとオープンネットワーキング#
SONiCの設定インターフェースはYANG構造化スキーマを持つRedisデータベースだ: 均一で、プログラム的で、最初から自動化のために設計されている。マルチベンダーの物理環境で労力を消費するベンダー固有のアダプター作業はここでは適用されない。同じ自動化ロジックが基礎ハードウェアベンダーに関係なくすべてのSONiCベースのプラットフォームで機能する。
SONiC CONFIG_DBのVLANエントリは次のようになる:
{
"VLAN": {
"Vlan210": {
"vlanid": "210"
}
},
"VLAN_MEMBER": {
"Vlan210|Ethernet0": {
"tagging_mode": "untagged"
}
}
}このJSONはsonic-cfggenまたはSONiCの管理REST API経由でRedisに直接書き込まれる。解析するCLIも構築するXMLもない。自動化プラットフォームが構造化データを書き込み、SONiCのorchagentがそれをハードウェアフォワーディングテーブルに調整する。
これがオープンネットワーキングが主張する設計方向だ: 自動化に適応されたのではなく、自動化のために設計されたネットワークインターフェース。従来の機器と並んでSONiCベースのプラットフォームを導入するチームは、SONiCアダプターが最もシンプルに書けて最も信頼性高く運用できることを発見するだろう。
ベンダーオファリング: SONiCはMicrosoft Azureの起源をはるかに超えて移動した。ほとんどの主要なスイッチシリコンベンダーが今やSONiCベースのプラットフォームを提供している: Microsoft Azure SONiC(上流リファレンス)、Aristaは一部のプラットフォームでSONiC互換管理APIを持つ、Cisco 8000シリーズはBroadcomベースのSONiCサポートを持つ、Dell OS10(SONiC派生アーキテクチャを使用)、Nvidia SpectrumプラットフォームはSONiCをファーストクラスのオプションとして実行、増加するODMベンダー(Edgecore、Celestica、UfiSpace)がブランド化されたSONiCプラットフォームを出荷。エコシステムはすべての価格とパフォーマンス層でSONiCベースのプラットフォームが商業的に利用可能なところまで成熟した。
成熟したユースケース: データセンターリーフスパインファブリックが最も確立されたデプロイメントだ。ハイパースケーラーは10年以上SONiCをスケールで実行している。エンタープライズデータセンターが今追いつきつつある。EVPN/VXLANオーバーレイ、BGPルーティング、ECMPロードバランシング、400G/800Gインターフェースサポートはよく検証されている。自動化のストーリーは強力だ: gNMI、YANG、Redisベースの CONFIG_DBがネイティブインターフェースだ。SONiCフリートは他のgNMI対応プラットフォームを管理する同じツールで管理できる。
新しいフロンティア: SONiCは従来のDCファブリックの外に現れ始めている。分解されたルーティングプラットフォーム(SONiCがスイッチだけでなく高ポート数のルーターで実行される場所)はオープンNOSモデルをルーティングのユースケースに拡張する。SONiCはセグメントルーティングサポートを含むようになった: SRv6(IPv6上のセグメントルーティング)は上流のSONiCで利用可能で、トラフィックエンジニアリングとネットワークスライシングのためにSONiCベースのプラットフォームを実行するサービスプロバイダーが本番で使用している。一部のサービスプロバイダーはSONiCをピアリングエッジとブロードバンドアグリゲーションにも評価している。キャンパスのSONiCデプロイメントはまれだが技術的に実現可能だ。キャンパスフォームファクターのハードウェアエコシステムはより成熟していない。今日新しいプラットフォームを構築するチームにとって、問いはもはやSONiCがDCで本番準備できているかではなく(できている)。未解決の問いはベンダーのSONiCフォークとリリースケーデンスがプラットフォームのライフサイクルにわたって上流と整合し続けるかどうかだ。
9.2.3.5. ファームウェア移行中の共存管理#
アダプターパターンはデバイスごとの既知で安定したOSバージョンを仮定する。ローリングファームウェアアップグレード中、その仮定は壊れる: 同じ役割にあるデバイスが、同じ自動化プラットフォームによって管理され、数日または数週間同時に異なるOSバージョンを実行する。昨日ファームウェア10.12で機能した抽象化レイヤーは、新しいアダプターパスが追加されるまでファームウェア10.13では機能しない場合がある。
SoTは意図されたOSバージョン(移行後のターゲット)を記録すべきで、CollectorはOperational Stateとして現在のOSバージョンを表面化すべきだ。ExecutorがConfiguration適用する前に、CollectorまたはObservabilityパイプラインから現在のOSバージョンを読み取り、意図されたバージョンがすでにデプロイされていると仮定するのではなく、適切なアダプターパスを選択すべきだ。
具体的なメカニズム: ExecutorはObservabilityブロック(またはデバイス自体に対する軽量な事前実行チェック)に実行中のOSバージョンをクエリする。アダプターレジストリはOSバージョン範囲をアダプター実装にマッピングする。ExecutorはSoTのインテントではなく現在の状態に基づいて正しいアダプターを呼び出す。デバイスがアップグレードされて実行中のバージョンがインテントと一致すると、アダプターの選択が安定する。移行ウィンドウ中、同じベンダーの2つのアダプターパスが同時にアクティブになる場合がある。
セクション9.3の実装例はこのパターンを直接示す: HPEアダプターのバグは1つのファームウェアバージョンが
vlan-existsを返し、別のバージョンが同じ条件に対してduplicate-vlanを返したためトリガーされた。修正はアダプターレジストリのOSバージョンごとのエラー処理だった。マルチバージョンフリートを管理するすべての自動化プラットフォームはこのクラスの問題に遭遇する。CollectorからRead読んだ現在のOSバージョンによって駆動されるバージョンごとのアダプターロジックをエンコードすることが系統的な緩和策だ。第11章はOSバージョンマッピングをPlaybook定数としてではなくプラットフォームレベルのカタログとして維持する方法を扱う。
組織的な含意: 誰かがSoTのOSバージョン追跡、アダプターバージョンレジストリ、アップグレードシーケンシングワークフローを所有しなければならない。これらの3つのアーティファクトがアップグレード自動化システムを形成する。明示的な所有なしには、それらは独立してドリフトし、すべてのファームウェアリリースとともにプラットフォームの信頼性が低下する。
9.2.4. すべてのブロックへの制約としてのネットワーク#
このセクションでカバーされた3つの領域、プログラム可能なインターフェース、シミュレーション環境、抽象化戦略、は孤立したトピックではない。NAFフレームワークのすべてのブロックへのネットワークの影響を説明する。
ネットワークのインターフェース機能はExecutorができることを制約する: CLIのみをサポートするデバイスはExecutorのアダプターを壊れやすいスクリーンスクレイピングに強制する。成熟したgNMIサポートを持つデバイスは信頼性の高い設定とストリーミングテレメトリを可能にする。ネットワークの収集サポートはCollectorが取り込めるものを制約する: 必要なOpenConfigパスを実装しないデバイスはベンダー固有の回避策または収集ギャップを必要とする。ネットワークのトポロジーはOrchestratorが安全に並列化できるものを制約する: フラットなアクセスレイヤーに安全なバッチサイズは、複数のスパインノードへの同時変更がネットワークを分断できるリーフスパインファブリックには壊滅的かもしれない。
SoTデータモデルはこれらの制約を反映する。OSバージョンフィールドがアダプター選択を制御する。インターフェースタイプフィールドが収集方法を制御する。トポロジー関係がOrchestratorの並列実行制御ルールを制御する。デバイスインベントリを記録するが自動化関連の属性(インターフェース機能、OSバージョン、トポロジーの役割)を記録しないSoTは、実行時にのみ明らかになる方法で不完全だ。
パート2の各アーキテクチャ決定には、本章が表面化する対応するネットワークレイヤーの制約がある。ネットワークは自動化のターゲットであるだけでない。それはそれに作用するすべてのブロックを形作り、それらの制約はプラットフォームのデータモデル、アダプターロジック、ワークフロー設定にエンコードされなければならない。ネットワークを均一なサーフェスとして扱う自動化は、失敗したデプロイメント1つずつ異種性を発見するだろう。
9.3. 実装例#
9.3.1. シミュレーションから本番へ#
キャンパスVLANワークフローは準備ができている。8週間の開発、3つのベンダーがモデル化され、3ノードのラボに対してべき等性がテストされた。チームはそれを本番にデプロイしたい: 800台のスイッチ、AからFの建物まで。それが起きる前に、シミュレーションに対して実行する。
この例はBuilding Bのスコープをシミュレーションターゲットとして使い、セクション9.2.2.4で説明した本番前ゲートシーケンスに従う: 24台のスイッチ、8台のCisco、8台のArista、8台のHPE。
ステップ1: 信頼できる情報源からトポロジーをエクスポート
SoTは意図されたOSバージョンを持つBuilding Bのスイッチインベントリを保持している:
- 8台のCisco Catalyst 9300: IOS-XE 17.9.4
- 8台のArista 7050: EOS 4.31.2F
- 8台のHPE Aruba 6300: AOS-CX 10.12.1006(古いファームウェアライン、10.13以前)
SoTエクスポートはnetlabトポロジー定義を生成する: ノードタイプ、意図されたOSバージョンにマッピングされたベンダー固有のイメージタグ、シミュレーションが開始すべきVLAN状態(既存のVLAN 100、150、200がすべてのスイッチに設定済みで、本番状態に一致)。
ステップ2: シミュレーション環境をインスタンス化
netlabはSoTエクスポートをcontainerlabトポロジーファイルにレンダリングする。containerlabはチームのCI環境の共有Linuxシミュレーションホスト(64GBのRAMを持つベアメタルサーバー、同時に24台の軽量なcEOS/vrnetlabコンテナに十分)で実行される。HPEノードはSoTの意図されたOSバージョンに一致する10.12.1006にピン留めされたvrnetlabラップのAOS-CXイメージを使用する。containerlabがトポロジーを起動する。24台のノードすべてが90秒以内に起動し、NETCONFとgRPC Network Management Interface (gNMI)に応答する。
ステップ3: シミュレーションターゲットに対して第7章のVLANワークフローを実行
Orchestratorは本番インベントリではなくシミュレーションインベントリをターゲットスコープとしてワークフローをトリガーする。最初の4つのワークフローステップは問題なく完了する:
- ServiceNow Webhookを受信、解析、SoTスキーマに対して検証
- 事前チェック: VLAN 210はシミュレーションに存在しない(正しい)
- SoTをVLAN 210インテントで更新
- 承認ゲート: シミュレーションモードで自動承認
5番目のワークフローステップ、Executor経由でシミュレートされた24台のスイッチ全体へのファンアウト実行が失敗を返す。
結果: 8台のCiscoノードが通過。8台のAristaノードが通過。8台のHPEノードが失敗。
HPEノードからのエラー: vlan-exists。HPEアダプターのべき等チェックはduplicate-vlanをノーオペレーションとして処理したが、vlan-existsにはハンドラーがなかった。Executorが失敗を返し、Saga補償をトリガーした: VLAN 210は受信したすべてのノードから削除された。
本番への変更は発生していない。障害のコストはコンテナの起動時間と30分の調査だ。
ステップ4: 診断と修正
チームはAOS-CX 10.12のリリースノートを確認する。vlan-existsエラーは10.11.1で導入され、重複VLAN検出のためにduplicate-vlanを置き換えた。10.13リリースはArubaプロダクトラインの残りとの一貫性のためにduplicate-vlanに戻った。
修正: HPEアダプターのべき等エラーコードリストにvlan-existsを追加する。SoTはOSバージョン境界についての注記で更新される(10.11から10.12.xはvlan-existsを返す。10.13以上はduplicate-vlanを返す)。
再実行前に、チームはpyATSまたはRobot Frameworkテストとして期待される変更後の状態をエンコードする: ワークフローが完了した後、VLAN 210がシミュレーションの24台のノードすべてに存在し、Saga補償がトリガーされなかったことをアサートする。このアサーションはシミュレーション通過基準に追加される: シミュレーションゲートはワークフローが完了し、かつ検証アサーションが通過したときのみ閉じる。
ステップ5: シミュレーションで再実行
修正されたアダプターが同じcontainerlabトポロジーに対して実行される。24台のノードすべてが通過する。Sagaは補償なしで完了する。SoTはVLAN 210がBuilding Bのすべてのノードに存在することを示す。
ステップ6: 本番デプロイメント
Orchestratorはフルの本番スコープに対して同じワークフローをトリガーする: 800台のスイッチ、AからFの建物まで。各ステップはシミュレーションで検証された同じSagaパターンを通じて実行される。HPEノードでのゼロの失敗。Orchestratorが完了すると、アプリケーションチームのServiceNowチケットは自動的にクローズする。オブザーバビリティレイヤーは期待される時間ウィンドウ内にすべてのインターフェースでVLAN 210の存在を検証する。
これが示すもの
シミュレーション環境はチームが自信を持っているときにスキップできる検証ステップではない。SagaパターンのUQ本番前ゲートだ。本番トポロジーとOSバージョンをミラーリングするシミュレーショントポロジーは、キャンパス規模で自動化をデプロイするチームの最小限の実行可能なテスト環境だ。投資はcontainerlabのセットアップ、OSバージョンピン留めされたイメージ、SoTエクスポートメカニズムだ。リターンはデバイス固有のバグがインシデントになる前に捕捉する能力だ。
シミュレーションがこのバグを捕捉したのは、エキゾチックなテストのためではなく、シミュレーションのOSバージョンが本番と一致し、プラットフォームがまったく同じワークフローコードをそれに対して実行したからだ。シミュレーション環境の本番状態への忠実度が、捕捉を可能にするものだ。最新のベンダーイメージを実行するシミュレーション環境はそれを見逃していた。
第10章では、シミュレーション環境をプラットフォームの一部として運用化する方法をカバーする: バージョン管理でcontainerlabトポロジーを維持し、スケジュールに従ってSoTエクスポートと同期し、シミュレーションゲートがすべてのワークフロー変更で自動的に実行されるようにCI/CDパイプラインに統合する。
9.4. サマリー#
第9章は、自動化プラットフォームが常に指し示していたブロック、ネットワーク自体を扱うことでパート2を締めくくる。
3つのアイデアが本章を支える。
ネットワークは均一ではない。 大規模な自動化プラットフォームはキャンパススイッチング、データセンターファブリック、クラウドVPC、Kubernetesオーバーレイ、オーバーレイコントローラー、レガシー機器を同時に扱う。それぞれが異なるインターフェースを公開し、異なる整合性セマンティクスの下で動作し、異なる自動化成熟度を持つ。プラットフォームはインターフェース選択階層(テレメトリにはgRPC Network Management Interface (gNMI)、設定にはNETCONF、最終手段としてCommand Line Interface (CLI))、SoTのOSバージョン追跡、ExecutorのベンダーFixしたアダプターを通じてこの異種性を吸収する。
シミュレーション環境が本番前ゲートだ。 コンテナベースのエミュレーションは、自動化ロジックが本番をミラーリングするトポロジーとOSバージョンに対してテストされる現実的で高速なCI/CD統合環境を提供する。シミュレーションでの障害は安い。本番での障害は高い。シミュレーション環境の本番状態への忠実度がゲートを意味あるものにする。
抽象化戦略がプラットフォームの寿命を延ばす。 アダプターパターンは今日のマルチベンダー物理環境を処理する。OpenConfigとYANG変換は長期的なアダプターメンテナンスを削減するベンダー中立モデルに向けてプッシュする。SONiCはそれをサポートするプラットフォームのアダプター作業を完全に排除する。これらの戦略のどれも完璧な答えを提供しない。それぞれは均一性と機能アクセスの間のトレードオフを含む。正しい選択はチームのデバイスカタログ、運用能力、自動化作業がどれだけ標準機能カバレッジ内に収まるかに依存する。
第9章により、パート2は完了した。6章がNAFフレームワークの7つのビルディングブロックすべてをカバーした: SoT、コレクターとオブザーバビリティ(第6章でまとめて)、実行、オーケストレーション、プレゼンテーション、ネットワーク。これらは独立したツールではない。SoTはExecutorに必要なインテントとCollectorが検証する期待される状態を供給する。Orchestratorは両方をシーケンスし、障害を処理し、プレゼンテーションレイヤーに進行を表面化する。ネットワークはそれらすべての下に座っている: 他のすべてのブロックの設計を形作った制約、そして自動化が最終的に結果を生み出すか失敗する場所。
パート3はブロックの構築からスケールでのプラットフォームの運用に向かう: 信頼性のためのエンジニアリング、セキュリティとコンプライアンスのための設計、自動化プラットフォームを独自のライフサイクルと運用要件を持つプロダクトとして扱うこと。
参考文献と追加資料#
- Network Programmability and Automation, Matt Oswalt, Christian Adell, Scott Lowe, Jason Edelman (O’Reilly, 2nd ed. 2023). NETCONF、gNMI、YANGモデル、自動化フレームワークを深く扱う、ネットワーク自動化ツーリングへの最も包括的な実践ガイド。
- Network Programmability with YANG, Benoit Claise, Loe Clarke, Jan Lindblad (Pearson, 2019). YANGデータモデリングの決定版リファレンス: IETFとOpenConfigモデルがどう構造化されているか、YANGモジュールの読み書き方法、NETCONFとRESTCONFがどう使うか。
- Cisco pyATS: Network Test and Automation Solution, John Capobianco, Dan Wade (Cisco Press). ネットワークテスト自動化のためのpyATSとGenieへの包括的なガイド: テストスクリプト、パーサー、構造化状態検証、CI/CDパイプライン統合。
- Infrastructure as Code, Kief Morris (O’Reilly, 2nd ed. 2021). ネットワーク固有ではないが、繰り返し可能で、テスト可能で、バージョン管理されたインフラの背後にある原則がネットワーク自動化プラットフォーム設計にどう直接適用されるかを理解するための基礎。
💬 Found something to improve? Send feedback for this chapter