LoginSignup
0
0

More than 1 year has passed since last update.

UBIマイクロからのOpen Libertyコンテナイメージの作成

Posted at

はじめに

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』です。

build.gradle
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」が作成されます。

VSCodeターミナル
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ランタイムのサイズがかなり小さくなっていることが分かります。
image.png

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を追加したコンテナイメージの作成は次章で行います。

classicノード
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でコンテナイメージをビルドします。結果としてイメージストリームが作成されます。
コンテナイメージサイズを小さくするために、マルチステージ・ビルドとしています。

classicノード
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
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"]

3.2. コンテナのデプロイ

Deployment「spring-liberty」としてコンテナをデプロイします。

classicノード
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
spring-liberty.yaml
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」でした。

classicノード
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マイクロを元にした場合
image.png
■ 参考情報
image.png`
■ Open Libertyを元にした場合
image.png

classicノード
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とヒストリーは以下の通りです。

ubi-microベース(シングル)
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 -
ubi-microベース(マルチ)
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 -
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0