モデルをコンテナ化

概要

このトピックでは、Dockerを使用したFlexSimモデルのコンテナ化について説明します。コンテナ化したモデルは、一般にウェブアプリケーションの一環であるサービスとして使用できます。Dockerとコンテナの全般的な情報については、Dockerのドキュメントを参照してください。

このトピックは、次の手順から成るウォークスルーです。

  1. 適切に設定されたライセンスサーバーを作成する
  2. Docker Desktopをインストールする
  3. モデルを作成する
  4. イメージを作成する
    • ビルドコンテキストを作成する
    • イメージ上にFlexSimをインストールする
    • イメージにライセンスファイルを追加する
    • イメージにモデルを追加する
  5. コンテナをテストし、デバッグする

各手順について以降のセクションで解説します。

コンテナのライセンスを発行する

コンテナのライセンスを発行するには、ライセンスサーバーを使用する必要があります。方法としては、パブリックライセンスサーバーを作成し、そこにコンテナで使用するランタイムライセンスのプールを配置することをお勧めします。このライセンスサーバーはパブリックであるため、オプションファイルで設定された任意のシークレットキーを使用してライセンスを保護できます。単純なケースでは、次のようなオプションファイルを使用できます。

TIMEOUTALL 900
PROJECT secret-key
INCLUDEALL PROJECT secret-key

ライセンスをチェックアウトするには、クライアントにLM_PROJECTという環境変数が存在し、値がsecret-keyに設定されている必要があります。

ライセンスサーバーがまだ利用できない場合でも、このウォークスルーを実行できます。コンテナから起動するときに、/maintenanceスイッチにevaluationlicenseを含めてください。たとえば、/maintenance nogui_evaluationlicenseと指定します。ランタイムライセンスの取得とライセンスサーバーの作成の詳細については、お近くのディストリビューターまたはリセラーにお問い合わせください。

Docker Desktopをインストールする

Docker Desktopは、https://www.docker.com/products/docker-desktop/からダウンロードできます。なお、一部の商用利用では有料のサブスクリプションが必要です。Dockerのライセンス契約およびポリシーに準拠するようにしてください。

Docker Desktopをインストールし、起動すると、Dockerエンジンが実行されます。

モデルを作成する

コンテナでは大半のFlexSimモデルを使用できます。モデルをサービスとして使用する場合は、外部との通信ができるようにそのモデルを強化する必要があります。このセクションでは、この通信を設計するときに役立つ考え方や推奨機能を紹介します。このセクションは出発点であり、お客様のユースケースを完全にカバーするものではありません。

1つの一般的なパターンは、Pythonレイヤーを使用して通信を管理する方法です。

内部/外部 コンテナ Python FlexSim

Pythonは非常に有名な言語であり、幅広いソースとの接続をサポートできます。ウェブサービスとデータベースの多くが、こうしたサービスとの接続のためにPythonパッケージを提供しています。

FlexSimは、次のようにさまざまな方法でPython(または他のサービス)と通信できます。

  • ファイルの読み書き
    • Excelのインポート/エクスポート
    • XMLファイルのインポート/エクスポート
    • JSONファイルのインポート/エクスポート
    • 一般ファイルのI/O
  • HTTPリクエスト
  • MQTTメッセージ
  • SQLデータベース接続
  • ソケット通信

Pythonを使用する場合は、FlexSimの起動と制御のためにFlexSimPyモジュールの使用を検討する必要があるかもしれません。詳細については、https://github.com/flexsim/FlexSimPyを参照してください。

さらに、FlexSimを起動するために、コマンドラインパラメータをカスタマイズして使用することもできます。基本的なコマンドライン構文は次のとおりです。

flexsim.exe path\to\model.fsm /maintenance nogui [additional args]

このモデルパスは、他のスイッチや引数(実行ファイル以外)より前に配置する必要があります。コンテナ内で実行するには、/mainentance noguiスイッチが必要です。このスイッチがあれば、FlexSimはウィンドウの作成を試みません。しかしその後には、必要なものを何でも指定することができます。たとえば、Pythonを使用して外部ソースからデータを取得し、そのデータをファイルに書き込むと仮定します。その場合、次の引数を使用してFlexSimを起動できます。

flexsim.exe path\to\model.fsm /maintenance nogui /datafile path\to\file.csv

その後で[モデルを開いたとき]トリガーを追加し、次のようなコードを追加できます。

string dataFilePath = commandlineparam("datafile");
if (fileexists(dataFilePath)) {
	importtable(Table("GlobalTable1"), dataFilePath, 1);

	// Run the model
	// ...

	// Write a file or communicate results somehow
	// ...
}

