5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🚀 Kubernetes v1.33 の Image Volume β が激アツ!“コードだけ”イメージで世界が変わる!

Last updated at Posted at 2025-05-20

Kubernetes v1.33 でついに Image Volumeβ になりました!(※デフォルト無効)
OCI イメージをそのまま 読み取り専用ボリューム としてマウントできるこの機能、 革命的 じゃないですか?

🧠 Image Volume ってなにがスゴいの?

これまでの「すべてを 1 つのコンテナに詰め込む」やり方をやめて、

  • アプリコード
  • ランタイム
  • ライブラリ

などを イメージごとに分割してマウントできる時代が来ました。

特にスクリプト言語勢(Node.js / Python等)にはめちゃくちゃ効く!
例:アプリ本体が入った “コードだけ” イメージをマウントし、Node.js を node:22.15.1 で動かす。

🧱 “コードだけ”の超軽量イメージを実際に構築してみる

Image Volume の魅力は、コードや設定ファイルだけを含んだ超軽量な OCI イメージを作れること。
その例として、Node.js のアプリケーションコードだけを収めたシンプルなイメージを作ってみましょう。


📁 index.js – アプリ本体

const http = require('http');
http.createServer((_, res) => res.end('Hello from OCI volume!\n'))
    .listen(process.env.PORT || 80);

Node.js で「Hello from OCI volume!」を返すだけの HTTP サーバー。


🐳 Dockerfile – "FROM scratch" の衝撃

FROM scratch
COPY app /

FROM scratch(=何もない状態)からスタートし、COPY でコードだけを入れた構成。
つまり、Node.js すら入っていません。

これはどういう意味かというと、ランタイム(Node.js)は別のコンテナから提供し、
このイメージはただの「コード置き場」として使う、という使い方です。


📏 そのサイズ、なんとたったの 134バイト

この3つのファイルだけで構成された OCI イメージのサイズは、なんと 134バイト

docker images | grep hello-app
localhost:5001/hello-app                                                799466d0                 c4bd064f6fff   About a minute ago   134B
  • ビルドは一瞬 ✅
  • レジストリにプッシュしてもほぼ瞬間 ✅
  • CI/CD の負荷も最小限 ✅

コードが変わらない限りはこのイメージを再利用可能で、キャッシュのヒット率も向上します。


このように、「アプリケーションのコードだけをイメージ化する」という発想は、
従来の「全部入りコンテナ」とは完全に異なる世界観をもたらしてくれます。

Image Volume があることで、
アプリコードのライフサイクルランタイムのライフサイクル完全に分離できるようになります。

📦 ベースイメージのパッチも即対応!実際の差分で見る

ImageVolume を使っていると、ベースイメージの脆弱性修正に対しても驚くほど簡単に追従できます。

✅ パターン①:タグを固定して手動で更新

たとえば、node:22.15.0 のベースイメージに脆弱性パッチがリリースされた場合は…

-    image: mirror.gcr.io/node:22.15.0
+    image: mirror.gcr.io/node:22.15.1

このように Podimage を修正して再デプロイするだけで対応完了。
“アプリ本体”のコードイメージは何も変更不要!
CI も再ビルド不要。Yaml を 1 行変更するだけで、即座にセキュリティパッチが反映されます。


🔄 パターン②:タグを浮動 (node:22) にして自動追従

もっと“完全自動”に近づけたい場合は、タグをマイナーバージョンではなくメジャー (node:22) にして、
さらに imagePullPolicy: Always を設定すれば、Pod を再起動するだけで最新のパッチが取り込まれます。

image: node:22
imagePullPolicy: Always

これにより、22.15.0 → 22.15.122.16.0 へのアップデートも、Pod の再起動のみで自動反映されます。

:::caution ⚠️ 注意点
この方法は 常に最新のパッチを取り込める反面、
リグレッション(=新しいバージョンにバグが含まれる)を即時に踏むリスクもあるため、
安定性が最優先の本番環境では慎重な判断が必要です。

特に本番では明示的なタグの運用が安心です。
:::


💡まとめ

戦略 メリット 注意点
固定タグ (node:22.15.1) 安定・予測可能な動作 手動で更新が必要
浮動タグ + Pull Always (node:22) 常に最新パッチが自動反映される 意図しないバージョンに上がる可能性あり

