Jenkinsを引き継いだ時に気をつけたいポイント


# はじめに

「じゃあ、○○さんが運用していたJenkinsの引き継ぎをお願いしますね」

そんな事を言われてしまった貴方へ。

# 筆者の作業環境

なるべく環境に依存しない内容を心がけますが、
ところどころ出てくるスクリプトは Linux 環境を想定しています。

# 前提知識

Jenkinsの運用は、いわばJVMで動くWebアプリケーションの運用です。
そのため次のような知識があると、問題発生時に役に立つでしょう。

- Webアプリケーションが動く環境の知識
	- Windows, macOS, Linux それぞれで、Webアプリケーションを動かすための知識が必要でしょう
- SSH の知識
	- JenkinsのNodeを増やす際もSSHを使います
- ネットワーク設定の知識
	- Proxy設定の知識
		- Jenkins × Proxy はハマりポイントの宝庫です
			- 宝庫すぎるので本記事では触れません (触れたらきりがありません)
	- JenkinsマシンのIPを固定する方法
		- あるいはDNSにホスト名を登録することもあるかもしれません
	- VM間でのみ接続できるネットワークに設定する方法
		- 構築環境によっては必要になるかもしれません
		- 例えば VirtualBox上に構築している場合は、VirtualBoxのネットワーク設定の知識が必要でしょう
- 監視の知識
	- Jenkinsのプラグインで監視系のものもありますが、すでに監視のノウハウがあるなら、Jenkinsにも適用したいところです
	- もっとも規模によっては、落ちていると気付いたら直す、というレベルで良いかもしれません

# 環境変数の設定箇所を確認しよう

Jenkinsのジョブビルド時に参照できる環境変数ですが、あらゆるところで設定が可能です。
思いつく限りリストアップしておきますので、どこで定義されているか確認しておきましょう。