最終的に、モデルとコンテナの正確な設計は、ニーズと設定に基づきます。

テストモデルを作成する

コンテナがライセンスサーバーに正しくアクセスすることをテストケースで確認すると効果的です。そのためには、どのライセンスを検出できたかをFlexSimに報告させます。モデルを作成し、[モデルを開いたとき]トリガーに次のコードを追加します。

if (commandlineparam("showlicense") == "1") {
	fileopen(modeldir() + "licenseinfo.txt");
	
	Array features = [
		["DragDropConnect", CLF_DRAG_DROP_CONNECT],
		["CreateObject", CLF_CREATE_OBJECTS],
		["NoModelLimit", CLF_NO_MODEL_LIMIT],
		["Stochastics", CLF_STOCHASTICS],
		["EntireTree", CLF_ENTIRE_TREE],
		["ModelTree", CLF_MODEL_TREE],
		["ConsoleScript", CLF_CONSOLE_SCRIPT],
		["Compile", CLF_COMPILE],
		["CommercialUse", CLF_COMMERCIAL_USE],
		["OptQuest", CLF_OPTQUEST],
		["XMLSaveLoad", CLF_XMLSAVELOAD],
		["StudentOptQuest", CLF_OPTQUEST_STUDENT]
	];
	
	for (int i = 1; i <= features.length; i++) {
		string featureName = features[i][1];
		int hasFeatures = licensehasfeature(features[i][2]);
		fpt(featureName + ": "  + (hasFeatures ? "Yes" : "No")); fpr();
	}

	fileclose();
	cmdexit();
}

上記のコードは、どのライセンス機能が使用できるかを確認して、結果をファイルに出力した後、終了します。ランタイムライセンスの機能のうち、モデルを実行して結果を得るために必要な中心的機能は、CLF_NO_MODEL_LIMITCLF_STOCHASTICSCLF_COMMERCIAL_USEのみです。

イメージを作成する

モデルができたので、イメージを作成する準備が整いました。イメージを作成するには、まずディレクトリを作成する必要があります。このディレクトリがビルドコンテキストになります。このセクションの目標は、次のフォルダー構造を作成することです。

[わかりやすい名前のフォルダー]
 ├─ install
 │   └── FlexSim_<バージョン>_x64.msi
 ├─ license
 │   └── flexsim_server.lic
 ├─ test
 │   └── test_model.fsm
 └─ Dockerfile

FlexSimインストーラーを入手するには、FlexSimのWebサイトのダウンロードセクションにアクセスし、.msiファイル(.exeファイルではない)をダウンロードします。このファイルを上記のようにフォルダー構造内に配置します。モデルに必要なFlexSimのバージョンを使用してください。

flexsim_server.licを取得するには、flexsim_server.licというテキストファイルを上記の場所に作成します。このファイルには次のような形式です。

SERVER 0.0.0.0 ANY 26914
VENDOR flexsim
USE_SERVER
FEATURE serverfeature flexsim 1.000 permanent uncounted HOSTID=ANY \
	SIGN="05CB 6F61 116D 06E3 A08D CAFB FC5C BEF3 DF53 BDC6 AF68 \
	060C 27B8 9968 CB94 0515 2BE7 E30C 2FAF C0D6 1D77 CCEB 878E \
	2D67 1434 0E3F 6BA5 1FDA BD35 F98D"

ただし、IPアドレス(SERVERの直後)は、使用するライセンスサーバーのIPアドレスに置き換えてください。

前のセクションのテストモデルを上記のtestディレクトリに保存します。名前を指定して保存すると便利ですが、必須ではありません。

最後に、Dockerfileを作成します。Dockerfileという名前(拡張子なし)の新しいテキストドキュメントをディレクトリに作成します。内容は次のとおりです。

# Start with a windowsservercore image
# See https://hub.docker.com/r/microsoft/windows-servercore for the latest version
FROM mcr.microsoft.com/windows/servercore:ltsc2022

# Copy the install directory from the context (this folder) to an install directory on the image
COPY ./install ./install

# Install FlexSim
RUN msiexec /i install\FlexSim_<version>_x64.msi /quiet /passive /norestart INSTALLDIR=C:\FlexSim

# Copy the license file
ARG programDir="C:/FlexSim/program/"
COPY ./license/flexsim_server.lic $programDir

# Add the programDir to the path
RUN setx path "%path%;%programDir%"

# Enter a secret key for licensing
ENV LM_PROJECT="enter-your-secret-key-here"

