こんにちは!日々のCI/CDパイプラインの管理、お疲れ様です。
「夜中に走ったビルドのせいで、朝出社したらJenkinsのディスクがパンクしていた」「前のジョブが残していったゴミファイルのせいで、後続のビルドが謎の失敗(フレークテスト)を起こす……」
そんな呪われたようなインフラの悩みを抱えていませんか?
今回は、その苦しみからあなたを完全に解放する魔法、「Jenkins × Kubernetes(Ephemeral Agents)」の世界へご案内します。これをマスターすれば、あなたのチームのCI/CD環境は劇的にクリーンになり、インフラ管理コストは驚くほど削減されますよ。
肩の力を抜いて、僕と一緒に一つずつ紐解いていきましょう!
—
1. なぜ「使い捨て(Ephemeral)」のエージェントなのか?
従来のJenkinsが抱えていた「闇」
昔ながらのJenkins運用を思い出してください。常時起動している仮想マシンやベアメタルのサーバーを「Jenkinsスレーブ(エージェント)」として登録し、そこにビルドを流し込んでいましたよね。
この方式、実は大きな爆弾を抱えています。
- 環境の汚染(State Pollution): あるジョブがインストールしたnpmパッケージやコンパイラのバージョンが、次のジョブに悪影響を与える。
- リソースの無駄遣い: ビルドが走っていない夜間や休日でも、ハイスペックなエージェント費用を払い続けなければならない。
- スケールの限界: 同時ビルドが急増するとキューが詰まり、誰かが手動でサーバーを追加するハメになる。
Kubernetesがもたらす究極の解
ここでKubernetes(K8s)の登場です。
JenkinsのKubernetesプラグインを使うと、「ビルドがリクエストされた瞬間だけPodとしてエージェントが立ち上がり、ビルドが終わった瞬間に跡形もなく消え去る」という仕組みが作れます。これがEphemeral Agents(一時エージェント)です。
- 完全なクリーンネス: 毎回まっさらな環境でビルドが始まるため、環境依存のバグとは永遠にオサラバです。
- 圧倒的なコスト削減: 動いた時間(秒単位)しかリソースを消費しません。
- 無限のオートスケーリング: 100個同時にビルドが来ても、K8sが勝手に100個のPodを並列で立ち上げてくれます。
—
2. 全体像を理解する:アーキテクチャの仕組み
仕組みはとてもシンプルです。
1. 開発者がGitHub等でプルリクエストを作成し、Jenkinsにビルドがトリガーされる。
2. Jenkinsマスターが、「お、新しいビルドだな。Kubernetes APIに言って、専用のエージェントPodを作ってもらおう」と指示を出す。
3. Kubernetesクラスター内に、数秒でビルド用Pod(Jenkins Agent)がデプロイされる。
4. そのPodの中でテストやビルドが実行される。
5. ジョブが完了すると、Podは自動的に消滅する。
これだけです。これを実現するための設定を、一緒にステップ・バイ・ステップで見ていきましょう。
—
3. 基本セットアップ:JenkinsとK8sを繋ぎ込む
ここでは、すでにKubernetesクラスター(MinikubeやEKS、GKEなど)と、そこに稼働しているJenkinsマスターがある前提で話を進めますね。
ステップ1: Kubernetesプラグインの導入
Jenkinsの管理画面から [Jenkinsの管理] > [プラグインの管理] を開き、「Kubernetes Plugin」をインストールしてください(現代のJenkinsコンテナには最初から入っていることも多いです)。
ステップ2: クラウド設定の構成
次に、JenkinsとK8sを連携させます。
[Jenkinsの管理] > [システムの設定] の一番下にある「Cloud」セクションから、[新規クラウドを追加] > [Kubernetes] を選択します。
ここで以下の基本情報を設定します:
- Name: `kubernetes` (分かりやすい名前でOK)
- Kubernetes URL: `https://kubernetes.default` (内部DNSを使用する場合)
- Kubernetes Namespace: `jenkins` (Jenkinsやエージェントを動かす名前空間)
- Jenkins URL: `http://jenkins-master.jenkins.svc.cluster.local:8080` (エージェントからマスターに通信するためのアドレス)
—
4. 精度高いHelloWorld!Podテンプレートの定義
さて、ここが一番ワクワクするポイントです。Jenkinsfileから呼び出される「使い捨てエージェントの設計図(PodTemplate)」を定義しましょう。
今回は、Maven(Javaのビルドツール)と、コンテナ内で安全にコンテナをビルドするためのKanikoを同居させた、ちょっとリッチなエージェントを作ってみましょう。
Jenkinsfileの書き方(宣言的パイプライン)
プロジェクトのルートに置く `Jenkinsfile` をこう書いてみてください。
pipeline {
agent {
kubernetes {
// Kubernetesプラグインで定義したテンプレート名、または動的定義
yaml “””
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: jenkins-agent
spec:
containers:
- name: maven
image: maven:3.9.6-eclipse-temurin-17-alpine
command: [‘sleep’]
args: [’99d’]
resources:
limits:
memory: “1Gi”
cpu: “500m”
requests:
memory: “512Mi”
cpu: “200m”
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
command: [‘sleep’]
args: [’99d’]
resources:
limits:
memory: “1Gi”
cpu: “500m”
requests:
memory: “512Mi”
cpu: “200m”
“””
}
}
stages {
stage(‘ソースコードチェックアウト’) {
steps {
echo “Kubernetesエージェント上でコードを取得します…”
checkout scm
}
}
stage(‘Mavenビルド & テスト’) {
steps {
// mavenコンテナを指定してコマンドを実行
container(‘maven’) {
sh ‘mvn clean package’
}
}
}
stage(‘KanikoでDockerイメージビルド’) {
steps {
// 特権コンテナやDockerDaemonが不要なKanikoで安全にイメージをビルド
container(‘kaniko’) {
sh ”’
/kaniko/executor \
–context=dir://. \
–dockerfile=Dockerfile \
–destination=my-registry.local/my-app:${BUILD_NUMBER} \
–no-push
”’
}
}
}
}
}
この設定の美しいポイント
1. マルチコンテナPod: 1つのPodの中に `maven` と `kaniko` という2つのコンテナが同居しています。
2. ワークスペースの共有: Jenkinsプラグインが自動的にボリュームをマウントしてくれるため、`maven` コンテナがビルドした成果物を、同じPod内の `kaniko` コンテナからそのまま参照できます。
3. セキュリティ(Kanikoの活用): 通常のDockerビルドには `/var/run/docker.sock` のマウントなど危険な特権が必要ですが、Kanikoを使えば非特権(Rootless)で安全にOCIイメージがビルドできます。K8s環境ではこれがベストプラクティスです。
—
5. 現場で役立つ!さらに一歩進んだハック
このEphemeral Agents構成を運用する上で、知っておくと現場でヒーローになれる「実践知見」をいくつかシェアします。
① キャッシュを制する者がK8s CIを制す
「毎回まっさらな環境」の裏返しとして、Mavenの依存関係(~/.m2)やnpmのキャッシュが毎回ダウンロードされ、ビルドが遅くなるという罠があります。
これを解決するために、KubernetesのPersistentVolumeClaim(PVC)をエージェントのホームディレクトリにマウントさせましょう。
Podテンプレートのyamlに以下のように追記します。
spec:
containers:
- name: maven
image: maven:3.9.6-eclipse-temurin-17-alpine
command: [‘sleep’]
args: [’99d’]
volumeMounts:
- name: m2-cache
mountPath: /root/.m2
volumes:
- name: m2-cache
persistentVolumeClaim:
claimName: jenkins-m2-pvc
これで、キャッシュを保持しつつ、ソースコードやビルド成果物のゴミは一切残らない、理想的な環境が手に入ります。
② リソース制限(Requests/Limits)の黄金律
K8sクラスターが突然「OutOfMemory (OOMKilled)」でビルドを強制終了させないために、各コンテナの `resources` は必ず設定してください。特にJavaのビルドはメモリを食うため、`requests` と `limits` を適切に見積もることが、安定稼働の秘訣です。
—
まとめ:今すぐクリーンな世界へ踏み出そう
いかがでしたでしょうか?
Jenkins × KubernetesのEphemeral Agentsは、一見すると設定が難しそうに見えますが、一度仕組みを理解してしまえば、「インフラの管理地獄」からあなたを永遠に解放してくれる最強の武器になります。
- もう、ディスク容量を気にして夜中にログを消す必要はありません。
- もう、環境依存の謎のビルドエラーに頭を抱える必要もありません。
これをマスターすれば、毎日の開発作業が劇的に、そして圧倒的に楽になりますよ。ぜひ、あなたの検証クラスターで試してみてくださいね!