くりにっき

フルスタックキュアエンジニアです

Jenkinsを安全にアップデートする方法

手持ちのJenkinsをいくつかアップデートすることがあったので備忘がてらまとめておきます。*1

Jenkins 1系 -> 2系などの大幅アップデートに限らず、プラグインのアップデートでも使えると思います。

事前にやるべきこと

アップデート後に何か問題があって戻さざるを得ないこともありうるので、すぐに元に戻せる状態にしておきます。*2

Jenkins本体のバックアップ

jenkins.warをそのまま使ってる場合

jenkins.warをどこかにバックアップするか、アップデート前のバージョンをどこかにメモっておいてください。

jenkins.warの過去バージョンは http://mirrors.jenkins-ci.org/war/ からダウンロードできます。

yumやaptを使ってる場合

yum installapt-get install では最新版しかインストールされないので、ロールバックも考慮するとパッケージ指定でインストールした方がいいと思います。

rpmdebはこちらからダウンロードできます

ちなみにパッケージからインストールしておくとjenkinsユーザ作ってくれたりデーモン化までやってくれるのでおすすめです

自分の場合こういうitamaeレシピ書いてます(Debian版)

jenkins.rb

execute "wget http://pkg.jenkins-ci.org/debian/binary/jenkins_#{node[:jenkins][:version]}_all.deb -P #{node[:jenkins][:deb_dir]} && dpkg -i #{node[:jenkins][:deb_dir]}/jenkins_#{node[:jenkins][:version]}_all.deb" do
  not_if "ls #{node[:jenkins][:deb_dir]}/jenkins_#{node[:jenkins][:version]}_all.deb"
end

node.yml

jenkins:
  version: "2.8"
  deb_dir: "/data/backup/jenkins_deb"

コマンドに書き下すとこんな感じ

cd /path/to/backup_dir
wget http://pkg.jenkins-ci.org/debian/binary/jenkins_2.8_all.deb
dpkg -i jenkins_2.8_all.deb

この場合でも戻す場合は過去バージョンのrpmdebでインストールしなおすだけです

最初ymlでバージョン変えてitamae実行したのですが、 /etc/default/jenkinsJENKINS_HOMEJVMのメモリ割り当てで編集してた関係で差分適用するかどうかの入力待ち*3でずっと止まってたので、もしかしたら手動の方がいいかもしれないです。

プラグインや設定一式のバックアップ

手前味噌ですが jenkins-backup-script を使うのがいいです。設定ファイルやプラグイン一式全部バックアップされます。

sue445.hatenablog.com

こういう風にジョブ登録しておいて1日1回夜中に定期実行したり、Jenkins本体やプラグインのアップデート前に手動実行したりしています。

f:id:sue445:20160612141547p:plain

一応tarは外部のバックアップサーバにも転送してるので、突然Jenkinsマシンが死んでもすぐに復旧できる状態にはなってます

Jenkins本体はそうでもないのですが、プラグインは稀に下位互換性をぶっ壊すような変更が入るのでバックアップは必須かと *4

アップデート手順

warなりdebなりrpmなり最新版でインストールし直すだけ。

確認方法

主要なジョブをいくつか手動実行してみる

戻す方法

  • jenkins.warを使ってる場合は過去バージョンのを置き直すだけ
  • rpmdeb使ってる場合は過去バージョンでインストールしなおすだけ
  • jenkins-backup-scriptは下記のようなコマンドで設定ファイルを上書きするだけ
cd /path/to/backup_dir
tar xzvf backup.tar.gz
sudo cp -R jenkins-backup/* /path/to/jenkins/
sudo chown jenkins:jenkins -R /path/to/jenkins/

アップデート時にハマったこと

Branches to build で変数が取れなくなった

jenkins-gitlab-merge-request-builder-plugin を使ってた時にビルド対象のブランチ名がとれなくなったハマりました

設定

f:id:sue445:20160612195822p:plain

正常な時のログ

20:11:03  > git rev-parse refs/remotes/origin/feature/remove_alias_method_chain^{commit} # timeout=10
20:11:03  > git rev-parse refs/remotes/origin/refs/remotes/origin/feature/remove_alias_method_chain^{commit} # timeout=10
20:11:03 Checking out Revision 4e9593d92e293c5ca99eaa6de3b92b973cb1716a (refs/remotes/origin/feature/remove_alias_method_chain)
20:11:03  > git config core.sparsecheckout # timeout=10
20:11:03  > git checkout -f 4e9593d92e293c5ca99eaa6de3b92b973cb1716a

エラー時のログ

19:09:00 Gitlab Merge Request #9222 : xxxx/my_xxxx/feature/update_ruby => master
19:09:01  > git rev-parse refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10
19:09:01  > git rev-parse refs/remotes/origin/refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10
19:09:01  > git rev-parse refs/remotes/origin/${gitlabSourceBranch}^{commit} # timeout=10
19:09:01 ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.

GitLabのwebhookからJenkinsにブランチ名は渡されてるっぽいのだけど、 git rev-parse する時にはブランチ名がとれなくなってるような挙動。

「明示的に設定したパラメータしか変数としてバインドされなくなったのかなー」と思って「ビルドのパラメータ化」のところに gitlabSourceBranch を定義したらビルドが動くようになりました。*5

f:id:sue445:20160612200104p:plain

所感

  • 1系 -> 2系のアップデートで身構えてたけど、アップデート自体は驚くほどサクッとできました
  • パイプラインやJob DSLに全部置き換えるとかだと大変そうだけど、既存のジョブをそのまま移行する分には問題なさそうです
  • とはいえ保険が多いにこしたことはないのでバックアップはしておいた方がいいです

まとめ

  • 何かあった時のロールバック手順は必ず用意しておく(石橋を叩いて渡るくらいが丁度いい)
  • Jenkins 2系はいいぞ

ブコメレス

id:C_L

JenkinsCIををrpmでアップデートすると、$JENKINS_HOMEをchown -Rする糞コマンド入っているので、workspace/以下を綺麗にしておくかexport JENKINS_INSTALL_SKIP_CHOWN=trueしておかないと何時間もupdate終わらんとかになる

ナルホディウス。debだと時間かかっていなかったのでプラットフォームごとに違うのですね。(自分のところのJENKINS_HOME配下もファイル数カオスなので一瞬でchown -Rが終わるとも思えない)

*1:Jenkins 3つ管理してて、それぞれ1.6系から2.8へのアップデート

*2:過去にアップデートしたらダッシュボードが全部吹っ飛んで、バックアップもなかったので脳内ソースを頼りに半日がかりで復旧したことがあります(;´Д`)

*3:上書きしますか?(y/n)的なやつ

*4:http://sue445.hatenablog.com/entry/2016/01/20/232500

*5:リリースノートちゃんと追ってないのでどこで変更あったかは不明