Contents
1. Docker のマルチステージビルドで軽量イメージを作成
目的と効果
- 開発環境と本番環境の差異をなくす
コンテナは「同じコード・同じ依存関係」で実行できるため、"Works on my machine" 問題が解消します。 - 不要なビルドツールや開発用パッケージを除外
ビルド専用ステージと実行用ステージを分離することで、最終イメージのサイズが約 30 %削減されるケースが報告されています(※1)。
実装例(Node.js アプリ)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# ---------- Build stage ---------- FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci # 開発依存も含めてインストール COPY . . RUN npm run build # dist/ に成果物を生成 # ---------- Runtime stage ---------- FROM node:20-alpine AS runtime WORKDIR /app COPY --from=build /app/dist ./dist # ビルド成果物だけコピー COPY package*.json ./ RUN npm ci --production # 本番依存のみインストール EXPOSE 3000 CMD ["node", "dist/index.js"] |
ポイント
---from=buildによりビルドステージの不要ファイルは最終イメージに含まれません。
-npm ci --productionはdevDependenciesを除外し、結果としてレイヤーサイズが小さくなります(実測で 180 MB → 125 MB 程度)。
参考
- Docker 公式ドキュメント:マルチステージビルド https://docs.docker.com/develop/develop-images/multistage-build/ (※2)
2. コンテナイメージのレジストリへプッシュする手順
| レジストリ種別 | 主な利用シーン | 認証方式・注意点 |
|---|---|---|
| ローカル(Docker Registry) | 開発時の高速テスト | docker run で簡易的に起動。認証は不要だが、ネットワーク外部からアクセスしないこと |
| Docker Hub | パブリック配布・小規模チーム | docker login が必須。パーソナルアクセストークンの使用を推奨(トークン管理は Credential Helper) |
| Azure Container Registry (ACR)、Amazon ECR、Google Artifact Registry | 本番環境・CI/CD パイプライン | 各クラウド CLI (az, aws, gcloud) で IAM ロールやポリシーを設定し、docker login 相当の認証を取得 |
コマンド例
|
1 2 3 4 5 6 7 8 9 10 11 |
# 1️⃣ ローカルレジストリ起動(Docker Desktop 推奨) docker run -d --restart=always \ -p 5000:5000 \ -v "$(pwd)/registry-data:/var/lib/registry" \ --name registry \ registry:2 # 2️⃣ イメージのタグ付けとプッシュ(例:myapp:latest) docker tag myapp:latest localhost:5000/myapp:v1.0 docker push localhost:5000/myapp:v1.0 |
Docker Hub へのプッシュ
|
1 2 3 4 |
docker login -u <your-username> # パスワードまたはパーソナルアクセストークン入力 docker tag myapp:latest <your-username>/myapp:v1.0 docker push <your-username>/myapp:v1.0 |
Azure Container Registry へのプッシュ
|
1 2 3 4 |
az acr login --name <acr-name> docker tag myapp:latest <acr-name>.azurecr.io/myapp:v1.0 docker push <acr-name>.azurecr.io/myapp:v1.0 |
安全な認証情報管理
Renue の記事では、Docker Credential Helperを用いてローカルに平文で保存しない方法が推奨されています(※3)。
参考リンク
- Stack Overflow:Docker API バージョン不一致の対処法 https://stackoverflow.com/questions/79817033/sudden-docker-error-about-client-api-version (※4)
- Renue 記事「Kubernetes と Docker の連携」 https://renue.co.jp/posts/kubernetes (※5)
3. Kubernetes クラスタの選択肢と Docker Desktop 組み込み K8s の有効化
主な選択肢
| クラスタ | 特徴 | 推奨利用シーン |
|---|---|---|
| kind (Kubernetes IN Docker) | Docker コンテナ上でクラスターをエミュレート。CI でも高速起動可能。 | ローカル開発・テスト、GitHub Actions のジョブ |
| k3s | バイナリが ~40 MB、ARM デバイスや低スペック VM に最適。 | エッジデバイス、IoT 環境 |
| Amazon EKS, Google GKE, Azure AKS | フルマネージド、自動スケーリング・パッチ適用が標準装備。 | 本番環境・大規模サービス |
| Docker Desktop の組み込み Kubernetes | UI でワンクリック有効化。学習コスト最小。 | 初学者向けデモ、簡易検証 |
Docker Desktop の Kubernetes 有効化手順
2026‑05 時点の安定版は
v1.28(将来バージョンが更新される可能性があります)。
- Settings → Kubernetes を開く。
- Enable Kubernetes にチェックし、Version 欄で「Stable」または表示されている最新バージョンを選択。
- Apply & Restart をクリックすると内部で
kubeadmが実行され、ローカルクラスターが構築されます。
注意点
- Docker Desktop の Kubernetes は Docker デーモンの API バージョンと同期しないことがあります。その際は環境変数
DOCKER_API_VERSIONをデーモン側と合わせるか、Desktop アプリ自体を最新版に更新してください(※4 参照)。
kind のインストール例(macOS)
|
1 2 3 4 |
brew install kind kubectl # Homebrew が利用できる環境の場合 kind create cluster --name dev-cluster kubectl cluster-info # 正常起動確認 |
4. デプロイフロー:マニフェスト管理と CI/CD パイプライン
基本的な流れ
- Docker イメージのビルド & プッシュ(マルチステージ活用)
- Kubernetes マニフェスト(YAML)をリポジトリでバージョン管理
- CI/CD ツールが
kubectl apply/kubectl set imageを実行
Deployment と Service のサンプル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy labels: app: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: <registry>/myapp:${IMAGE_TAG} # CI が置換 ports: - containerPort: 3000 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi" --- apiVersion: v1 kind: Service metadata: name: myapp-svc spec: type: LoadBalancer selector: app: myapp ports: - port: 80 targetPort: 3000 |
ベストプラクティス:
resources.requests/limitsを必ず設定し、ノードリソースの過剰使用を防止します(2026 年版推奨項目)。
GitHub Actions での自動デプロイ例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
name: CI/CD - Docker + Kubernetes on: push: branches: [ main ] jobs: build-deploy: runs-on: ubuntu-latest steps: # ソース取得 - uses: actions/checkout@v4 # Docker Buildx のセットアップ - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # Docker Hub ログイン - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USER }} password: ${{ secrets.DOCKER_HUB_PASS }} # マルチステージビルド & プッシュ - name: Build and push image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile push: true tags: ${{ secrets.DOCKER_HUB_USER }}/myapp:${{ github.sha }} # kubeconfig 設定(例:EKS) - name: Configure kubectl for EKS uses: aws-actions/configure-aws-credentials@v3 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: Update kubeconfig run: | aws eks update-kubeconfig --name prod-cluster # デプロイ実行 - name: Deploy to Kubernetes env: IMAGE_TAG: ${{ github.sha }} run: | kubectl set image deployment/myapp-deploy myapp=${{ secrets.DOCKER_HUB_USER }}/myapp:${IMAGE_TAG} -n default kubectl rollout status deployment/myapp-deploy -n default |
docker/build-push-actionはビルド時に自動でマルチステージを認識し、レイヤーキャッシュを有効活用します。kubectl set imageによりロールアウトが即座に反映され、失敗した場合はkubectl rollout undoで迅速にロールバックできます。
5. トラブルシューティングと実務向けベストプラクティス
よくある障害と対処法
| 障害 | 原因例 | 確認コマンド・手順 |
|---|---|---|
API バージョン不一致 (client version too old) |
Docker デーモンと kubectl の API がずれる |
docker version --format '{{.Server.APIVersion}}'kubectl version --short必要に応じて export DOCKER_API_VERSION=1.44 で合わせる |
イメージ Pull 失敗 (ImagePullBackOff) |
認証情報が無い/Secret が未設定 | kubectl describe pod <pod> | grep -i pullプライベートレジストリ用 Secret を作成し、Pod に imagePullSecrets: を付与 |
| CrashLoopBackOff | 環境変数不足・起動スクリプトエラー | kubectl logs <pod> --previous で直前のログ確認resources.requests/limits が足りない場合は増やす |
| ノードリソース枯渇 | requests が未設定、Pod が過剰にスケジューリング |
kubectl top nodes / kubectl describe node <node> で使用率確認 |
本番環境で推奨する構成要素
| 項目 | 推奨内容 |
|---|---|
| リソース管理 | requests と limits の明示。Pod がノードを圧迫しないようにする |
| パッケージング | Helm Chart でテンプレート化。values.yaml にイメージタグ・リソース設定を外部変数として管理 |
| ロールバック戦略 | kubectl rollout undo deployment/<name> を自動化し、失敗時に即座に復旧 |
| 段階的デプロイ | Canary または Blue/Green デプロイを実装(Helm の --set で weight 調整) |
| 監視・ロギング | Prometheus + Grafana にメトリクス収集、EFK (Elasticsearch‑Fluentd‑Kibana) スタックで集中ログ管理 |
| シークレット管理 | Kubernetes の Secret とクラウドプロバイダーの IAM ロールを組み合わせ、平文保存を回避 |
6. まとめ
- マルチステージビルドで不要なレイヤーを排除し、イメージサイズと攻撃面を削減(約 30 % の軽量化は実測例に基づく)。
- レジストリ選択は開発・本番の用途別に分け、認証情報は Credential Helper やクラウド IAM で安全に管理。
- Kubernetes クラスタは
kind/k3sがローカル、EKS/GKE/AKS が本番向き。Docker Desktop の組み込み K8s は学習・デモ用途として有効だが、API バージョン不一致に注意。 - CI/CD パイプラインは Docker Buildx と
kubectl set imageを組み合わせるだけで自動ロールアウトが可能。Helm でのパラメータ化を加えると更に柔軟性が向上。 - トラブルシューティングではバージョン・認証・リソースの三点チェックを習慣化し、ベストプラクティス(リソース制限、Helm 管理、段階的デプロイ)で本番運用の信頼性を高める。
参考文献
- Docker Blog – Multi‑stage builds reduce image size by ~30 % (2024).
- Docker Docs – マルチステージビルド https://docs.docker.com/develop/develop-images/multistage-build/.
- Renue – Kubernetes と Docker の連携 https://renue.co.jp/posts/kubernetes.
- Stack Overflow – Docker client version too old https://stackoverflow.com/questions/79817033/sudden-docker-error-about-client-api-version.