はじめに
Ansibleは、RedHat社によって開発されたオープンソースのIaC向け自動化ツールです。本テクニカルブログでは、以前にもAnsibleを用いたネットワーク設定の管理および自動化について御紹介しています。
今回は、"Enterprise SONiC Distribution by Edgecore"(以下、Edgecore SONiCと記します)が搭載されたホワイトボックススイッチを管理するためのAnsibleプレイブックと、それを核とした成果物について御紹介いたします。このプレイブックを核とした一連の成果物は、当社よりホワイトボックススイッチを御購入いただきましたユーザー様に限りまして、当社より御購入いただいたホワイトボックススイッチのみ操作する条件で、サンプルとして無償で提供しています。
今回は、"Enterprise SONiC Distribution by Edgecore"(以下、Edgecore SONiCと記します)が搭載されたホワイトボックススイッチを管理するためのAnsibleプレイブックと、それを核とした成果物について御紹介いたします。このプレイブックを核とした一連の成果物は、当社よりホワイトボックススイッチを御購入いただきましたユーザー様に限りまして、当社より御購入いただいたホワイトボックススイッチのみ操作する条件で、サンプルとして無償で提供しています。
Edgecore SONiC向けにプレイブックなどを実装した目的
SONiCは、ホワイトボックススイッチで動作する、オープンソースなネットワークOSのひとつです。SONiC foundationによって開発が進められているcommunity版と、community版の安定したブランチをベースとして、様々なソフトウェアベンダーによって独自の特長が付加されてリリースされた版が存在します。本記事に登場するEdgecore SONiCは、Edgecore社によってリリースされているSONiCの名称です。
Edgecore SONiCのバージョン202111系列では、設定の可能な箇所または機能が以下に示すように複数存在します。
そこで今回は、Infrastructure as Code (IaC)向けの自動化ツールであるAnsibleを用いて、商用ネットワークの構築作業を支援する各種のプレイブックなどを作成しました。作成した成果物は後ほど御紹介いたします。
Edgecore SONiCのバージョン202111系列では、設定の可能な箇所または機能が以下に示すように複数存在します。
- Config DB
- FRRouting
- Extended Control plane ACL(TCP/UDPの特定のポートに対するアクセスを制限する機能、以下Extended CACL)
そこで今回は、Infrastructure as Code (IaC)向けの自動化ツールであるAnsibleを用いて、商用ネットワークの構築作業を支援する各種のプレイブックなどを作成しました。作成した成果物は後ほど御紹介いたします。
Ansibleについて
冒頭で述べたように、AnsibleはIaC向けの自動化ツールの一つです。Ansibleの利点を以下に示します。
コントロールノード: Ansibleを実行するホストです。
プレイブック: 望ましい状態(desired state)の実現に不可欠な一連の処理をYAMLで記述したものです。ひとつ以上のプレイによって構成されるリスト構造を有します。べき等性(後述)を有することが望ましいです。
プレイ: プレイブックを構成するオブジェクトです。プレイブックにとっての望ましい状態の一部として、プレイにとっての望ましい状態も存在します。以下に示す情報を保持します。
ロール: プレイの中の「特定アプリケーションのセットアップ」のような何らかの役割に関連するタスクを、リストとしてまとめたものです。
モジュール: Ansibleに対する指示またはマネージドノードに対して実行する処理をコードとして実装したものです。一般的に、固有のパラメーターが規定されています。コミュニティによって管理されているモジュールの大半はべき等性を有していますが、そうでないものも存在します。
インベントリー: プレイブックの実行中にマネージドノードとして選択され得るホスト毎に、固有な情報を変数とその値の対として記述したものです。後述するようにプレイブックと組み合わせて用いられます。以下に示す3種類の情報を保持します。
- マネージドノード(Ansibleによって制御されるホスト)に専用のエージェントプログラムを必要としません。
- プレイブックの記述に、人間にとって理解しやすいYAMLを用いています。
用語
Ansibleに登場する要素について簡単に説明します。コントロールノード: Ansibleを実行するホストです。
プレイブック: 望ましい状態(desired state)の実現に不可欠な一連の処理をYAMLで記述したものです。ひとつ以上のプレイによって構成されるリスト構造を有します。べき等性(後述)を有することが望ましいです。
プレイ: プレイブックを構成するオブジェクトです。プレイブックにとっての望ましい状態の一部として、プレイにとっての望ましい状態も存在します。以下に示す情報を保持します。
- そのプレイにおいてマネージドノードとなるホストまたはホストグループの名前
- プレイにとっての望ましい状態の実現に不可欠なタスクのリスト and/or ロールの名前のリスト
- Ansibleに対する指示(例: タスク群を記述したファイルのインポート)
- マネージドノードに対して実行する処理(例: 指定されたファイルの削除)
ロール: プレイの中の「特定アプリケーションのセットアップ」のような何らかの役割に関連するタスクを、リストとしてまとめたものです。
モジュール: Ansibleに対する指示またはマネージドノードに対して実行する処理をコードとして実装したものです。一般的に、固有のパラメーターが規定されています。コミュニティによって管理されているモジュールの大半はべき等性を有していますが、そうでないものも存在します。
インベントリー: プレイブックの実行中にマネージドノードとして選択され得るホスト毎に、固有な情報を変数とその値の対として記述したものです。後述するようにプレイブックと組み合わせて用いられます。以下に示す3種類の情報を保持します。
- ホストのグループ定義。 ※任意
- コントロールノードからホストに接続するための情報(ホスト名, IPアドレスなど)。
- ホストに固有な設定。プレイブックからホスト変数として参照可能。