# Copy the test directory to make those files available
COPY ./test ./test

# Set the starting command of the image
CMD [ "Cmd.exe" ]

Dockerfileには、基本イメージを修正して新しいイメージを作成する旨の指示が含まれています。このケースでは、まずwindowsservercoreコンテナから始まります。次に、FlexSimインストーラーを実行し、追加ファイルをコピーします。ダウンロードしたファイルに合わせて、インストーラーの<version>を変更してください。

コンテキストフォルダーができたので、そのコンテキストからイメージを作成できます。ターミナルから次のコマンドを実行します。

docker build -t my-container .

-tスイッチにはイメージ名を指定します。名前は必要に応じて変更できます。

トラブルシューティング

この手順で問題が発生した場合は、次の対処方法を試してください。

  • Dockerが実行中であることを確認します。
  • DockerがWindowsモードであることを確認します。
  • Dockerfileで指定したパスと名前がコンテキストフォルダーのパスおよび名前と一致することを確認します。

コンテナを実行する

コンテナを実行するには、docker runコマンドを使用します。

docker run -i my-container

最後の引数は、実行するイメージの名前です。-iスイッチは、コンテナのターミナルを操作することを示します。

コンテナが実行中であれば、コンテナのターミナルを使用できるはずです。次のコードを使用してテストモデルを実行します。

flexsim C:\test\TestLicense.fsm /maintenance nogui /showlicense 1

ターミナルコマンドからはすぐに返信がありますが、FlexSimの実行には少し時間がかかる場合があります。ライセンスサーバーのIPアドレスまたはLM_PROJECTキーに誤りがある場合、ライセンス取得の試行に30秒以上かかります。FlexSimがまだ実行中かどうかを検出するには、コマンドラインで次のコマンドを使用します。

tasklist /fi "IMAGENAME eq flexsim.exe"

FlexSimが完了すると、ライセンス情報がテキストファイルに書き込まれます。このファイルは次のコマンドで読み取ることができます。

more test\licenseinfo.txt

すべてが正常に処理されれば、FlexSimがライセンスサーバーから必要なライセンスを取得できたことがわかります。コンテナのターミナルを終了するには、CTRL-Cを使用します。

コンテナの例

モデルをサービスとして実行する例を確認するには、次の手順を実行します。

  1. 次のzipファイルをダウンロードして展開します:
    ContainerDemo.zip
  2. FlexSimの最新インストーラー(.msiファイル)をダウンロードします。このインストーラーをContainerDemo/installフォルダーに配置します。
  3. ダウンロードしたインストーラー名に合わせて、ContainerDemo/Dockerfileのインストーラー名を更新します。
  4. ターミナルでContainerDemoディレクトリに移動し、次のコマンドでイメージをビルドします。
    docker build -t container-demo .
  5. 次のコマンドでコンテナを実行します。
    docker run -d -p 8000:8000 container-demo
  6. ブラウザーでlocalhost:8000にアクセスします。

ページが表示され、モデルパラメータの変更、モデルの実行、結果の確認を行うことができます。ジョブの実行から結果の表示までに数秒かかります。

説明

このデモには次のファイルがあります。

  • index.html - このページはウェブサーバーが表示するデフォルトページです。フォームとして機能します。また、このページは、フォームをJSONに変換してそれをサーバーにPOSTリクエストとして送信し、応答を処理するまでのロジックも提供します。
  • server.py - アプリケーションの中心となる部分です。ブラウザーからのHTTPリクエストを処理します。また、POSTリクエストを処理するようにカスタマイズされています。POSTリクエストを受信すると、server.pyはJSONデータを一時ファイルに書き込みます。次にモデルをFlexSimで開き、一時ファイルのパスを渡します。処理が終了すると、結果のデータがリクエストの応答として送信されます。
  • model.fsm - このモデルには、ファイルパスの有無をチェックする[モデルを開いたとき]トリガーがあります。ファイルが存在する場合、モデルはそのファイルに基づいてパラメータを設定します。次に、モデルは時間1000まで実行され、パフォーマンスの測定をすべて出力ファイルに書き込みます。最後にFlexSimが終了します。
  • Dockerfile - DockerfileはPythonイメージを使用します。次にFlexSimをインストールし、サーバーファイルをコピーします。最後に、server.pyファイルを実行します。

このデモは、あくまでも出発点です。有効なコンテナを作成するには、さまざまな方法があります。このデモの各要素には、おそらく改善の余地があります。必要に応じて自由に変更を加え、改善してください。