はじめに
Code Engineを使用していて、もしBuildpack StrategyでOpenlibertyをランタイムとしたJavaアプリを動かしたい、と思った場合に2022年7月6日時点でどうするべきかを記事として取り上げます。
Code Engineは、IBM Cloudで提供されるフルマネージドなコンテナ実行基盤になります。持ち込みのコンテナ・イメージ(x86_64)のほか、Cloud Foundryと同じくBuildpackの仕組みを用いてアプリを動かすことができるのが特徴の基盤です。
以下のリンク[1]など、Web上でOpenLibertyとCode Engineをキーワードに検索しても明確な記載が見当たらなかったため、実際にどうすればBuildpack StrategyでOpenLibertyを利用できるかを整理したものになります。
今後仕様も変わるかと思います。変更され次第、情報を修正しようと思います。
この記事執筆のきっかけ
Code Engineでは、2種類のアプリケーションのビルド戦略が提供されています。
- Dockerfile
- Cloud Native Buildpack
Dockerfile Strategyは、事前にユーザーがDockerfileをソースコードと共に準備しておくことで任意のコンテナ・イメージをCode Engine上でビルドできます。そのため、OpenLibertyをはじめとし、自由にアプリのランタイムを決めてコンテナ・イメージをビルドすることが可能となっています。(ただし、利用するSWが商用SWの場合は製品上サポートされるかは各ベンダーに問い合わせが必要です。)
Cloud Native Buildpack Strategy (長いので以後Buildpack Strategyと記載)は、Cloud Foundry/Herokuで利用されていたBuildpackと同様に、ビルド時にアプリのソースコードの構造を見てランタイムを判断し、適切なビルドを行ってくれる仕組みです。例えば、ソースコードのルートディレクトリにpackage.jsonというファイルがあれば、Node.jsのアプリと判断しBuildpack側でよしなにランタイムを組み立て、コンテナイメージを生成してくれます。対応するランタイムは以下のリンク[2]に記載があります。
このBuildpackはPaketoベースで実装されているとリンク[2]に記載がありますが、一方で、2022年の4月にOpenLiberty ProjectにてPaketo BuildpackのランタイムとしてOpenLibertyも選択できるようになったと記事が投稿されました。
この記事を見て、「ではCode EngineのBuildpack StrategyでOpenLibertyをランタイムにしたアプリがデプロイできますね!」と思い、試してみようと思ったのがこの記事執筆のモチベーションです。
結論としてどうする?
試してみた結果として、Buildpack StrategyでOpenLibertyをランタイムにしたビルドを行うことは可能です。ただし、執筆時点(2022年7月6日)では、IBM CloudのWebコンソールおよびIBM Cloud CLI(ibmcloud ce)にはビルドに対して環境変数BP_JAVA_APP_SERVERを設定する方法が提供されていないため、Code EngineをkubectlコマンドでBuildを直接定義する必要があります。
まずは実験 (執筆時点ではNGケース)
まず、IBM CloudのWebコンソールでサクッとビルドして動作を確認してみます。
ビルドの手順の詳細はチュートリアルを確認ください。
アプリはリンク[3]の紹介記事に合わせて、OpenLibertyのサンプルを利用します。
また、ビルド成果物はコンテナ・イメージとして生成されますが、今回はICR (IBM Cloud Container Registry)を使用する前提とし、事前に認証情報はibm-container-registryとしてCode Engineに登録済みとします。
Buidpack Strategyでの設定
Code Engineのイメージ・ビルドの項目でビルドの動作及び設定を行いますが、執筆時点で以下の図にある設定が可能となっています。ビルド時の環境変数の指定の項目はどこにもないですね。
ちなみにIBM Cloud CLIにも記載はありませんでした。
% ibmcloud ce build create --help
名前:
create - ビルドを作成します。
使用法:
create --name BUILD_NAME [options...]
オプション:
--name, -n value 必須。 ビルドの名前。
--build-type, --bt value ビルドのタイプ。 有効な値は「git」および「local」です。 (デフォルト: "git")
--commit, --cm, --revision value プルするソース・リポジトリーのコミット、タグ、またはブランチ。
--context-dir, --cdr value ビルドパック・ファイルまたは Dockerfile を含むリポジトリー内のディレクトリー。
--dockerfile, --df value Dockerfile へのパス。 (デフォルト: "Dockerfile")
--force, -f 指定されたシークレット参照の存在を検査しません。 (デフォルト: false)
--git-repo-secret, --grs, --repo, -r value コンテナー・イメージのビルド用のソース・コードを含むプライベート・リポジトリーへのアクセスのための、Git
リポジトリーのアクセス・シークレットの名前。
--image, -i value
イメージ・レジストリーのロケーション。形式は「REGISTRY/NAMESPACE/REPOSITORY:TAG」で、「TAG」はオプションです。「TAG」が指定されない場合、デフォルトは「latest」です。
--output, -o value 出力フォーマット。有効な値は、'json'、'yaml'、'jsonpath=JSONPATH_EXPRESSION'、および 'jsonpath-as-json=JSONPATH_EXPRESSION' です。
--quiet, -q このオプションを指定すると、コマンドの出力が削減されます。 (デフォルト: false)
--registry-secret, --rs value
イメージ・レジストリーのアクセス・シークレットの名前。コンテナー・イメージを作成する際、イメージ・レジストリーのアクセス・シークレットを使用して、プライベート・レジストリーで認証します。レジストリー・シークレットを作成するには、'ibmcloud
ce registry create' を実行します。
--size, --sz value ビルドに使用するサイズ。これにより、使用されるリソースの量が決定します。有効な値として、small、medium、large、xlarge
があります。詳しくは、https://cloud.ibm.com/docs/codeengine?topic=codeengine-plan-build#build-size を参照してください。 (デフォルト: "medium")
--source, --src value Git リポジトリーの URL。
--strategy, --str value イメージのビルドに使用する戦略。有効な値は、'dockerfile' および 'buildpacks' です。 (デフォルト: "dockerfile")
--timeout, --to value ビルドが成功または失敗するまでに経過可能な時間 (秒)。 (デフォルト: 600)
--help, -h ヘルプを表示します。 (デフォルト: false)
ビルド実施時のBuildpackの選択動作の確認
実際にビルドを実行すると、ビルドの初期ステップでソースコードに合わせて適切と思われるBuildpackが以下のようにログに出力されます。このBuildpack群は上から順に適用されていく挙動のようなので、libertyよりもapache-tomcatが優先になっているのがすごく気になります。。。
ビルドされたイメージを利用したアプリの動作確認
実際に作成されたイメージを利用して、以下の図のような設定でアプリをデプロイします。Listenするポート番号はOpenLibertyならばおそらく9080番だろうということで、デフォルトの8080番から変更しています。

