3
0

More than 5 years have passed since last update.

Init Containerを使ってLibertyにEar等を配置する

Last updated at Posted at 2018-10-14

はじめに

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}のように環境変数から値を読み込むことができるが、環境変数を読み込めない設定ファイルがある場合はenvsubstsedを使ってテンプレートから設定ファイルを生成する必要がある。今回はそのような想定のファイルとしてsample.properties.tmplをイメージの中に入れる。

Dockerファイルは以下。

Dockerfile
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
$

テンプレートファイルは以下。

sample.properties.tmpl
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を作成する。

liberty.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!$

参考リンク

3
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
3
0