概要
1台のWindowsマシンで、Dockerで立ち上げたJenkinsマスターと、ホストのWindowsネイティブで動くJenkinsスレーブを共用できたので、備忘録として残します。
モチベーション
- 会社の組み込みソフト用のCI環境立ち上げが目的
- 手元にあるのがWindows10マシン1台なので、まずはこれで全て賄いたい
構成
何でそんな構成にしたの?
主な理由は以下の通りです。
- Jenkins立ち上げの属人化を防ぐ一環で、DockerでJenkinsサーバーを立ち上げたかった
- CI対象のビルド用ライセンスがWindows限定だった
- JenkinsのDockerはLinuxコンテナ限定なのでWindowsのコマンドが動かせず、ビルドできなかった: 参考文献
主に2、3のせいで若干複雑な構成になった感じです。
単に目的達成だけなら、JenkinsマスターをWindowsインストーラでセットアップすれば良かったんですが。
仮にサーバーマシンを入れ替えたりすることになっても、手順書をゴリゴリ書くよりはコマンド一発でセットアップできるほうが楽かなと。
(あと単純にDockerを使ってみたかったという理由もあります)
環境
- Windows10 Home Version 20H2 (Build 19042.685)
- Docker Desktop Version 3.1.0 (51484)
- WSL2
- Jenkins Version 2.263.2
- WMI Windows Agent Version 1.7
リポジトリ
今回のDocker構成は Github に置いています。
Jenkinsマスター
Dockerfile
コンテナ内のファイルを編集するときに備えて、(宗教上の理由から)Vimだけインストールしています。
本当はここにWMI Windows Slaveプラグインのインストールを書くべきなのでしょうが、今回は省略しました。
FROM jenkins/jenkins:2.263.2-lts-slim
USER root
RUN apt-get update -y
RUN apt-get install -y vim
USER jenkins
docker-compose.yml
ポートフォワーディングの設定を管理したり、将来的にnginxも使ったりするかもなので、今はJenkinsマスター単体ですがdocker-composeから起動するように準備してます。
データの永続化はVolumeで。
個人的に後から分かりやすいようにjenkins_
って付けてるんですが、Volume名なんかがjenkins_jenkins_master_data
とかになっちゃう。フォルダ名が付与されちゃうのかな・・・?
version: "3"
services:
jenkins_master:
container_name: master
build:
context: .
dockerfile: ./jenkins/Dockerfile
environment:
JENKINS_OPTS: '--prefix=/jenkins'
ports:
- 80:8080
- 50000:50000
volumes:
- jenkins_master_data:/var/jenkins_home
volumes:
jenkins_master_data:
Dockerコンテナ起動
普通に docker-compose up -d
で起動します。
Jenkins起動まで
Unlockして、Suggested pluginをインストールして、Adminユーザーを作る。
今回は詳細は省略します。
Jenkins初期設定
Jenkinsの管理
-> プラグインの管理
から WMI Windows Agent プラグインをインストールします。
Slaveノードの追加
Jenkinsの管理
-> ノードの管理
-> 新規ノード作成
から追加します。
最初のページは以下の通り設定。
- ノード名: windows-slave (今回の例。スレーブに合わせて適切に)
- Permanent Agent にチェック
次のページは以下の通り設定。
- リモートFSルート:
C:/tmp
- 起動方法:
Launch agent by connecting it to the master
これでノードの追加は完了です。
この時点では「×」のアイコン付きで表示されます。
スレーブのノードをクリックするとJNLPで接続する手順が表示されます。
今回はLaunchボタンでなく、Run from agent command line
の手順で接続しました。
ちゃんと接続できると「×」のアイコンが消えます。
ジョブ設定
新規ジョブ作成
からテスト用のジョブを作成します。
- ジョブ名: SlaveJob1(今回の例。ジョブに合わせて適切に)
- フリースタイル・プロジェクトのビルドを選択
General の設定
-
実行するノードを制限
- ラベル式: windows-slave
ビルド の設定
-
ビルド手順の追加
->Windowsバッチコマンドの実行
- コマンド:
..\..\build.bat
- あとでスレーブに作るビルド用のバッチファイル名と合わせます
- 実行ディレクトリは
[リモートFSルート]/workspace/[JOB名]
となるようなので、2つ上の階層を指定しています
Jenkinsスレーブ
リモートFSルートであるC:\tmp
を作成します。
その中に先ほど指定したbuild.bat
を作成します。
今回はテスト用に中身は単純なechoとしますが、ここにビルド用のコマンドを記述します。
@echo off
echo "Slave build job"
ビルド実行
再度メニューからビルド実行
で手動ビルドします。
するとビルド履歴に#XX
と履歴が表示されるので、そこからコンソール出力
を見ると以下のように表示されるはずです。
Started by user USER_NAME
Running as SYSTEM
Building remotely on windows-slave in workspace C:/tmp/workspace/SlaveJob1
[SlaveJob1] $ cmd /c call C:\Users\USER\AppData\Local\Temp\jenkins12877575992189775420.bat
C:\tmp\workspace\SlaveJob1>..\..\build.bat
"Slave build job"
C:\tmp\workspace\SlaveJob1>exit 0
Finished: SUCCESS
終わりに
若干複雑な構成になっちゃいましたが、1台のWindows10マシンでDockerのJenkinsマスターとホストネイティブのJenkinsスレーブを共用することができました。
ただ、実は2021/01/24現在、この記事の構成に成功したのは自宅のWindows10マシンで、会社のマシンではスレーブの接続あたりが上手く動いてません。
WSL2バックエンドでないとダメとかあったら嫌だなぁ・・・(会社マシンはWindowsビルドバージョンのせいでWSL2が入れられない)