はじめに
Open Libertyをコンテナとして実行するとき、Docker Hubで公開されている公式イメージを元にするのが容易です。ただ、Java実行環境とOpen Libertyを個別に変更したいこともあります。本記事では、UBIマイクロイメージを元とし、Java実行環境とOpen Libertyを追加した軽量なイメージを作成して「Red Hat OpenShift on IBM Cloud」にデプロイします。
■ Open Liberty公式イメージ
1. Open Libertyパッケージング
1.1. Open Liberty用Gradleプラグイン設定
Open Liberty用Gradleプラグインには、Open Libertyランタイムとサーバー構成、ビルド済のWebアプリケーション(warファイル)を複数種類の形式でパッケージングする「libertyPackage」タスクがあり、同タスクではOpen Libertyのサイズを縮小することも可能です。
The libertyPackage task is used to create a ZIP, TAR, TAR.GZ or JAR archive of your Liberty runtime and server.
以前の記事で利用したbuild.gradleにて、Open Libertyバージョンを最新の「21.0.0.11」とし『minify』でパッケージする設定を追加します。デフォルト動作は『all』です。
plugins {
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'io.openliberty.tools.gradle.Liberty' version '3.2'
id 'java'
id 'war'
}
group = 'dummy'
version = ''
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '21.0.0.11'
}
test {
useJUnitPlatform()
}
liberty {
server {
name = 'defaultServer'
deploy {
apps = [file('build/libs/spring-liberty-plain.war')]
}
packageLiberty {
include = "minify"
os = "Linux"
packageType = "tar.gz"
}
}
}
clean.dependsOn 'libertyStop'
1.2. Open Libertyパッケージタスク実行
『gradle libertyPackage』によりパッケージされ「build/libs/spring-liberty.zip」が作成されます。
gradle libertyPackage
### 標準出力↓
> Task :installFeature
> Task :deploy
Application spring-liberty-plain.war was installed as a file as specified. To install as a loose application, specify the plugin or task generating the archive.
BUILD SUCCESSFUL in 38s
10 actionable tasks: 10 executed
オプションによるパッケージサイズ等の差異は下表の通りです。『minify』は『all』と比較して、Open Libertyランタイムのサイズがかなり小さくなっていることが分かります。
2. Open Libertyコンテナイメージ作成
2.1. Java実行環境
Java実行環境として、下記URL記載の「IBM Semeru 11」をダウンロードしておきます。
ls -l
### 標準出力↓
-rw-r--r--. 1 root root 43966499 11月 20 17:44 ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz
2.2. UBIマイクロコンテナイメージへのパッケージ追加
UBIマイクロコンテナイメージに、Java実行環境とOpen Libertyの実行に必要なパッケージを追加し、タグ「liberty-base」としてDocker Hubにプッシュします。Java実行環境とOpen Libertyを追加したコンテナイメージの作成は次章で行います。
microcontainer=$(buildah from redhat/ubi8-micro)
micromount=$(buildah mount $microcontainer)
yum install \
--installroot $micromount \
--releasever 8 \
--setopt install_weak_deps=false \
--nodocs -y \
libstdc++-devel sed grep which
yum clean all \
--installroot $micromount
buildah umount $microcontainer
buildah commit $microcontainer liberty-base
podman tag liberty-base <アカウント名>/<リポジトリ名>:liberty-base
podman login docker.io
podman push <アカウント名>/<リポジトリ名>:liberty-base
3. OpenShiftへのデプロイ
3.1. コンテナイメージのビルド
OpenShiftでコンテナイメージをビルドします。結果としてイメージストリームが作成されます。
コンテナイメージサイズを小さくするために、マルチステージ・ビルドとしています。
ls -l
### 標準出力
-rw-r--r--. 1 root root 961 11月 21 22:06 Dockerfile
-rw-r--r--. 1 root root 43966499 11月 20 17:44 ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz
-rw-r--r--. 1 root root 45347557 11月 21 22:14 spring-liberty.tar.gz
oc new-project spring-liberty
oc new-build --name=spring-liberty --strategy=docker --binary
oc start-build spring-liberty --from-dir=. --follow
### 標準出力↓
Uploading directory "." as binary input for the build ...
…
STEP 1: FROM <アカウント名>/<リポジトリ名>:liberty-base AS builder
STEP 2: ADD ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz /opt
--> 1fee53489ae
STEP 3: ADD spring-liberty.tar.gz /opt
--> 1a1f57daba2
…
Push successful
oc get is
### 標準出力↓
NAME IMAGE REPOSITORY TAGS UPDATED
spring-liberty image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty latest 7 seconds ago
FROM <アカウント名>/<リポジトリ名>:liberty-base as builder
ADD ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz /opt
ADD spring-liberty.tar.gz /opt
WORKDIR /opt
RUN mkdir -p /opt/wlp/output/defaultServer \
&& chmod -R g+rw /opt \
&& chmod +x /opt/wlp/bin/server \
&& mkdir /logs \
&& chmod -R g+rw /logs
FROM <アカウント名>/<リポジトリ名>:liberty-base
ENV PATH=/opt/wlp/bin:/opt/jdk-11.0.13+8-jre/bin:$PATH \
LOG_DIR=/logs \
WLP_OUTPUT_DIR=/opt/wlp/output
COPY --from=builder /opt/wlp /opt/wlp
COPY --from=builder /opt/jdk-11.0.13+8-jre /opt/jdk-11.0.13+8-jre
COPY --from=builder /logs /logs
RUN ln -s /opt/wlp/output/defaultServer /output \
&& ln -s /opt/wlp/usr/servers/defaultServer /config
EXPOSE 9080
CMD ["/opt/wlp/bin/server", "run", "defaultServer"]
3.2. コンテナのデプロイ
Deployment「spring-liberty」としてコンテナをデプロイします。
oc apply -f spring-liberty.yaml
oc get pod,svc,ing
### 標準出力↓
NAME READY STATUS RESTARTS AGE
pod/spring-liberty-1-build 0/1 Completed 0 7m24s
pod/spring-liberty-84c44ffc5b-gqpnp 1/1 Running 0 68s
pod/spring-liberty-84c44ffc5b-lzccq 1/1 Running 0 68s
pod/spring-liberty-84c44ffc5b-x88bj 1/1 Running 0 68s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/spring-liberty ClusterIP 172.21.255.127 <none> 80/TCP 68s
NAME CLASS HOSTS ADDRESS
PORTS AGE
ingress.networking.k8s.io/spring-liberty <none> spring-liberty.apps.ocp.cloud.vpc router-default.roks-jp-tok-3-bx2-4x16-db921bfba21f21a261dcbdfd
d8987265-i000.jp-tok.containers.appdomain.cloud 80 68s
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-liberty
labels:
app: spring-liberty
spec:
replicas: 3
selector:
matchLabels:
app: spring-liberty
template:
metadata:
labels:
app: spring-liberty
spec:
containers:
- name: spring-liberty
image: image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty
ports:
- containerPort: 9080
readinessProbe:
httpGet:
path: /healthz
port: 9080
---
apiVersion: v1
kind: Service
metadata:
name: spring-liberty
spec:
selector:
app: spring-liberty
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 9080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-liberty
spec:
rules:
- host: spring-liberty.apps.ocp.cloud.vpc
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: spring-liberty
port:
number: 80
4. コンテナサイズについて
4.1. OpenShiftで作成したコンテナサイズの確認
OpenShiftにデプロイしたコンテナのイメージは、各workerノードのCRI-Oコンテナエンジンがダウンロードしています。crictlコマンドで確認したところ、「spring-liberty」コンテナイメージのサイズは「238MB」でした。
oc debug node/10.244.32.4
### 標準出力↓
Starting pod/10244324-debug ...
To use host binaries, run `chroot /host`
chroot /host
### 標準出力↓
Pod IP: 10.244.32.4
If you do not see a command prompt, try pressing enter.
crictl images | grep "spring-liberty" | grep "latest"
### 標準出力↓
image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty latest 6250bd030d7e1 238MB
4.2. Podmanで作成したコンテナサイズの比較
Podmanでコンテナをビルドしたときのサイズを下表にまとめます。
Open Liberty公式イメージを元にした場合と比較して、UBIマイクロを元にした場合は半分以下のサイズになりました。サイズ差異は、OSライブラリが異なること(ubunts⇔ubi8-maicro)、Open Libertyに含まれるライブラリが異なること(すべて⇔必要最小限)から生じています。
■ UBIマイクロを元にした場合
■ 参考情報
`
■ Open Libertyを元にした場合
podman images | egrep "localhost|ubi8-micro|open-liberty"
### 標準出力
localhost/spring-liberty-official latest cc8e92f49b93 3 minutes ago 540 MB
localhost/spring-liberty-multi latest 8ca620024c71 4 minutes ago 238 MB
localhost/spring-liberty-single latest 82b26d37234a 6 minutes ago 416 MB
localhost/liberty-base latest 009a113d13db 6 minutes ago 59.7 MB
docker.io/library/open-liberty 21.0.0.11-full-java11-openj9 37333a74cc7b 2 weeks ago 527 MB
docker.io/redhat/ubi8-micro latest c8efdc89ddd2 2 weeks ago 38.7 MB
4.3. UBIマイクロを元にしたマルチステージ・ビルドについて
シングルステージ・ビルドの場合、liberty-base:59.7MBにJava実行環境:123MBとOpen Liberty・アプリ:49MBを追加します。合計すると231.7MBですが、実際に作成されたコンテナイメージのサイズは416MBでした。イメージのヒストリーを確認したところ、ディレクトリ作成・権限変更をしている箇所で178MB増加していました。ディレクトリ作成・権限変更を別ステージで実行=マルチステージ・ビルドすることで、ほぼ想定通りの238MBのイメージが作成されました。
8 minutes ago /bin/sh -c mkdir -p /opt/wlp/output/defaul... 178 MB
Dockerfileとヒストリーは以下の通りです。
cat ./single/Dockerfile
### 標準出力↓
FROM <アカウント名>/<リポジトリ名>:liberty-base
ENV PATH=/opt/wlp/bin:/opt/jdk-11.0.13+8-jre/bin:$PATH \
LOG_DIR=/logs \
WLP_OUTPUT_DIR=/opt/wlp/output
ADD ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz /opt
ADD spring-liberty.tar.gz /opt
WORKDIR /opt
RUN mkdir -p /opt/wlp/output/defaultServer \
&& chmod -R g+rw /opt \
&& chmod +x /opt/wlp/bin/server \
&& ln -s /opt/wlp/output/defaultServer /output \
&& ln -s /opt/wlp/usr/servers/defaultServer /config \
&& mkdir /logs \
&& chmod -R g+rw /logs
EXPOSE 9080
CMD ["/opt/wlp/bin/server", "run", "defaultServer"]
podman history localhost/spring-liberty-single
### 標準出力↓
ID CREATED CREATED BY SIZE COMMENT
cdebeab35069 8 minutes ago /bin/sh -c #(nop) CMD ["/opt/wlp/bin/serve... 0 B
<missing> 8 minutes ago /bin/sh -c #(nop) EXPOSE 9080 0 B
<missing> 8 minutes ago /bin/sh -c mkdir -p /opt/wlp/output/defaul... 178 MB
91bbe4104f1b 8 minutes ago /bin/sh -c #(nop) WORKDIR /opt 0 B
<missing> 8 minutes ago /bin/sh -c #(nop) ADD file:e0cf85c990987ef... 49.6 MB
fce619af2bd1 8 minutes ago /bin/sh -c #(nop) ADD file:07363d12ccff3d1... 128 MB
4767b35696bf 8 minutes ago /bin/sh -c #(nop) ENV PATH=/opt/wlp/bin:/o... 0 B FROM docker.io/<アカウント名>/<リポジトリ名>:liberty-base
<missing> 2 days ago /bin/sh 21.5 MB FROM registry.access.redhat.com/ubi8/ubi-micro:latest
c8efdc89ddd2 2 weeks ago 38.7 MB
<missing> 2 weeks ago 1.02 kB Imported from -
cat ./multi/Dockerfile
### 標準出力↓
FROM <アカウント名>/<リポジトリ名>:liberty-base as builder
ADD ibm-semeru-open-jre_x64_linux_11.0.13_8_openj9-0.29.0.tar.gz /opt
ADD spring-liberty.tar.gz /opt
WORKDIR /opt
RUN mkdir -p /opt/wlp/output/defaultServer \
&& chmod -R g+rw /opt \
&& chmod +x /opt/wlp/bin/server \
&& mkdir /logs \
&& chmod -R g+rw /logs
FROM <アカウント名>/<リポジトリ名>:liberty-base
ENV PATH=/opt/wlp/bin:/opt/jdk-11.0.13+8-jre/bin:$PATH \
LOG_DIR=/logs \
WLP_OUTPUT_DIR=/opt/wlp/output
COPY --from=builder /opt/wlp /opt/wlp
COPY --from=builder /opt/jdk-11.0.13+8-jre /opt/jdk-11.0.13+8-jre
COPY --from=builder /logs /logs
RUN ln -s /opt/wlp/output/defaultServer /output \
&& ln -s /opt/wlp/usr/servers/defaultServer /config
EXPOSE 9080
CMD ["/opt/wlp/bin/server", "run", "defaultServer"]
podman history localhost/spring-liberty-multi
### 標準出力↓
ID CREATED CREATED BY SIZE COMMENT
aaf23c9e895b 6 minutes ago /bin/sh -c #(nop) CMD ["/opt/wlp/bin/serve... 0 B
<missing> 6 minutes ago /bin/sh -c #(nop) EXPOSE 9080 0 B
<missing> 6 minutes ago /bin/sh -c ln -s /opt/wlp/output/defaultSe... 4.61 kB
bb5cd35f2328 6 minutes ago /bin/sh -c #(nop) COPY dir:5f70bf18a086007... 1.54 kB
d5f7639bf283 7 minutes ago /bin/sh -c #(nop) COPY dir:7c77887630b5c9a... 128 MB
0e3bf830c855 7 minutes ago /bin/sh -c #(nop) COPY dir:d919f6f91df129a... 49.6 MB
4767b35696bf 9 minutes ago /bin/sh -c #(nop) ENV PATH=/opt/wlp/bin:/o... 0 B FROM docker.io/<アカウント名>/<リポジトリ名>:liberty-base
<missing> 2 days ago /bin/sh 21.5 MB FROM registry.access.redhat.com/ubi8/ubi-micro:latest
c8efdc89ddd2 2 weeks ago 38.7 MB
<missing> 2 weeks ago 1.02 kB Imported from -