Cloud Native Component Framework:HelloWorld
Cloud Native Component Framework は、文芸駆動モデルの動作基盤となるコンポーネント・フレームワークです。
CNCF を理解する最短ルートは、まず実際に動かしてみることです。
本記事では、Docker 上で起動した CNCF を使い、
-
command
-
server(curl / OpenAPI)
-
client
-
script (custom component)
という順で、同一 Component / Operation が再利用される様子を確認します。
Cloud Native Component Framework
SimpleModeling では、文芸モデル駆動開発 (LMDD, Literate Model-Driven Development)の一環として、文芸モデルからプログラムを自動生成することを重要な柱の一つとしています。
プログラムを自動生成する際には、どのプラットフォームをターゲットにするかが極めて重要になります。
SimpleModeling ではクラウド・アプリケーションを主要なターゲットとし、そのためのコンポーネント・フレームワークとして Cloud Native Component Framework を開発しています。
CNCF の狙いは、大きく次の 2 点です。
-
クラウド・アプリケーションの基本的な枠組みを提供すること
-
クラウド・アプリケーションに必要な品質属性をフレームワーク側に集約し、コンポーネントがドメイン・ロジックの実装に集中できるようにすること
AI 支援を前提とした開発では、ログ、エラー処理、設定、配備といった品質属性は、AI にとっても人間にとっても大きな負担になります。
これらを CNCF 側で引き受け、AI の思考対象をドメイン・ロジックに集中させることが、AI 時代の開発における重要な論点になります。
本記事では HelloWorld として、CNCF を理解するための最小構成の使い方を紹介します。
デモ環境
コマンド実行
admin コンポーネントの system サービスは、ping オペレーションを提供しています。
オペレーションパスは次の通りです。
-
admin.system.ping
これは、CNCF 実行体がアクティブであることを確認するための最小のオペレーションです。
CNCF は Docker イメージとして配布されています。
以下のように入力すると、Docker で配布されている CNCF で ping オペレーションをコマンド実行します。
$ docker run --rm goldenport-cncf:0.3.2 command admin.system.ping
実行結果は以下のとおりです。
runtime: goldenport-cncf
runtime.version: 0.3.2
mode: command
subsystem: goldenport-cncf
subsystem.version: 0.3.2
サーバー実行
CNCF は、コマンド実行と全く同じ構成で、サーバーとして起動することができます。
サーバー実行時には REST API が公開され、HTTP 経由で外部からオペレーションを呼び出せます。
server オペレーションを指定すると、CNCF が REST サーバーとして立ち上がります。
$ docker run -p 8080:8080 goldenport-cncf:0.3.2 server
この時、ログが標準出力に表示されます。
[io-compute-0] INFO org.http4s.ember.server.EmberServerBuilderCompanionPlatform - Ember-Server service bound to address: [::]:8080
別ターミナルから curl コマンドを用いて ping を呼び出します。
$ curl http://localhost:8080/admin/system/ping
その結果、command オペレーションによるコマンド実行と同じ結果を得ることができました。
runtime: goldenport-cncf
runtime.version: 0.3.2
mode: server
subsystem: goldenport-cncf
subsystem.version: 0.3.2
mode は server となっており、command と server で、同一の Operation が異なる実行形態で動いていることが確認できます。
OpenAPI
CNCF は OpenAPI 定義も自動で提供します。
$ curl http://localhost:8080/openapi.json | jq
実行結果は以下のとおりです。 多数のオペレーションが組み込みで登録されていることがわかります。
{
"openapi": "3.0.0",
"info": {
"title": "CNCF API",
"version": "0.1.0"
},
"paths": {
"/admin/component/list": {
"get": {
"tags": [
"experimental:admin.component"
],
"summary": "admin.component.list",
"description": "Component: admin\nService: component\nOperation: list\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/admin/config/show": {
"get": {
"tags": [
"experimental:admin.config"
],
"summary": "admin.config.show",
"description": "Component: admin\nService: config\nOperation: show\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/admin/extension/list": {
"get": {
"tags": [
"experimental:admin.extension"
],
"summary": "admin.extension.list",
"description": "Component: admin\nService: extension\nOperation: list\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/admin/system/ping": {
"get": {
"tags": [
"experimental:admin.system"
],
"summary": "admin.system.ping",
"description": "Component: admin\nService: system\nOperation: ping\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/admin/variation/list": {
"get": {
"tags": [
"experimental:admin.variation"
],
"summary": "admin.variation.list",
"description": "Component: admin\nService: variation\nOperation: list\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/client/http/get": {
"get": {
"tags": [
"experimental:client.http"
],
"summary": "client.http.get",
"description": "Component: client\nService: http\nOperation: get\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/client/http/post": {
"get": {
"tags": [
"experimental:client.http"
],
"summary": "client.http.post",
"description": "Component: client\nService: http\nOperation: post\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/spec/export/openapi": {
"get": {
"tags": [
"experimental:spec.export"
],
"summary": "spec.export.openapi",
"description": "Component: spec\nService: export\nOperation: openapi\n(experimental; subject to change in Phase 2.8)",
"responses": {
"200": {
"description": "OK"
}
}
}
}
}
}
クライアント実行
サーバーは baseurl オプションで指定します。
今回は Docker イメージ内からホスト OS にアクセスするため、少し特殊な指定になっていますが、通常は一般的な URL を指定すれば問題ありません。
$ docker run --rm goldenport-cncf:0.3.2 \
client admin.system.ping \
--baseurl http://host.docker.internal:8080 \
admin.system.ping
実行の結果、以下のように ping オペレーションの結果が表示されました。
runtime: goldenport-cncf
runtime.version: 0.3.2
mode: client
subsystem: goldenport-cncf
subsystem.version: 0.3.2
この場合、CLI は CNCF サーバーと通信し、その結果を表示しています。
クラウド・サービスとして公開した CNCF に対して、専用の CLI を実装せずにそのまま操作できる点は、運用面でも大きな利点になります。
カスタム・コンポーネント
CNCF ではカスタム・コンポーネントを組み込んで使用することができます。
通常は sbt を用いたプロジェクト構成になりますが、HelloWorld では scala-cli を使った最小構成のスクリプトとしてコンポーネントを作成します。
引数に相当する call は ScriptActionCall というオブジェクトであり、ここから CNCF が提供する機能を利用できるようになっています。
#!/usr/bin/env -S scala-cli shebang
//> using repository "https://www.simplemodeling.org/maven"
//> using dep "org.goldenport:goldenport-cncf_3:0.3.2"
import org.goldenport.cncf.dsl.script.*
@main def main(args: String*): Unit = run(args) { call =>
"hello world"
}
それでは実行してみましょう。
$ ./greeting.scala
hello world
無事「hello world」が表示されました。
クラウド・サービスの開発や運用では、さまざまなユーティリティが必要になってきます。 こういったユーティリティを手軽に開発するための機能として、スクリプト機能を提供しています。
引数
次は引数を受け取る例です。 call の args を使って引数を受け取っています。 受け取った引数を通常の Scala プログラミングとして「hello」と連結しています。
#!/usr/bin/env -S scala-cli shebang
//> using repository "https://www.simplemodeling.org/maven"
//> using dep "org.goldenport:goldenport-cncf_3:0.3.2"
import org.goldenport.cncf.dsl.script.*
@main def main(args: String*): Unit = run(args) { call =>
"hello " + call.args(0)
}
パラメタとして「world」を与えてみます。
$ ./greeting.scala world
hello world
無事「hello world」が表示されました。
まとめ
本記事では、CNCF を実際に動かしながら、
-
command
-
server(REST / OpenAPI)
-
client
-
custom component(scala-cli)
という異なる実行形態を順に確認しました。
ここで重要なのは、実行形態が変わっても、内部の実行モデルは一切変わらないという点です。
CNCF では、
-
Service
-
Operation
という構造が一貫して保たれ、command / server / client / script はすべて、同一の Component / Operation を呼び出しているにすぎません。
この設計により、
-
CLI と REST を分けて実装する必要がない
-
OpenAPI が自動で生成される
-
スクリプトやユーティリティを本番と同じ実行モデルで書ける
といった利点が自然に得られます。
HelloWorld で確認したこの最小構成が、そのままクラウド・アプリケーション全体へと拡張されていきます。
参照
用語集
- Cloud Native Component Framework (CNCF)
-
Cloud Native Component Framework(CNCF)は、クラウド・アプリケーションを構成するコンポーネントを、単一かつ一貫した実行モデルで実行するためのフレームワークです。 Component / Service / Operation という構造を中核とし、command、server(REST / OpenAPI)、client、script といった異なる実行形態から、同一の Operation を再利用できることを特徴とします。 ログ、エラー処理、設定、配備といったクラウド・アプリケーションに必要な品質属性をフレームワーク側に集約することで、コンポーネントはドメイン・ロジックの実装に集中できます。 CNCF は、文芸モデル駆動開発および AI 支援開発を前提に、「何を実行するか」と「どのように呼び出すか」を分離するための実行基盤として設計されています。
- 文芸モデル (literate model)
-
文芸モデル(Literate Model)は、モデル構造と自然言語による語り(構造化文書)を統合した「読めるモデル」です。 文芸的プログラミング(Literate Programming)の思想をモデリング領域に拡張し、 構造(モデル)+語り(構造化文書) を一体化することで、人間とAIの双方が理解・操作できる知識表現を実現します。 「Literate Modeling(文芸的モデリング)」という発想自体は、 これまでにも一部の研究者や開発者によって試みられてきました。 しかし、それらは主にドキュメント生成やコード理解の支援にとどまっており、 モデルと言語・語り・AI支援を統合した体系的なモデリング手法として確立されたものではありません。 文芸モデル(Literate Model)は、SimpleModelingがAI時代に向けて新たに体系化・提唱したモデリング概念です。 文芸的モデリングの思想を継承しつつ、 AI協調型の知識循環とモデル生成を可能にする知的モデリング基盤として再構成されています。 文芸モデルは、単なるモデル記述技法ではなく、 人間の思考過程や設計意図を語りとしてモデルに埋め込み、 AIがそれを解析・再構成して設計や生成を支援するための枠組みです。
- コンポーネント (Component)
-
責務・契約・依存関係を明示的に定義し、再利用可能で交換可能な単位としてカプセル化されたソフトウェア構成要素。論理モデルでは抽象構造単位として、物理モデルでは実装・デプロイメント単位として扱われる。
- 文芸モデル駆動開発 (LMDD, Literate Model-Driven Development)
-
文芸モデル駆動開発(Literate Model–Driven Development, LMDD) は、自然言語による語りと形式的なモデル構造を統一されたテキスト基盤上で統合するソフトウェア開発手法です。従来のモデル駆動開発(MDD)を拡張し、ドキュメントとモデルを単一の整合的ソースとして扱います。 LMDDでは、開発成果物の記述要素と構造要素をSmartDox言語を用いて同時に表現します。この統合的な表現から、ModelDoxが構造データを抽出し、CML(Cozy Modeling Language)がドメイン固有モデルを定義し、Cozyが実行可能なコード、ドキュメント、構成情報などの成果物を生成します。 人工知能(AI)は、語りの文脈を解析し、構造の整合性を検証し、モデルおよび生成成果物の改良を支援することでLMDDプロセスに関与します。すべての成果物はテキスト形式で表現されるため、トレーサビリティ、バージョン管理、標準的な開発環境との相互運用性が確保されます。 ドキュメント、設計、実装の間に形式的かつ機械可読な関係を定義することにより、LMDDは人間による記述と機械による推論が同一の表現層で機能する、AI支援型モデル駆動開発の基盤を提供します。
- エラー (error)
-
汎用的な表現として用いられる用語。ソフトウェア工学では多義的に使われ、バグや障害全般を指す。SimpleModeling では広義のラベルとして使用し、個別には Mistake・Defect・Fault・Failure・Deviation に整理する。