[Cisco Advent Calendar 2019] (https://qiita.com/advent-calendar/2019/cisco) 第24日目!
1. はじめに
2019年も早くも年末となりました。Cisco有志で綴るAdvent Calendarも今年は3回目。私はこの、年末恒例行事になったわくわくするAdvent Calendarに、わくわくする(?!)システム理論的なことを書くことにしています。過去二回のエントリーもぜひご覧いただけたら嬉しいです。
2. システム理論って何?
「わくわくするシステム理論」などと言いながら、そういえば「システム理論とは何か」についてきちんと記述していませんでした。Wikipediaによる「システム理論」解説 によると「現象のマクロな挙動を直接的にモデル化して扱う科学理論のこと」と書かれています。システムは、それぞれが相互作用する複数の構成要素から成り立ちますが、システム理論は、それまでの、システム構成要素を個別に探求する要素還元的アプローチではなく、ひとまずシステム全体を捉えて観測し、そこから分析を始める方法論です。1950年代に学術的アプローチとして認められ今に至りますが、現在、相互につながることが大前提であるネットワークシステムや分散システムのエンジニアリングにおいて、このシステム理論の果たす役割は大きいと見ています。
で、なぜシステム理論でわくわくするか、というと、個々の要素同士がつながったり相互作用することによって、新たな発見や思いもよらなかったような効果が現れたりするのを観測したり、ある現象の背後に目には見えない機序が働いていることを分析できたりするからです。(この相互作用が全く偶然に起こると「セレンディピティ」ですね!)勿論、暗澹たる構造があぶり出される可能性もある訳ですが、それでも、何もかもわからない状態よりは遥かにましと言えます。
3. 宣言的ネットワーキング
さて、今回のテーマは「宣言的ネットワーキング」です。過去二回のエントリーで、システムを複雑適応系として捉えることについて記述しましたが、私は「宣言的ネットワーキング」を、ネットワークシステムを複雑適応系と捉えた場合の、強力なエンジニアリング方法論と考えています。
3-1 宣言的プログラミングについて
宣言的(Declarative)という用語は、まずはソフトウェアプログラミング手法のパラダイムを示すものとして導入されました。宣言的プログラミングの対義語となるものは、「プログラムはコンピュータやOSに与える命令のセット・手順・手続きである」とする、命令的(Imperative)、もしくは手続き型(Procedural)プログラミングです。宣言的という用語の由来は、命令的にやり方(how)を逐次指示するのではなく、結果や目的(what)を「宣言」するということであり、関数型プログラミング、論理型プログラミング、制約型プログラミングが、この宣言的プログラミングのカテゴリーに分類されます。
宣言的プログラミングのメリットとしては、数理論理学 に基づいているためモデル駆動型とも親和性が高い、宣言した状態と具体的なやり方を分離することができるためデバッグ性や保守性に優れている、などが挙げられるでしょう。また、具体的なやり方でなく宣言した状態を合意している、ということは、つまり 冪等性 を保証することにもつながります。
3-2 宣言的ネットワーキングの例
このような宣言的パラダイムは、ネットワークシステムやネットワークで接続されている分散システムの制御手法として、特に有益です。なぜなら「ネットワーク・エンジニアリングから学ぶこと − システム理論の見地から」でみたように、これらのシステムにおいては、ネットワークでの遅延やロスの発生は避けられず、帯域は有限であり、複数の管理主体が存在し、多様な構成要素から成るため、不確実性が高いためです。
ネットワークプログラミングを、命令的・逐次処理的に実施することを想定してみましょう。例えば、通信状態不安定などの理由により確認応答が返ってこない場合、命令した処理が実行されていないのか、それとも、処理は実行されたが確認応答のみが返ってこないのか、判然としません。このような状況でリトライすると、望んだ結果と実際の結果が異なってしまう可能性があります。また、命令する側に障害が発生する可能性もあります。この場合、バックアップシステムに制御を引き継ぐことになりますが、それぞれの処理の状況を逐一引き継ぐことは困難です。
宣言的な制御の場合は、ひとつひとつの手順ではなく、望まれる状態を宣言しているので、処理途中の状態を expose する必要がありません。
そこで、ここにいくつか宣言的ネットワーキングの例を書きます。
3-2-1 BGP
宣言的ネットワーク、というとなにか特別なもののように聞こえるかもしれませんが、ルーティングプロコトルは、各ノードが自らの能力と保持する経路情報を宣言するという点で、元来宣言的なものといえます。
IGP や BGP などのルーティングプロトコルは、元来宣言的であることに加え、共存可能性や互換性を保つための仕組みを持ちます。例えば BGP message に含まれる Path Attribute には次の4つのカテゴリがありますが、Optional Transitive
というカテゴリは、そのアトリビュートは必須ではない+自分は解釈できない Path Attribute であっても他に転送する、ということを意味します。
BGP Path Attribute (RFC4271, Section 5より)
1. Well-known mandatory.
2. Well-known discretionary.
3. Optional transitive.
4. Optional non-transitive.code
IGP にも Optional TLV 等がありますが、ともあれこれらにより、その機能を関知しないノードは単に転送し、その機能を搭載しているノードだけが機能を実行する、ということが可能なため、下の図のような、任意の機能毎のトポロジーを形成することが可能になります。
通常このようなことはレイヤをオーヴァレイすることにより実現されますが、過度にレイヤを重ねることは複雑性を増大しますので、これは宣言的ネットワーキングにより複雑性を縮減する例と言えます。何と言っても、この不確実性も高い環境で、世界的規模の自律分散システムであるインターネットが今日も動いている、ということが、宣言的ネットワーキングの有用性を例証していると思います。
3-2-2 GBP
ルーティングプロトコルはそもそも宣言的であり、インターネットもそれで動いている訳ですが、もっときめ細い制御への要望が出てきました。SDN(Software Defined Networking)です。アプリケーションの要請に応じてネットワークを動的に制御したり、運用の自動化をNetwork Programmability により実施したり、という実践が盛んになりました。
SDN が話題になった当初は、Openflow や Script/Workflowなど、命令的・手続き型のパラダイムが使用されましたが、実際にはモデル駆動型で宣言的な方法が多く展開されることになりました。
その一つの先駆けになったのが、GBP(Group Based Policy)です。GBPでは、ネットワーク制御のための必要機能を、"EPG(End Point Group)"と、EPG間の"Contract"という要素を用いて、モデル化・定式化しています。
GBPにより、ScriptやWorkflowを使用したり、Access Listをごりごり記述・保守する必要なく、必要な制御を宣言的に行うことができます。これは Cisco ACI の中心的概念であり、また、OpenStack や [OpenDayLight] (https://wiki.opendaylight.org/view/Group_Based_Policy_(GBP)) などの各種オープンソースにも採用されています。
3-2-3 Cloud Native API
マルチクラウド、仮想アーキテクチャを真に活用するためには、Cloud Native の実践が必要になります。Cloud Native の定義は諸説あると思いますが、CNCF (Cloud Native Computing Foundation) の定義では、Cloud Native技術を実現する重要アプローチとして、コンテナ、サービスメッシュ、マイクロサービス、イミュータブル(不変の)インフラに加えて、Declarative(宣言的な)APIを挙げています。
また、Google で Kubernetes Projectに携わる Janet Kuoは、"Kubernetes: Living up to the hype"というKubeCon講演で、Kubernetusが誇大広告負けしていない、すぐれた技術であり続ける理由の一つとして、宣言的 - 命令的でない - API(Declarative - not Imperative - API)と自動化を挙げています。不確実性の高い分散システムにおいては、宣言的に制御しないと自動化は達成できないと述べています。
このように、Cloud Nativeシステムのコンテクストにおいても、宣言的アプローチは重要です。
3-2-4 Network Datalog (NDlog)
ここまでに見たとおり、宣言的ネットワーキングは、既に実用化されているものもあり、また今後ますます重要になると考えられます。ところで、"Declarative Networking"で検索すると、最初にヒットするのが、ACMで発表された論文 Declarative Networking です(2019年12月現在)。この論文では、Declarative Networking のための言語として、NDlogが提案されています。
宣言的プログラミングのための代表的言語として、関数型の Haskell などと共にあげられるのが、Database Query 言語である SQL です。SQLは、どのようにデータを検索するかを命令的・手続き的に指示するのではなく、望む状態 -得たいデータは何か- を宣言するために、宣言的です。このようなデータ論理に Prolog 的ルールを追加して拡張したのが Datalog であり、宣言的論理的プログラミング言語と言われます。このDatalogに、ネットワークの特性・要素を加味して応用しているのが NDlog です。
論文では、NDlogの応用例としてSPF(Shortest Path Fast)計算を記述しており、まずは自システム内に閉じたユースケースが想定されているようですが、今後の応用が期待されます。
3-3 宣言的アプローチの限界と克服
という訳で、宣言的アプローチは、不確実性の高いネットワークシステムや分散システムにとって、有力なエンジニアリング方法論です。しかし万能な方法はありません。そこで宣言的アプローチの限界も記述しておきます。
まず、論理自体に限界がある、ということです。もし論理が万全であれば、試験やデバッグも論理的に行え、ブラックボックステストや受け入れテストの必要は無くなるはずです。しかし実際はそうはいきません。(あなたは15,000円所持しており、パーティのためにピザを注文しようとしています。ピザは1枚2,400円だそうです。その時Aさんが「ピザが5枚買えますね!」と言いました。Aさんは正しいでしょうか?)
また数理モデルが解決できるものにも限界があります。下図は Mathematical Modeling in Chemical Engineering に示された解析的方法による解法の難易を示したものです。近年ではBig dataと機械学習でかなり補完ができるものの、本質的にはあまり変わりません。
しかしそれでも、より良いシステムの具現化ために、宣言的アプローチの追求を諦めてはならないと思います。システムの目的を的確に捉え、良い抽象化を行う。
これは技術システムのみならず、組織や社会システムなどにも当てはまります。私達も、命令的に逐次指示されるより、目的を合意し、自らやるべきことを宣言してそれにコミットする方が良いですよね。宣言的プログラミング言語である Haskell の入門書に次のように書かれていました。「Haskell の美しさを知っている人は、人生に絶望することはない。」
4. おわりに
システム理論、そして宣言的アプローチの追求は、私の生涯のライフワークと言っても過言ではありません。そのような中、尊敬する、そして業界の盟友である 進藤 資訓さんに声をかけて戴き、次回 [JANOG] (https://www.janog.gr.jp/meeting/janog45/)で [宣言的ネットワーキングに関するセッション] (https://www.janog.gr.jp/meeting/janog45/program/declarative)を行うことになりました。
進藤さんとのコラボレーションによりどのような議論ができるのか、今からとても楽しみにしています。ぜひご興味のある方にご参加いただき、ご意見や忌憚ないフィードバックを戴けたら幸甚です。
References
- Group Based Policy, Mike Dvorkin
- フォン・ベルタランフィ「一般システム理論 その基礎・発展・応用」みすず書房
- 重城 良国「Haskell 教養としての関数型プログラミング」秀和システム
- (他の参考文献は、文中にリンクで示しました。)