株式会社日立製作所 研究開発グループ サービスコンピューティング研究部の長沼です。
今回はCloud Native Application Bundles(CNAB)を、開発ツールの1つであるporterを使って開発・利用してみましたので、その内容について紹介します。
CNABとは
CNABとは、分散型アプリケーションのインストールや管理のためのパッケージ仕様を定めたものです。KubeCon NA 2018で紹介され、以降、仕様のアップデートや関連ツールの開発が行われています。
CNABの基本的な構成要素は
- インストール処理を行うコンテナイメージであるinvocation image
- パッケージの説明やバージョン、対となるinvocation image名や処理実行時に入力するパラメータの定義などを記述したbundle.json、
となります。
要は、最近のCloud Nativeなアプリケーションを立ち上げようとすると、構築のために色々なクライアントツール入れ、構成定義を取得し、、、準備だけでも大変です。これを1コマンド(例えばdocker run)で、クライアントツール準備からアプリケーションのインストールまでやってくれる、そんなパッケージを作りましょう、という仕様です。
CNABを実現する開発ツール
CNABはパッケージの仕様であって、bundle.jsonやInvocation Imageの具体的な開発や利用方法までは定めていません。
全部手書き開発して、Invocation Imageをdocker runすれば利用することもできますが大変です。
そこでCNABの実装として、いくつかのツール(以下)も開発が進められています。
-
duffle:
bundle.json(とinvocation image)を用いてアプリケーションのインストール、アンインストールなどCNABの利用が可能。 -
porter:
porter.yamlというYAMLで記述された独自の書式をもとに、bundle.jsonとinvocation imageを生成。
helmやterraformのラインタイム(Mixinと呼ばれる)が用意されており、様々なプラットフォーム(Kubernetes, パブリッククラウドサービス etc.)に対してアプリケーションのインストールが可能。 -
docker-app:
docker-composeで用いるdocker-compose.yamlやそのメタ情報からbundle.jsonとinvocation imageを生成。
生成したinvocation imageを用いて、kubernetesまたはswarmへアプリケーションのインストールが可能。
今回は数あるツールの中からporterを用いて、CNABの開発・利用を行ってみることとしました。
porterによるCNABの開発・利用
https://github.com/deislabs/porter/blob/master/docs/content/quickstart.md
を参考に、
- porterをセットアップ
- helmによりkubernetesにアプリケーションをインストールするためのbundle.json、invocation imageを作成
- 作成したbundle.jsonとinvocation imageを用いて、事前に構築済みのkubernetesクラスタ(helm tillerも立ち上げ済)に実際にインストール(デプロイ)
を動かしてみた流れを紹介します。
なお今回使っているporterのバージョンはv0.10.0-beta.2であり、執筆時点で頻繁にアップデートされています。
このためバージョンによっては一部動作が異なる場合があります。
porterの準備
https://github.com/deislabs/porter/blob/master/docs/content/install.md
の記述を参考に、利用するクライアントのOSに対応したスクリプトを実行します。例えば、MacOSの場合は、以下となります。
curl https://cdn.deislabs.io/porter/canary/install-mac.sh | bash
なおプロキシ環境下で動作させる場合、mixinのインストール失敗する場合がありました。注意ください。
porterによる開発
まず今回開発するパッケージ用のディレクトリを作成・移動し、porter create
により雛型を生成します。
mkdir -p my-bundle/ && cd my-bundle
porter create
すると作成したディレクトリ(上記my-bundle)下に以下のような雛型が生成されます。
my-bundle
├── Dockerfile.tmpl
├── README.md
└── porter.yaml
次に、インストールに使うhelm chart(下記my-bundle/chart/my-noderedの部分)の追加と、生成されたporter.yamlの編集を行います。
今回の例は、サンプルとしてNode-REDのhelm chartを用い、
フローベースプログラミングツールNode REDをインストールする例を試しました。
- helm chartを追加したディレクトリ構成:
my-bundle
├── Dockerfile.tmpl
├── README.md
├── chart
│ └── my-nodered
│ ├── Chart.yaml
│ ├── templates
│ │ └── ...
│ └── values.yaml
└── porter.yaml
- 編集後のporter.yamlの内容:
name: my-bundle
version: 0.1.0
description: "An example Porter configuration"
invocationImage: path-to-registry/my-bundle:0.1.0
# インストールほか処理で利用するmixins(ランタイム)を定義すると、invocation imageビルド時に読み込まれる
mixins:
- helm
# デフォルトで読み込まれるkubeconfigの場所
credentials:
- name: kubeconfig
path: /root/.kube/config
# 変数の定義
parameters:
- name: release-name
type: string
default: default-name
install:
- helm:
description: "Install my-bundle"
name: "{{ bundle.parameters.release-name}}" #{{ bundle.parameters.xxx}}でparametersで指定の変数を読み込む
chart: chart/my-nodered #相対パスでchartの格納場所を指定
version: 0.1.0
replace: true
...
このように準備したディレクトリ下で
porter build
を実行すると、bundle.json(bundle.jsonはmy-bundle/.cnab/配下に格納)とinvocation imageが作成されます。
invocation imageの作成では、porter.yamlのmixins部分に指定のmixinを含むコンテナイメージが自動的に作成されるため、必要なツールを都度準備して格納するといった作業は不要となります。
porterによるインストール
同じく上記で準備したディレクトリ(my-bundle)下で
porter install
を実行します。
すると、対応するinvocation image(今回の場合は上記porter build
で作成したもの)内で定義されたinstall処理が実行されます。
具体的には、porter.yamlのinstall部分に記述された処理(今回の場合はhelm install chart/my-nodered
)が実行されることになります。
結果、対象としたkubernetesクラスタ上でNode REDがインストールされる(動作している)ことが確認できました。
なお作成済みのbundle.json、invocation imageを利用してインストールする場合は、オプションで次のように--cnab-file=
を指定することができます(bundle.jsonのkeyの一つとしてinvocation imageが含まれています)。
porter install --cnab-file=path_to/bundle.json
同様に、認証情報(今回の場合はkubeconfig)やporter.yamlに指定したパラメータ(今回の場合はrelease-name)をデフォルトから変更することもできます。
例えば、kubeconfigとしてクライアントのpath_to_kubeconfigディレクトリにあるmy-kubeconfigを用い、パラメータrelease-nameをchanged-nameに変更する場合、
- $HOME/credset.yaml:
name: my-credentials
credentials:
- name: kubeconfig
source:
path: /path_to_kubeconfig/my-kubeconfig
というファイルを用意しておき、オプションとして認証情報の変更:-c $HOME/cred.yaml
、変数の変更:-param release-name=changed-name
を付加した
poter install -c $HOME/credset.yaml -param release-name=changed-name
を実行することになります。
なおporterで認証情報を扱う仕組みとして、porter credentials
コマンドが用意されているように見えますが、今回はうまく動かすことができず利用を断念しました。こちらは引き続き調査したいと思います。
porterによるインストール内容の確認
porterでインストールしたbundleの内容は、
# 一覧の出力
porter bundles list
# 個々のインストールbundle(名称$NAME)の出力
porter bundles show $NAME
のコマンドにより確認することができます。
なお現仕様では、porterが動作するクライアントの$HOME/.porter
下に状態を管理するファイルが置かれており、その内容を整形・出力しているようです。
まとめ
porterを使ってCNABのinvocation image, bundle.jsonを作成し、サンプルのアプリケーションをkubernetesにインストール(デプロイ)することができました。
作成済みのCNABを利用しアプリケーション環境を構築する立場から見ると、環境構築のために色々なツールを準備せずコンテナが実行可能な環境(要はdocker runが可能)のみ用意すればよいため、便利そうな印象を受けました。
一方で、porterを使ったとしても、CNABのコンテンツ(bundle.jsonやinvocation image)を準備するのはまだまだ大変そうな印象です。また利用の立場でもinvocation imageの中の処理次第では、インストール先環境との不整合で結局うまく動かない場合も考えられます。
このあたりはCNABの周辺ツール含めて、動向を引き続きウォッチしていきたいと思います。