APRESIA Technical Blog

SONiCのconfig apply-patchを試してみた

はじめに

 SONiC開発コミュニティにて、apply-patch機能が202205ブランチにて開発されました。この機能は、設定変更のない機能には影響を与えずに、設定の差分(パッチ)のみを動作に反映することができます。本機能は、商用ディストリビューションである"Enterprise SONiC Distribution by Edgecore "(以下、Edgecore SONiCと記します)でも、202111.1リリースからサポートしています。 今回は、本機能の動作を確認しましたので、そちらの結果をご紹介いたします。なお、Edgecore SONiCはこちらから無償でダウンロード可能です。

apply-patchの機能の説明

 これまで、SONiCの設定変更は方法が統一されておらず、またCLIなどで設定を変更することができない機能もありました。ただし、設定の保存についてはSONiCの全ての設定はconfig_db.jsonに保存する仕様に統一されていました。そこで、SONiC 202205ブランチの"SONiC Generic Configuration Update and Rollback"によって、config_db.jsonをベースに設定を反映するための統一的な方法が開発されました。この開発の中で以下の機能がSONiCに追加されています。
  1. config_db.json(設定保存ファイル)のcheckpoint(config_db.jsonのスナップショット)を作成
  2. 設定の差分を、差分がない機能に影響を与えることなく、動作に反映(apply-patch)
  3. 過去のcheckpointへのロールバック
 上記のapply-patchは以下の手順で使用することが可能です。
  • jsonデータの差分をRFC6902のjson patch形式で表したパッチファイルを用意
  • 用意したパッチファイルを設定に反映
 このapply-patchの使い方を、以降で実機を使って確認してみます。

Edgecore SONiCによるapply-patchの動作確認

 ここでは、実際にapply-patch機能をEdgecore SONiCを使って確認します。今回使用した環境は以下です。
  • ハードウェア:Edgecore製 AS7326-56X
  • Edgecore SONiCバージョン:202111.3
 注意点ですが、apply-patchを試す前に、config_db.jsonに以下の設定を追加して設定を反映(rebootあるいはreload)しておく必要があります。この設定が反映されていないと、apply-patchコマンドが失敗します。管理ポートがeth0ではない場合は、環境に合わせて以下の設定を変更ください。
    "MGMT_PORT": {
        "eth0": {
            "alias": "eth0",
            "admin_status": "up"
        }
    },
 今回の実験では、apply-patchを使って以下の変更を行ってみます。
  • VLAN 11: 削除
  • VLAN 12: 変更なし
  • VLAN 13: 追加
 この場合、config_db.jsonの中のVLAN設定は、以下のように変更されます。
変更前 変更後
{
    "VLAN": {
        "Vlan11": {
            "vlanid": "11"
        },
        "Vlan12": {
            "vlanid": "12"
        }
    },
    "VLAN_MEMBER": {
        "Vlan11|Ethernet0": {
            "tagging_mode": "tagged"
        },
        "Vlan11|Ethernet1": {
            "tagging_mode": "tagged"
        },
        "Vlan12|Ethernet0": {
            "tagging_mode": "tagged"
        },
        "Vlan12|Ethernet1": {
            "tagging_mode": "tagged"
        }
    }
}
{
    "VLAN": {
        "Vlan12": {
            "vlanid": "12"
        },
        "Vlan13": {
            "vlanid": "13"
        }
    },
    "VLAN_MEMBER": {
        "Vlan12|Ethernet0": {
            "tagging_mode": "tagged"
        },
        "Vlan12|Ethernet1": {
            "tagging_mode": "tagged"
        },
        "Vlan13|Ethernet0": {
            "tagging_mode": "tagged"
        },
        "Vlan13|Ethernet1": {
            "tagging_mode": "tagged"
        }
    }
}
 SONiCでは、二つのjsonファイルからRFC6902形式で差分を生成するjsondiffコマンドを実行することができます。変更前のVLAN設定を01_vlan.json、変更後のVLAN設定を02_vlan.jsonとしてファイルに保存しておき、以下のようにjsondiffを実行することで差分を得ることができます。
$ jsondiff 01_vlan.json 02_vlan.json | jq
[
  {
    "op": "remove",
    "path": "/VLAN/Vlan11"
  },
  {
    "op": "add",
    "path": "/VLAN/Vlan13",
    "value": {
      "vlanid": "13"
    }
  },
  {
    "op": "move",
    "from": "/VLAN_MEMBER/Vlan11|Ethernet0",
    "path": "/VLAN_MEMBER/Vlan13|Ethernet0"
  },
  {
    "op": "move",
    "from": "/VLAN_MEMBER/Vlan11|Ethernet1",
    "path": "/VLAN_MEMBER/Vlan13|Ethernet1"
  }
]
 この出力結果をファイルに保存します。今回はpatchというファイル名で保存しました。apply-patchを実行する前に、VLANの現在の設定を確認します。以下のようにVLAN 11と12が設定されています。
