OpenShift 全部俺 Advent Calendar 2017
OpenShiftやKubernetesではConfigMapを使ってファイルを差し替えることができます。今日はJBoss EAPのstandalone-openshift.xmlをConfigMapでカスタマイズしたいなー、と思ってやってみたらストレートに行かなかった話です。
$ oc new-project test-javaee $ oc policy add-role-to-user view -z default $ oc new-app eap70-basic-s2i -p APPLICATION_NAME=hello-javaee -p SOURCE_REPOSITORY_URL=https://github.com/nekop/hello-javaee -p SOURCE_REPOSITORY_REF= -p CONTEXT_DIR= -p MAVEN_MIRROR_URL=http://nexus.example.com:8081/nexus/content/groups/mirror/
JBoss EAPのコンテナイメージは/opt/eap/standalone/configuration/standalone-openshift.xml
を利用するようになっているので、まずはファイルの内容はまったく変更しないで、standalone-openshift.xmlをConfigMapに移してConfigMapのsubPath指定でvolume mountして差し替えます。
$ oc create configmap eap-config --from-file=./standalone-openshift.xml $ oc volumes dc/hello-javaee --add --name=eap-config --configmap-name=eap-config --default-mode=0777 --mount-path=/opt/eap/standalone/configuration/standalone-openshift.xml --sub-path=standalone-openshift.xml
すると、CrashLoopしました。なんでやねん。
$ oc get pod NAME READY STATUS RESTARTS AGE hello-javaee-1-build 0/1 Completed 0 1m hello-javaee-2-deploy 1/1 Running 0 33s hello-javaee-2-p9bcj 0/1 CrashLoopBackOff 1 31s
ログを見るとsedがDevice or resource busy
で失敗しているログがずらずら出ており、JBoss EAPは設定ファイルが不正で起動できません、という状態になっています。
$ oc logs -p hello-javaee-2-p9bcj sed: cannot rename /opt/eap/standalone/configuration/sedezxomS: Device or resource busy sed: cannot rename /opt/eap/standalone/configuration/sedjGz72R: Device or resource busy sed: cannot rename /opt/eap/standalone/configuration/sedCDOG5Q: Device or resource busy sed: cannot rename /opt/eap/standalone/configuration/sedBrYC5Q: Device or resource busy sed: cannot rename /opt/eap/standalone/configuration/sedwG75aV: Device or resource busy (省略) 07:03:43,188 ERROR [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0055: Caught exception during boot: org.jboss.as.controller.persistence.ConfigurationPersistenceException: WFLYCTL0085: Failed to parse configuration at org.jboss.as.controller.persistence.XmlConfigurationPersister.load(XmlConfigurationPersister.java:131) [wildfly-controller-2.1.18.Final-redhat-1.jar:2.1.18.Final-redhat-1] at org.jboss.as.server.ServerService.boot(ServerService.java:362) [wildfly-server-2.1.18.Final-redhat-1.jar:2.1.18.Final-redhat-1] at org.jboss.as.controller.AbstractControllerService$1.run(AbstractControllerService.java:301) [wildfly-controller-2.1.18.Final-redhat-1.jar:2.1.18.Final-redhat-1] at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151] Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[131,9] Message: WFLYCTL0133: Missing required attribute(s): default-job-repository
設定ファイルの内容を変更していないのになぜこのようなエラーになるのでしょうか。
JBoss EAPのコンテナイメージは起動スクリプトで環境変数の内容からさまざまな設定をstandalone-openshift.xmlにsedコマンドで適用します。ログではsedコマンドがDevice or resource busy
で失敗していたので、もうわかりますね。ConfigMapによるファイルの差し替えを行ったので、このファイルはマウントポイントになっています。それをsedで「置き換え」しようとしているのですが、マウントポイントであるため置き換えができず、Device or resource busy
というエラーとなっています。結局書き換えられるはずの設定ファイルが書き換えられないまま不完全な状態で起動シーケンスに入ってクラッシュしていたのでした。ちなみにファイルを置き換えるのではなく、編集するのであれば成功します。あとoc debug
で起動するとマウントポイントでもファイルの置き換えが可能になる挙動を確認しましたが、今回は深追いしません。
コンテナイメージ作成者は設定ファイルのテンプレートは実際の設定ファイルではなく、別のファイルにしましょう。そうすればテンプレートと出力先ファイルが同一なので置き換えられない、という今回の問題は回避できます。また、記事では触れませんでしたがオリジナルのstandalone-openshift.xmlを取り出すにも一工夫必要となります。というのも、起動したコンテナから取り出すと既に起動スクリプトが設定変更を適用した後のファイルとなってしまうため、oc debugで起動したコンテナから取得しないといけなかったり面倒でした。
というわけで、設定テンプレート元ファイルと実際の設定ファイル、同一のロケーションにするのはやめましょう、というお話でした。
JBoss EAPについてはチケットを作成しましたが、以前のバージョンとの互換性とかも気にしないといけないのですぐには解決できないんじゃないかなー、という雰囲気です。チケットに書いた通り、/opt/eap/standalone/configuration/
ディレクトリをまるっとConfigMap化すると大丈夫です。