状況や環境に応じて、リスクと自動化のバランスをとったタグ戦略を選びましょう。

🧪 実際に動かす!全自動スクリプト付き

Image Volume の世界をすぐに試してみたいあなたのために、一発で動く検証スクリプトも用意しました。

✅ 検証スクリプト全文はこちら:

#!/usr/bin/env bash
set -euox pipefail

# Create a temporary file for the upstream script
TMP_SCRIPT=$(mktemp)
echo "Downloading upstream kind-with-registry.sh to $TMP_SCRIPT"

# Download the upstream script
curl -fsSL https://kind.sigs.k8s.io/examples/kind-with-registry.sh -o "$TMP_SCRIPT"

# Patch and execute the script
# This adds the ImageVolume feature gate after the apiVersion line
echo "Patching and executing the script with ImageVolume feature gate enabled"
awk '
  /^apiVersion: kind.x-k8s.io\/v1alpha4/ {
    print
    print "featureGates:\n  ImageVolume: true"
    next
  }
  {print}
' "$TMP_SCRIPT" | bash -s

##############################################################################
# 2. "コードだけ" OCI イメージをビルド & push
##############################################################################
WORK=$(mktemp -d)
echo "Workdir: $WORK"
mkdir -p "$WORK/app"

cat > "$WORK/app/index.js" <<'JS'
const http = require('http');
http.createServer((_, res) => res.end('Hello from OCI volume!\n'))
    .listen(process.env.PORT || 80);
JS

cat > "$WORK/Dockerfile" <<'DOCKER'
FROM scratch
COPY app /
DOCKER

RAND_TAG=$(openssl rand -hex 4)
FULL_IMAGE="localhost:5001/hello-app:${RAND_TAG}"

docker build -f "$WORK/Dockerfile" -t "${FULL_IMAGE}" "$WORK"
docker push "${FULL_IMAGE}"

##############################################################################
# 4. Pod マニフェストを適用 (ImageVolume 参照)
##############################################################################
cat > "$WORK/node-demo.yaml" <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: node-demo
spec:
  containers:
  - name: runtime
    image: mirror.gcr.io/node:22-slim
    command: ["node", "/usr/src/app/index.js"]
    workingDir: /usr/src/app
    ports: [{containerPort: 80}]
    volumeMounts:
    - mountPath: /usr/src/app
      name: app-src
  volumes:
  - name: app-src
    image:
      reference: ${FULL_IMAGE}
      pullPolicy: IfNotPresent
EOF

sleep 10
kubectl apply -f "$WORK/node-demo.yaml"
kubectl wait --for=condition=Ready pod/node-demo --timeout=120s

##############################################################################
# 5. 動作確認
##############################################################################
kubectl port-forward pod/node-demo 3000:80 >/dev/null &
PF=$!
sleep 2
echo -n "curl → "
curl http://localhost:3000
kill $PF

cat <<EOM

✅ 完了! ImageVolume でコードをマウントした Node.js が起動しました。

後片付け:
  kind delete cluster
  rm -rf ${WORK}
EOM

このスクリプトをコピペして実行するだけで、あなたのローカル環境で Image Volume を使った Node.js アプリの立ち上げが完了します!

🎯 使い所:こんなケースで効いてくる

ユースケース 従来方法 Image Volumeなら
Node.js のコード配布
(例: node:22.15.1)
アプリコードをベースに組み込んで再ビルド コードだけを別イメージにし、マウントするだけ
Pythonライブラリの共有
(例: python:3.11-slim)
各アプリごとにビルド 共通環境をベースイメージに固定、アプリは別管理
AIモデルや証明書の展開 巨大イメージに全部詰め込み モデルや証明書だけを Image Volume 化して共有

✅ まとめ:これはもう、未来のデファクトになります

  • “コードだけ” イメージで ビルド時間短縮キャッシュヒット向上
  • ベースイメージの更新で パッチ即反映
  • CI/CD もスリムに、セキュリティも向上

「イメージをマウントする」って今までちょっとピンとこなかった人も、
この仕組みが 次世代のベストプラクティス になっていくのを今から体験してみてください。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?