$ show vlan brief
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
|   VLAN ID | IP Address   | Ports     | Port Tagging   | Proxy ARP   | DHCP Helper   | DHCP Source   | DHCP Link   |
|           |              |           |                |             | Address       | Interface     | Selection   |
+===========+==============+===========+================+=============+===============+===============+=============+
|        11 |              | Ethernet0 | tagged         | disabled    |               |               |             |
|           |              | Ethernet1 | tagged         |             |               |               |             |
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
|        12 |              | Ethernet0 | tagged         | disabled    |               |               |             |
|           |              | Ethernet1 | tagged         |             |               |               |             |
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
 そのうえで、'sudo config apply-patch 'を実行して、設定の差分を動作に反映させます。
$ sudo config apply-patch patch
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "add", "path": "/VLAN/Vlan13", "value": {"vlanid": "13"}}, {"op": "move", "from": "/VLAN_MEMBER/Vlan11|Ethernet1", "path": "/VLAN_MEMBER/Vlan13|Ethernet1"}, {"op": "move", "from": "/VLAN_MEMBER/Vlan11|Ethernet0", "path": "/VLAN_MEMBER/Vlan13|Ethernet0"}, {"op": "remove", "path": "/VLAN/Vlan11"}]
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config does not have empty tables, since they do not show up in ConfigDb.
Patch Applier: Sorting patch updates.

(省略)

Patch Applier: The patch was sorted into 7 changes:
Patch Applier:   * [{"op": "remove", "path": "/VLAN/Vlan11/vlanid"}]
Patch Applier:   * [{"op": "add", "path": "/VLAN/Vlan13", "value": {"vlanid": "13"}}]
Patch Applier:   * [{"op": "add", "path": "/VLAN_MEMBER/Vlan13|Ethernet1", "value": {"tagging_mode": "tagged"}}]
Patch Applier:   * [{"op": "add", "path": "/VLAN_MEMBER/Vlan13|Ethernet0", "value": {"tagging_mode": "tagged"}}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN_MEMBER/Vlan11|Ethernet0"}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN_MEMBER/Vlan11|Ethernet1"}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN/Vlan11"}]
Patch Applier: Applying 7 changes in order:
Patch Applier:   * [{"op": "remove", "path": "/VLAN/Vlan11/vlanid"}]
Patch Applier:   * [{"op": "add", "path": "/VLAN/Vlan13", "value": {"vlanid": "13"}}]
Patch Applier:   * [{"op": "add", "path": "/VLAN_MEMBER/Vlan13|Ethernet1", "value": {"tagging_mode": "tagged"}}]
Patch Applier:   * [{"op": "add", "path": "/VLAN_MEMBER/Vlan13|Ethernet0", "value": {"tagging_mode": "tagged"}}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN_MEMBER/Vlan11|Ethernet0"}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN_MEMBER/Vlan11|Ethernet1"}]
Patch Applier:   * [{"op": "remove", "path": "/VLAN/Vlan11"}]
Patch Applier: Verifying patch updates are reflected on ConfigDB.
Patch Applier: Patch application completed.
Patch applied successfully.
 最後に"Patch applied successfully."が出力されれば、apply-patchは成功です。ログを見ると、jsonのパッチファイルから7つの変更内容を抽出し、その順番を並べ替えてから、順次反映する処理になっているようです。VLANの設定を確認すると、以下のように、VLAN 11が削除され、VLAN 13が追加されていました。
$ show vlan brief
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
|   VLAN ID | IP Address   | Ports     | Port Tagging   | Proxy ARP   | DHCP Helper   | DHCP Source   | DHCP Link   |
|           |              |           |                |             | Address       | Interface     | Selection   |
+===========+==============+===========+================+=============+===============+===============+=============+
|        12 |              | Ethernet0 | tagged         | disabled    |               |               |             |
|           |              | Ethernet1 | tagged         |             |               |               |             |
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
|        13 |              | Ethernet0 | tagged         | disabled    |               |               |             |
|           |              | Ethernet1 | tagged         |             |               |               |             |
+-----------+--------------+-----------+----------------+-------------+---------------+---------------+-------------+
 また、変更のないVLAN 12にテスト通信を流しながら、apply-patchを実行しても、VLAN 12の通信にパケットロスは発生しませんでした。つまり、apply-patchの前後で設定に変更がない機能に対して影響を与えることなく、設定を変更できることを確認できました。

まとめ

 今回は、apply-patchについて、実機にて動作確認を行った結果をもとに使用方法を説明いたしました。これによって、これまでSONiCの課題の一つであった設定変更の統一性について、一つの解が示された形になります。ほかにもSONiCコミュニティでは活発に機能開発が行われていますので、今後も情報を随時共有してまいります。