図1: プレイ、タスク、モジュールの関係
プレイとインベントリーの組み合わせによって、「どのホストで」「どのような望ましい状態を実現するか」が確定します(図2)。
図2: プレイとインベントリーの対で確定すること
Ansibleによる自動化
Ansibleでは、ユーザーはコードとしてプレイブック(図3の①)とインベントリー(図3の②)を記述し、コントロールノードでこれらを指定してAnsibleを実行します。Ansibleは、プレイブックの先頭から順次プレイをひとつずつ処理します(図3の③)。
図3: Ansibleによるホスト管理の概要
プレイに対するAnsibleの処理内容を以下に示します。- プレイに記述されたマネージドノードとなるホストまたはホストグループの名前と、インベントリーに記述されたホストおよびホストグループの定義から、そのプレイにおけるマネージドノードを選出します。
- 図1の例では、マネージドノードは hostsの値で指定されたleafグループに所属する、 Leaf01から Leaf03までのホストです。
- マネージドノードとして選出されたホストに関して、それに固有な情報をホスト変数として登録します。
- プレイに記述された一連のタスクのうち、インポート(タスクや変数を記述したファイルを静的に取り込むこと)の指示を処理します。
- 各マネージドノードに対して、プレイに記述された一連の処理を実行します。
- ロールの名前のリストが記述されている場合、対応するロールの記述を参照します。
べき等性
IaCでは、操作に関する重要な性質として「べき等性」が登場します。これは「操作前の状態が望ましい状態か否かを問わず、操作後は常に望ましい状態が得られる」性質です(図4)。
図4: べき等性を有する操作
- 望ましい状態以外から必ず望ましい状態が得られる(遷移①)。
- 望ましい状態からも必ず望ましい状態が得られる(遷移②)。
- 任意の状態からワンタッチで望ましい状態を実現できます。例えば、ドリフト(望ましい状態との相違)が存在する状態、またはエラーなどの理由によってAnsibleによる変更が完了していない状態から、Ansibleを実行することで望ましい状態を実現できます。このとき、実行前の状態に合わせてプレイブックおよびインベントリーを修正する作業も不要です。
- 望ましい状態を容易に再現できます。同一のホストに対しては言うまでもありませんが、インベントリーの中に記述された各ホストのIPアドレスを変更することによって、同一構造を有するネットワークを別のホスト群で容易に再現できます。例えばデータセンター毎に同一構造を有するネットワークを構築したいケースでは、ユーザーは単一のプレイブックとデータセンター毎のインベントリーを用意すれば十分です。
Edgecore SONiC向けAnsibleプレイブックを核とした成果物
Edgecore SONiC向けAnsibleプレイブックを核とした成果物について、以下に示します。
上の結果ではchangedが正の値です。これは、各マネージドノードの状態を変化させるタスクが幾つか実行されたこと(=望ましい状態へ遷移した)ことを示しています。
上の結果ではchangedが0です。これは、各マネージドノードの状態を変化させるタスクが実行されていないこと(=望ましい状態を維持している)ことを示します。
- Edgecore SONiC向けに作成された複数のAnsibleプレイブック。
- 設定の検証 (validate)
- 設定の確認 (deploy_apply_debug)
- 設定の展開 (deploy_apply)
- プレイブックの構築に使用するロール群。
- 上記プレイブックと組み合わせるインベントリーのサンプル。
- ansible-playbookコマンドのラッパースクリプト。
- プレイブックを指定して本スクリプトを実行する度に、Ansibleの動作ログが異なるログファイルに出力されます。
- プレイブックを指定してAnsibleを実行するために不可欠なPythonパッケージを記載したファイル。
- pip installコマンドの入力として利用できます。
- ansible-core 2.17用および2.18用のファイルが同梱されています。
Ansibleプレイブックの一覧
商用ネットワークの構築作業で使用されることを想定して、以下に示すように設定の検証からマネージドノードへの設定展開までをそれぞれ担当するプレイブックを用意しました。1. 設定の検証 (validate.yml)
ホストに固有な設定に関して、基準に対する適合性を検証します。基準はJSON Schemaを用いて記述されています。代表的な基準を以下に示します。- 必須である変数が存在すること
- 値の持つ型が正しいこと
- 値が上限・下限などの制約へ適合していること
- IPアドレスに関して、IPv4/IPv6の種別およびプレフィックス長の有無の指定へ適合していること
- Dynamic Port Breakout機能に関するモードに関して、マネージドノード上の指定されたインターフェースで設定可能であること
- べき等性を有します。その理由は、検証結果に影響を及ぼす要素はホストに固有な設定のみであるためです。
- 「既に望ましい状態が実現している場合、何もしない」性質は、前提自体が成立しません。その理由は、検証結果は動作ログ以外に保存されず、また以前の検証結果は参照されない、すなわち実行前において検証結果は常に不明であるためです。
- マネージドノードへアクセスできない環境においても実行が可能できます。その理由は、全てのタスクの処理をコントロールノードで実行するためです。
2. 設定の確認 (deploy_apply_debug.yml)
ホストに固有な設定から、Config DB, FRRouting, そしてExtended CACLへ設定を展開するために使用される各ファイルをマネージドノード単位で作成します。設定の展開時、これらのファイルはマネージドノードに作成されますが、このプレイブックでは内容を容易に確認できるようにするためコントロールノードに作成されます。 このプレイブックの特徴を以下に示します。- べき等性を有します。各ファイルの内容に影響を及ぼす要素はホストに固有な設定のみであるためです。
- 「既に望ましい状態が実現している場合、何もしない」性質は、前提自体が成立しません。その理由は、コントロールノードに作成された各ファイルは次の実行時の冒頭に削除され参照されない、すなわち実行前において各ファイルは常に存在しないためです。
- マネージドノードへアクセスできない環境においても実行が可能です。その理由は、全てのタスクの処理をコントロールノードで実行するためです。
3. 設定の展開 (deploy_apply.yml)
ホストに固有な設定を、Config DB, FRRouting, そしてExtended CACLに対して展開します。それぞれに対する作業の手順を以下に示します。- Config DB
- Config DBの現在の設定を格納したJSONファイル(C0)を一時的に作成します。
- ホストに固有な設定から、Config DBの新たな設定を格納したJSONファイル(X)を一時的に作成します。
- C0とXとの間でDynamic Port Breakoutの変更が存在する場合のみConfig DBにそれを反映します。
- Config DBの現在の設定を格納したJSONファイル(C1)を一時的に作成します。
- C1からXへ遷移させるための差分を格納した、RFC 6902 JSON patchフォーマットのファイルを一時的に生成します。
- 差分ファイルの中身が空ではない場合のみapply-patchコマンドによって差分を一括反映します。
- FRRouting
- ホストに固有な設定から、FRRoutingの新たな設定を格納したファイルを一時的に作成します。
- 上記ファイルとFRRoutingの現在の設定を格納したファイルを比較して、内容に差分が存在する場合のみfrr-reload.pyを実行して新しい設定を展開します。この際、frr-reload.pyの動作によって設定を格納したファイルも更新されます。
- Extended CACL
- ホストに固有な設定から、Extended CACLの新たな設定を格納したファイルを一時的に作成します。
- Extended CACLの現在の設定を格納したファイルと上記ファイルを比較して、内容に差分が存在する場合のみ設定ファイルを更新します。
- 2で更新が発生した場合のみcaclmgrdの再起動によって新しい設定を展開します。
- 設定を展開するために一時的に作成した各ファイルはプレイブックの終盤で削除されます。
- べき等性を有します。
- Config DBの設定作業はべき等性を有します。現在の設定に対する新しい設定の差分を都度求めて、Config DBに対して反映することによって、プレイブック実行前にどのような設定であっても新しいものが展開されます。
- FRRoutingの設定作業はべき等性を有します。frr-reload.pyはその内部において現在の設定に対する新しい設定の差分を求め、それに含まれる設定を追加または削除するコマンドを発行します。これを実行することによって、プレイブック実行前にどのような設定であっても新しいものが展開されます。
- Extended CACLの設定作業はべき等性を有します。caclmgrdは起動時に既存のiptables/ip6tablesのルールを全て消去してから新しいルールを追加します。そのためプレイブック実行前にどのような設定であっても新しいものが展開されます。
- 「既に望ましい状態が実現している場合、何もしない」性質は、Config DBおよびFRRoutingに関してのみ成立します。
インベントリー
Edgecore SONiCを搭載したLeaf3台, Spine2台によるIP-Clos fabricを構築し、BGP EVPN/VXLANおよびStatic Anycast Gatewayを設定するためのインベントリーの例を紹介します(図5)。
図5: Leaf3台, Spine2台によるIP-Clos fabric構成
まず、YAMLによってホストグループの定義およびコントロールノードからホストへ接続するための設定を記述した例を示します。all: hosts: localhost: ansible_connection: local ansible_python_interpreter: "{{ ansible_playbook_python }}" children: network: children: leaf: hosts: Leaf01: ansible_ssh_host: 192.168.10.1 Leaf02: ansible_ssh_host: 192.168.10.2 Leaf03: ansible_ssh_host: 192.168.10.3 spine: hosts: Spine01: ansible_ssh_host: 192.168.10.101 Spine02: ansible_ssh_host: 192.168.10.102 vars: ansible_user: ansible_ssh_user: ansible_ssh_pass: ansible_sudo_pass: ansible_ssh_port: 22 ansible_python_interpreter: /usr/bin/python3.9
- all、network、leafおよびspineはホストグループです。all以外は独自に定義したグループです。
- 設定の検証、設定の確認および設定の展開の各プレイブックは、networkグループをマネージドノードとして指定しています。したがって、組み合わせるインベントリーではnetworkグループにIP-Clos fabricを構成する全てのホストを直接的または間接的に所属させることが必要です。
- leafおよびspineの定義は任意です。
hostname: Leaf01 router_id: 10.1.10.1 device: type: ToRRouter mgmt_vrf_enabled: true ipaddr: 192.168.10.1/24 gwaddr: 192.168.10.254 bgp: asn: fabric_ports: - Ethernet64 - Ethernet68 fabric_af: - l2vpn_evpn vlans: - vid: 100 members: - port: Ethernet0 - vid: 250 vlan_interfaces: - vid: 100 vrf: Vrf_A - vid: 250 vrf: Vrf_A vrfs: - name: Vrf_A vni: 2500 vxlan: nvo: nvo vtep: vtep tun_maps: - {vid: 100, vni: 1000} - {vid: 250, vni: 2500} sag: gwmac: e0:11:22:33:44:55 ipv4: status: enable vlans: - vid: 100 ipaddr_list: - 172.16.1.254/24 snmp: communities: - name: public type: RO location: name: public
- この例にExtended CACLに関する設定は含まれていませんが、Config DBおよびFRRoutingの設定が一ファイルに集約されています。
設定の展開の例
設定の展開を行うプレイブックで、BGP EVPN/VXLANおよびStatic Anycast Gatewayの設定を展開する例を示します。画像は本記事作成時の最新版のものです。1回目の実行結果
望ましい状態が実現されていないときに設定の展開を行うプレイブックを実行した結果を以下に示します。
2回目の実行結果
1回目の実行から続けて(=既に望ましい状態が実現されている状態において)、再び設定の展開を行うプレイブックを実行した結果を以下に示します。
成果物の主な仕様
本記事の作成時点における主な仕様を以下に示します。
サポートしているEdgecore SONiCのバージョン
- 202111.8
- 202111.9
サポートしているホワイトボックススイッチ
- Edgecore社 EPS121 (AS4625-54T)
- Edgecore社 EPS201 (AS4630-54TE)
- Edgecore社 DCS201 (AS5835-54X)
- Edgecore社 DCS202 (AS5835-54T)
- Edgecore社 DCS203 (AS7326-56X)
- Edgecore社 DCS204 (AS7726-32X)
- Edgecore社 DCS501 (AS7712-32X)
サポートしている主な機能
項目 | 主な仕様 |
デバイスタイプ | ToRRouter, LeafRouter (今後追加を予定) |
BGP | BGP unnumberedのみ対応 他peerとの接続はeBGP固定 peer-groupとしてfabric, serverの2個を用意(Routing on the host構築可能) AS-path prependによる経路変更可能(drain mode) |
BGP EVPN | peer-group fabricのみ対応(今後serverも対応を予定) アンダーレイのトンネル技術としてVXLANを使用可能 |
Extended CACL | 以下に示すポートに対する、管理ポートを経由したアクセスを制限(指定したネットワークからのみアクセス許可) SSH(22/tcp) NTP(123/tcp) SNMP(161/tcp, 161/udp) |
Management VRF | 有効/無効の設定可能 |
PortChannel(LAG) | Edgecore SONiC 202111.9の仕様に準ずる |
SNMP | SNMP contactの設定は非対応 上記以外はEdgecore SONiC 202111.9の仕様に準ずる |
Static Anycast Gateway | Edgecore SONiC 202111.9の仕様に準ずる |
VLAN | Edgecore SONiC 202111.9の仕様に準ずる |
VRF | Edgecore SONiC 202111.9の仕様に準ずる |
VXLAN | Edgecore SONiC 202111.9の仕様に準ずる |
おわりに
Edgecore SONiC向けAnsibleプレイブックを核とした成果物についてご紹介いたしました。冒頭で御紹介しましたとおり、この成果物は、当社よりホワイトボックススイッチを購入いただいたお客様に無償で提供しています。御興味がございましたら、当社までお問合せください。