Dockerのjenkins:2.60.3-alpineを利用しているが、Dockerのイメージが1年ほど更新されていない状況。
そのためJenkinsのUI(ブラウザーから開いた管理画面)からアップデートをかけたところ、思わぬところで躓いたため、対応を残しておく。
https://hub.docker.com/r/library/jenkins/tags/
(注意)以降に記載した対応が公式のJenkins Dockerイメージとして推奨/サポートする対応かどうかは未確認である。Docker Hubに公開されている文書上からはブラウザー上からのアップデート操作を想定していない可能性も考えられる。
##前提
- Docker 17.05.0-ce
- docker-compose 1.8.0
- jenkins:2.60.3-alpine
- 自分のDocker環境で(当初)永続化していたディレクトリーは以下
/var/jenkins_home/
現象
- ブラウザーからUI上でJenkinsのアップデートをかけバージョンアップした
- 普段のバックアップはdocker stopコマンドで停止した状態で実行しており、アップグレード後にdocker-compose downは未実行
- ある日、別件のメンテナンスでdocker-compose downして作業を行いdocker-compose up --build -dを実行したところjenkinsにログインできない状況となった
- エラー「XmlPullParserException」が発生
1次調査
- エラー・ログの出力は以下
org.xmlpull.v1.XmlPullParserException: only 1.0 is supported as <?xml version not '1.1' (position: START_DOCUMENT seen <?xml version='1.1'... @1:1
-
エラーが表示されたファイルのxmlのバージョンを1.0に修正し再起動すると該当するエラー・メッセージは消えるが、別のファイル(中身はxml 1.1)のエラーが表示された
-
xml v1.1となっているファイルを検索するとアップグレード作業を行った日のタイムスタンプとなっている
-
v2.105からjenkinsが生成するファイルが1.1対応になっている
-
まともに起動しない状態をとりあえず解消するべきxml 1.1の記述を一通り1.0に戻す
- 下記はコマンドの例(へっぽこですが)
$ sudo grep -rnw srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs -n 1 -I{} cp {} {}.bk
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
$ sudo grep -lr srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs sed -i 's/1.1/1.0/'
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
-
docker-compose up --build dを実行し起動
-
ブラウザーからアップデートを実行
-
アップグレードは正常に完了する
-
docker-compose down し、docker-compose up -d (--buildなしでも)を実行するとXmlPullParserExceptionが再発する
原因の推測
- 新しいバージョンのjenkins.warファイルがダウンロードおよび展開されているディレクトリーが永続化されてない可能性が高い
2次調査
- docker-compose down
- xmlファイルを全て1.0に戻す(grepとsedで一括置換)
$ sudo grep -lr srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs sed -i 's/1.1/1.0/'
$
- docker-compose up --build -d
- コンテナに「docker exec -it /bin/bash」でログインしwarのディレクトリーを調査
- 「/usr/share/jenkins/jenkins.war」(warファイルの配置先と推測)
- 「/var/cache/jenkins/war」(warの展開先と推測)
$ docker exec -it jenkins_1 /bin/bash
bash-4.3# find / -name *war* -type d
/var/cache/jenkins/war
/var/cache/jenkins/war/META-INF/maven/org.jenkins-ci.main/jenkins-war
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-781527918347635117.dir
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-2252951103130751390.dir
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-5296010582638823514.dir
/lib/firmware
/sys/bus/acpi/drivers/hardware_error_device
/sys/devices/software
/sys/class/firmware
/sys/firmware
/sys/module/firmware_class
bash-4.3# find / -name *.war -type f
/usr/share/jenkins/jenkins.war
bash-4.3# exit
$
- docker cpコマンドでコンテナ内の該当するディレクトリー(2つ)をDockerホスト上に取得する
$ mkdir -p .srv/jenkins/var/cache
$ mkdir -p .srv/jenkins/var/cache/jenkins/
$ docker cp jenkins_1:/var/cache/jenkins/war ./srv/jenkins/var/cache/jenkins/
$ docker cp jenkins_1:/usr/share/jenkins ./srv/jenkins/usr/share/
- docker-compose.ymlを編集しjenkinsのコンテナの永続化ボリュームを2つ追加する
./srv/jenkins/var/cache/jenkins/war:/var/cache/jenkins/war
./srv/jenkins/usr/share/jenkins:/usr/share/jenkins
- docker-compose up --build -dを実行
- ブラウザー上からjenkinsのアップグレードを実行
- docker-compose downを実行
- docker-compose up -dを実行
- jenkinsは正常に起動し、アップグレードしたバージョンが維持されている
まとめ
- DockerのJenkins(公式)イメージはブラウザーのボタンから実行したアップグレードについては想定していない可能性が高い
- 無理やり最新版を利用したい場合には永続化ボリュームの見直しが必要になる