はじめに
WebSphere LibertyのDockerイメージは、基本的には以下のようにビルド時にEarとserver.xmlなど必要なファイルを入れ込んで使用する。
FROM websphere-liberty:18.0.0.4-webProfile8
COPY --chown=1001:0 server.xml /config/
COPY --chown=1001:0 myApp.war /config/dropins/
上記のようにイメージの中にEar等を組み込まず、以下のリンク先のようにInit Containerを使ってEar等を配置する方法を試したメモ。
Java Web Application with Tomcat and Init Container
オフライン環境で、アプリリリースのたびにファイルサイズの大きいLibertyイメージ全体を本番環境に持って行くことに制約がある環境では使える方法かもしれない。
LibertyのDockerイメージの確認
DockerHubのLibertyイメージのページにDockerfileへのリンクがあるのでLibertyイメージの特徴を確認する。websphere-liberty:18.0.0.4-kernelのDockerfileでは以下のように記述されている。
(省略)
ENV LOG_DIR=/logs \
WLP_OUTPUT_DIR=/opt/ibm/wlp/output
(省略)
RUN mkdir /logs \
(省略)
&& ln -s $WLP_OUTPUT_DIR/defaultServer /output \
&& ln -s /opt/ibm/wlp/usr/servers/defaultServer /config \
&& ln -s /opt/ibm /liberty \
(省略)
つまり以下のようになっている。
-
/config
がサーバー構成ディレクトリー${server.config.dir}
であり、/opt/ibm/wlp/usr/servers/defaultServer
へのシンボリックリンク -
/output
がサーバー出力ディレクトリー${server.output.dir}
であり、/opt/ibm/wlp/output/defaultServer
へのシンボリックリンク -
/logs
がログディレクトリー
Libertyイメージの中に/config
ディレクトリーは存在していてデフォルトのserver.xml
などが置いてあるが、enptyDir
として作成したVolumeにInit Containerで必要なファイルを配置し、LibertyコンテナではこのVolumeを/config
に上書きマウントすることにする。
Init Containerイメージの準備
Init Containerとして使うイメージを作成する。
Init ContainerにはLibertyが使う/config
ディレクトリーをそのままの構造でイメージに入れておく。また、アプリケーションが使う設定ファイル等を格納したディレクトリーが別にある想定で、今回は/appconfig
もイメージに入れておく。Init Containerの起動時にやりたい処理をスクリプト化してイメージの中に入れておいてもよいが、今回は起動時に実行するコマンドはマニフェストに書くことにする。
なお、server.xml
については${env.hogehoge}
のように環境変数から値を読み込むことができるが、環境変数を読み込めない設定ファイルがある場合はenvsubst
かsed
を使ってテンプレートから設定ファイルを生成する必要がある。今回はそのような想定のファイルとしてsample.properties.tmpl
をイメージの中に入れる。
Dockerファイルは以下。
FROM alpine:3.8
# envsubstをインストールする
RUN apk --no-cache add gettext
COPY config/ /config/
COPY appconfig/ /appconfig/
ビルドを実行するディレクトリーの構造は以下。
$ tree
.
├── Dockerfile
├── appconfig
│ └── sample.properties.tmpl
└── config
├── apps
│ └── sample.war
├── jvm.options
├── server.env
└── server.xml
3 directories, 6 files
$
テンプレートファイルは以下。
message=${MY_MESSAGE}
イメージをビルドしてレジストリにpushする。
docker build -t sotoiwa540/liberty-init:1.0 .
docker login
docker push sotoiwa540/liberty-init:1.0
イメージの中に意図したとおりにファイルが入っているか確認。
$ docker run --rm -it sotoiwa540/liberty-init:1.0 ls -lR /appconfig /config
/appconfig:
total 4
-rw-r--r-- 1 root root 21 Dec 28 16:32 sample.properties.tmpl
/config:
total 12
drwxr-xr-x 2 root root 24 Dec 28 16:34 apps
-rw-r--r-- 3 root root 127 Dec 28 15:20 jvm.options
-rw-r--r-- 3 root root 18 Dec 28 15:20 server.env
-rw-r--r-- 3 root root 433 Dec 28 15:20 server.xml
/config/apps:
total 4
-rw-r--r-- 3 root root 2071 Dec 28 15:20 sample.war
$
Liberty本体のイメージの準備
今回はLiberty本体は公式のイメージをそのまま使う。なお、Init Containerでフィーチャーを導入することはできないので、もし公式イメージにないフィーチャーが必要な場合は、フィーチャーを追加したイメージをビルドしておいて、そちらを使う必要がある。
Kubernetesへのデプロイ
Deploymentのyamlを作成する。
apiVersion: apps/v1
kind: Deployment
metadata:
name: liberty
spec:
selector:
matchLabels:
app: liberty
replicas: 1
template:
metadata:
labels:
app: liberty
spec:
initContainers:
- image: sotoiwa540/liberty-init:1.0
name: liberty-init
imagePullPolicy: Always
command:
- sh
- -c
- |
cp -rp /config/* /mnt/config/
envsubst < /appconfig/sample.properties.tmpl > /mnt/appconfig/sample.properties
chown -R 1001:0 /mnt/config
chown -R 1001:0 /mnt/appconfig
volumeMounts:
- mountPath: /mnt/config
name: config-volume
- mountPath: /mnt/appconfig
name: appconfig-volume
env:
- name: MY_MESSAGE
value: "Hello World!"
containers:
- name: liberty
image: websphere-liberty:18.0.0.4-webProfile8
imagePullPolicy: Always
ports:
- containerPort: 9080
volumeMounts:
- mountPath: /config
name: config-volume
- mountPath: /appconfig
name: appconfig-volume
volumes:
- name: config-volume
emptyDir: {}
- name: appconfig-volume
emptyDir: {}
- Init ContainerではemptyDir Volumeを
/mnt/config
にマウントし、Libertyコンテナでは同じemptyDir Volumeを/config
にマウントするようにしている - Init Containerで実行したい処理はの内容はマニフェストに直接書いているが、イメージ内にスクリプトを入れておいてそのスクリプトを実行してもよい
-
envsubst
で環境変数から設定ファイルを生成するのはInit Containerの処理なので、環境変数はInit Containerの側に設定している - Init Containerは
root
で起動するがLibertyコンテナはdefault
ユーザーで起動するのでコピーしたあと権限を変えている
デプロイを実行。
kubectl apply -f liberty.yaml
ログを確認。アプリケーションが起動していることが確認できる。
$ kubectl logs liberty-6c656978d8-l8h6m
Launching defaultServer (WebSphere Application Server 18.0.0.4/wlp-1.0.23.cl180420181121-0300) on IBM J9 VM, version 8.0.5.26 - pxa6480sr5fp26-20181115_03(SR5 FP26) (en_US)
[AUDIT ] CWWKE0001I: The server defaultServer has been launched.
[AUDIT ] CWWKE0100I: This product is licensed for development, and limited production use. The full license terms can be viewed here: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/license/base_ilan/ilan/18.0.0.4/lafiles/en.html
[AUDIT ] CWWKG0093A: Processing configuration drop-ins resource: /opt/ibm/wlp/usr/servers/defaultServer/configDropins/defaults/keystore.xml
[AUDIT ] CWWKZ0058I: Monitoring dropins for applications.
[AUDIT ] CWWKS4104A: LTPA keys created in 1.754 seconds. LTPA key file: /opt/ibm/wlp/output/defaultServer/resources/security/ltpa.keys
[AUDIT ] CWPKI0803A: SSL certificate created in 2.472 seconds. SSL key file: /opt/ibm/wlp/output/defaultServer/resources/security/key.jks
[AUDIT ] CWWKT0016I: Web application available (default_host): http://liberty-6c656978d8-l8h6m:9080/sample/
[AUDIT ] CWWKZ0001I: Application sample started in 0.804 seconds.
[AUDIT ] CWWKF0012I: The server installed the following features: [localConnector-1.0].
[AUDIT ] CWWKF0011I: The server defaultServer is ready to run a smarter planet.
$
なお、/config
はシンボリックリンクであり、そこにマウントをしているが、ちゃんとシンボリックリンク先にファイルが配置される挙動となっていた。
$ kubectl exec -it liberty-6c656978d8-l8h6m -- ls -l /config /appconfig /opt/ibm/wlp/usr/servers/defaultServer /opt/ibm/wlp/usr/servers/defaultServer/apps
lrwxrwxrwx. 1 default root 38 Dec 18 00:35 /config -> /opt/ibm/wlp/usr/servers/defaultServer
/appconfig:
total 4
-rw-r--r--. 1 default root 20 Dec 28 16:46 sample.properties
/opt/ibm/wlp/usr/servers/defaultServer:
total 12
drwxr-xr-x. 3 default root 40 Dec 28 16:47 apps
drwxr-xr-x. 3 default root 22 Dec 28 16:46 configDropins
drwxr-x---. 2 default root 6 Dec 28 16:47 dropins
-rw-r--r--. 1 default root 127 Dec 28 15:20 jvm.options
-rw-r--r--. 1 default root 18 Dec 28 15:20 server.env
-rw-r--r--. 1 default root 433 Dec 28 15:20 server.xml
/opt/ibm/wlp/usr/servers/defaultServer/apps:
total 4
drwxr-x---. 3 default root 24 Dec 28 16:47 expanded
-rw-r--r--. 1 default root 2071 Dec 28 15:20 sample.war
$
テンプレートからのファイル生成も行われていることが確認できる。
$ kubectl exec -it liberty-6c656978d8-l8h6m -- cat /appconfig/sample.properties
message=Hello World!$