- Jenkins本体の設定画面
  ![image-env-001.png](https://qiita-image-store.s3.amazonaws.com/0/27201/cf78d039-54b7-0f6f-af72-8ae386b6bbb3.png "image-env-001.png")
- Jenkins Nodeの設定画面
  ![image-env-002.png](https://qiita-image-store.s3.amazonaws.com/0/27201/a8a14278-7915-38cf-5eb1-8c5cc7ce5d9c.png "image-env-002.png")
- Jenkins Node の コマンド起動部分
  ![image-env-003.png](https://qiita-image-store.s3.amazonaws.com/0/27201/29907489-5f10-470b-ed62-032939eda7a8.png "image-env-003.png")
- ジョブのパラメータ化
  ![image-env-004.png](https://qiita-image-store.s3.amazonaws.com/0/27201/e0705597-b342-2888-e7ae-d25344e2cfba.png "image-env-004.png")
- EnvInject Plugin
	- Jenkins本体の設定
	- Nodeの設定
	- ジョブの設定
- Parameterized Trigger Plugin で 子ジョブにパラメータを上書き
- Mask Passwords Plugin
- ビルドマシンの環境変数
- ビルド時にファイルを `source` して読み込む

探せばまだまだあると思います。

# Credentialsの設定箇所を確認しよう

特に `git clone` する際に使用するCredentials情報は、色々な場所で設定できます。

- Jenkins本体の Credentials
- Folders プラグインで階層化された先の Credentials
- Jenkinsの環境変数
- マシン上の ~/.ssh/ 以下など

# 検証用のJenkinsをローカルに立てておこう

Jenkinsのメンテナンスや設定変更を試すために、自分の環境にJenkinsを立てておきましょう。
可能なら、本番用のJenkinsから設定やインストール済みのプラグインをコピーして、手元で再現できるようにしたが検証用としては確実です。

検証用Jenkinsの設定をコピーする方法のおすすめは `git` を使う方法です。

例えば次のような手順です。

```bash
# 本番用のJenkinsで作業

# JENKINS_HOME は OS によって違うので確認してください
$ cd $JENKINS_HOME
$ git init

# gitignoreで設定とプラグイン以外は除外する
# 参考: http://qiita.com/konyavic/items/db8077886ab31edaa3bb
$ vim .gitignore

# Jenkins の設定を git で commit
$ git commit -A "First commit"
```

```bash
# LocalのJenkinsで作業

# JENKINS_HOME は OS によって違うので確認してください
$ cd $JENKINS_HOME

# 本番用Jenkinsのジョブ設定を取得
$ git init
$ git remote add origin ssh://${本番用Jenkinsサーバー}:${本番用JenkinsのJENKINS_HOME}
$ git fetch
```

`rsync` でも良いですが、過去の設定に簡単に戻せるので `git` の方が便利だと思います。

## ローカルJenkinsのジョブ実行には注意しよう

引き継いだJenkinsには、もしかすると商用環境に作用するものが含まれているかもしれません。
同じジョブが2つ同時に動くことを想定していない場合は、問題を起こすかもしれないので注意しましょう。

# :bomb:「Jenkinsが壊れた」と言われたら

~~「壊れたのではなく壊したの間違いでは:smirk:」と言い返しましょう。~~
憤る気持ちを抑えて調査しましょう。

最近では、Jenkinsというアプリケーションが原因で壊れることは、それほど多くありません。
まずは **壊れた** が、どういう状態のことを表現しているのか確認しましょう。

## :bomb: 何度やってもビルドが失敗する

![image001.png](https://qiita-image-store.s3.amazonaws.com/0/27201/bd76ce81-6588-8de5-075c-6d0fb250dcdc.png "image001.png")


まずは失敗し始めたビルドの変化点を探しましょう。
ソースコードはもちろんですが、ビルドが実行されるマシン上の変化も要注意です。
マシン上の問題だとすると、もはや Jenkins は関係なくてインフラの話です。[^1]  
[^1]: Jenkins運用が疲れる大きな要因ですね

経験上、ビルド用の環境が原因でビルドに失敗することが多いです。NTPが機能しておらず時間がずれていたとか、ディスク空き容量が足りないとか、ネットワークの設定に問題があるとか。

## :bomb: いつまで経ってもビルドされない

![image002.png](https://qiita-image-store.s3.amazonaws.com/0/27201/cb71a5db-db17-e75b-b1f9-e7a88f713a98.png "image002.png")

ビルドキューが溜まり続けているパターンです。
ほとんどの場合、ビルドが実行されるNodeが止まっているか、長時間ビルド中のジョブがあるのでしょう。
[GitHub Organization Folder Plugin](https://wiki.jenkins.io/display/JENKINS/GitHub+Organization+Folder+Plugin) を使っている場合、GitHub API の Limit に引っかかっている可能性もあります。
その場合はビルド間隔を延ばすか、GitHub から JenkinsのAPIを叩いてビルドするようにしましょう。[^2]
[^2]: やんごとなき理由で外部からJenkinsのAPIを叩けない場合は、GitHub Organization Folder Plugin を諦めて Polling した方が良いかもしれません

## :bomb: Jenkinsが落ちている

![image003.png](https://qiita-image-store.s3.amazonaws.com/0/27201/832e8e99-de26-bb11-c899-9e591f309519.png "image003.png")

メモリ不足、ディスク容量不足などで Jenkins がダウンすることがあります。
他にも、Jenkinsの設定ファイルが壊れてしまっている時や、Pluginの相性が悪くて立ち上がらなってしまうこともあります。[^3]
[^3]: Pluginが起因してJenkinsがおかしくなることは、最近はかなり減ったような気がします ※個人の感覚です
まずは、落ち着いて情報収集です。エラー画面の文言や、サーバー上のログを確認しましょう。  

また JUC 2014 の発表が参考になるかもしれません。[^4]
参考） https://www.cloudbees.com/event/topic/help-my-jenkins-down
[^4]: 私はここまで困ったことはないので、あくまで参考まで

## :bomb: 思った通りに動かない

つ https://teratail.com/tags/Jenkins

# アカウントの管理方法を知ろう

Jenkinsのアカウント管理は何種類かあります。  

- Jenkins本体にアカウントを作る
- Unixのアカウントと連携する
	- `/etc/shadow` への読み込み権が必要になります
- LDAPと連携する
- Pluginを入れて外部サービスと連携する
	- GitHub OAuth
	- Bitbucket OAuth
	- GitLab OAuth
	- など...

私のおすすめは [GitHub OAuth Plugin](https://wiki.jenkins.io/display/JENKINS/GitHub+OAuth+Plugin) です。[^5]
[^5]: 最近は GitHub Authentication Plugin という名前に変わったっぽい？
理由は単純で GitHub を使って開発しているからです。

逆にJenkins本体でのアカウント管理はおすすめしません。
こちらの理由も単純で、UIがアカウント管理に向いていないからです。特に、アカウントの作成・削除と、権限の設定が全く別のパスとUIなので直感的ではなく、慣れが必要です。

# Jenkinsの最新情報をキャッチアップしよう

Jenkinsの運用自体はWebアプリケーションの運用なので、おおよそ既存のノウハウで何とかなります。
一方で、Jenkinsおじさんがどこからともなく集めているJenkinsの最新情報は、自分から集めなければどうにもなりません。

幸いにも、日本Jenkinsユーザー会が勉強会を開いていますので、そちらに参加するか、発表時のスライドを眺めると良いでしょう。[^6]
[^6]: 最近の大阪の勉強会は、スライドを見ているだけでも楽しくて良いですね
また、最近発売された [Jenkins実践入門の第三版](https://www.amazon.co.jp/dp/4774189286) は、Workflow Plugin や BlueOcean Plugin も言及されており、今風の Jenkins を知るには良い本だと思います。


# 古いJenkinsを捨てる勇気を持とう

Jenkinsの引き継ぎ方によっては想像以上の負担が掛かります。Jenkins本体の設定、環境変数の設定箇所、ジョブの設定、日々の監視など、見なければならない場所が意外と多いのがJenkinsです。
一体、Jenkinsのどこで何が設定されているのか分からず悩んでしまこともあるかもしれません。  

「このジョブだけ使ってるMavenのバージョン違うんだよね...[^7]」
[^7]: 以前、自分で作ったNodeにMasterとは違うMavenをデフォルトバージョンとしたことをすっかり忘れてしまい、困惑したことがあります
「JenkinsでProxyの設定をした記憶がないのに、こいつどこを経由してるんだ...[^8]」  
[^8]: 以前、Nodeの設定で、SSH経由で `slave.jar` を実効するスクリプトに `souce ~/.bashrc` としていたことを忘れてしまい、困惑したことがあります

もし、受け継いだJenkinsがゴリゴリマッチョにカスタムされていた場合、それを運用し続けるのは辛いことでしょう。
例えばビルド時間を短縮させるために Matrix Project を使ったり、パイプラインの途中から実行できるようとパラメータが複雑になったジョブがあったり、自分のやりたい事を実現するためのGroovyスクリプトがジョブにベタ書きされていたり...。
特に、バージョンが1.X系の頃のJenkinsで[^9]、CI/CD をがっつり仕組みを作ろうと思ったら、初めから最後までやる大きなジョブを用途ごとに作るか、汎用的で小さなジョブを組み合わせて、パイプラインのように処理を進めることが多かったと思います。  
[^9]: ちょうど、TravisCIやCircleCIの情報が出始めた頃でしょうか

記事のタイトルを裏切るかもしれませんが、Jenkinsの運用が辛ければそのJenkinsは捨てましょう。
CircleCIやTravisCIに移行できれば、マシンを運用する苦しみからは解放されます。[^10]
[^10]: たとえVirtualBoxであっても、マシンを１つ運用するというコストはバカにできないものです
逆に、Jenkinsを使い続けるのであれば、Jenkins 2.x系に移行し、[Jenkinsfile](https://jenkins.io/doc/book/pipeline/jenkinsfile/)とDockerを活用しましょう。
この2つを使えば、ジョブの設定管理を外出しでき、Nodeの管理もDockerで完結できるため、Jenkinsの運用はぐっと軽くなるはずです。[^11]
[^11]: 時間があれば、Jenkinsfile + Docker の運用についてまとめたいと思います

# 最後に

できれば、そもそもJenkinsおじさんが居なくても運用できる環境にしておくことが望ましいのですが...限られたリソースの中でやりきるのは難しいですね... :sweat: 

なお、本記事は編集リクエスト大歓迎です :smile: 
誤字脱字などありましたら、ぜひ編集リクエスト頂けると幸いです。