実際にアプリのデプロイを行うも、うまく起動完了まで辿り着きません。コンテナのログを見てみると「org.apache.catalina」など、明らかにApache Tomcatベースで起動しているのが確認できます。。ちなみにListenポートもこのログから8080番だと読めますので、起動失敗するのは納得です。
OpenLiberty Buildpackを指定する方法 (OKなケース)
では、BuildpackでどうしてもOpenLibertyをデプロイしたい場合はどうするかに踏み込みます。
Buildpackの選出方法をきちんと理解すれば対策は立てられますので、まずは以下のBuildpackの説明をきちんと読みます。
選出される条件が記載されていますが、最も重要と思うのは環境変数BP_JAVA_APP_SERVERに対する条件です。とりあえずlibertyという値をセットしてビルドを行えば動作が変わりそうです。
とはいえ、上述した通りビルド時に環境変数を設定する項目は今のところなさそうです。そのため、Code Engine側が提供している直接Kubernetesとしてkubectlコマンドで操作する方法で対応します。
Code Engineへのアクセス
IBM Cloud CLI (ibmcloud) およびkubectlコマンドが導入されている前提で、まずはIBM Cloudにログインします。
ibmcloud login -r <リージョン(jp-tokなど)> -g <リソースグループ名> <ログインオプション(--sso, --apikeyなど)>
その後、Code Engineで利用したいプロジェクトを選択しますが、この際に「--kubecfg」をつけてアクセスします。
ibmcloud ce project select --name <プロジェクト名> --kubecfg
これでkubectlコマンドでCode Engineにアクセスできるようになっているはずです。実際にkubectl get pod
などを実行して、接続できているかを確認します。
% kubectl get pod
NAME READY STATUS RESTARTS AGE
openliberty-build-run-220602-2333080-kxwfj-pod 0/2 Completed 0 80m
また、提供されているKubernetesのNamespaceがわからない場合、Code Engineにおいてはkubectl config current-context
でざっくり確認できます。
% kubectl config current-context
p3tasofreum
ビルドの作成
接続できたら、ビルドの定義を作成します。kubectl get build
で既存のビルド設定を参考にしつつ、以下のようなBuild定義を作成します。envで環境変数BP_JAVA_APP_SERVERを設定しているのがポイントです。Shipwrightを利用しているので、Buildのカスタマイズに関してはShipwrightのDocも確認すると良いと思います。
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
annotations:
build.shipwright.io/build-run-deletion: "true"
name: openliberty-test-build2
namespace: p3tasofreum
spec:
dockerfile: Dockerfile
output:
credentials:
name: ibm-container-registry
image: private.jp.icr.io/ra1nmaker/openliberty-test
source:
contextDir: finish
revision: prod
url: https://github.com/openliberty/guide-getting-started.git
strategy:
kind: ClusterBuildStrategy
name: buildpacks-v3-medium
timeout: 10m
env:
- name: BP_JAVA_APP_SERVER
value: "liberty"
ファイルとして作成したら、kubectl apply
で直接適用します。
% kubectl apply -f build-openliberty.yml
build.shipwright.io/openliberty-test-build2 created
作成すると、IBM CloudのWebコンソール画面にも表示されます。
ビルド実施時のBuildpackの選択動作の確認
作成したビルドをベースに実行します。実行ログを見てみると、今度はapache-tomcatのBuildpackは選出されていないです。
ビルドされたイメージを利用したアプリの動作確認
実際に再度アプリをデプロイ、あるいはリビジョンの更新を行います。設定はNGケースと同じ設定で実行します。
デプロイ完了後、以下のログのように、明確にOpenLiberty起動時のメッセージが確認できるので、OpenLibertyで起動できていると判断できます。
アプリの起動も正常完了したので、OpenLibertyのBuildpackではOpenLibertyのListenポートはデフォルトだと9080番をListenしていることもこちらで判断できます。
さいごに
アプリのビルド時に環境変数を指定できる機能はBuildpack選出の仕様を考慮すると必要だと思います。
改善リクエストをあげてみようと思いますが、現時点でOpenLiberty Buildpackを利用したい場合は参考にしていただければ幸いです。