Container Management Docker Podman

コンテナ管理 Docker/Podman 完全ガイド

目次

  1. はじめに
  2. コンテナの基本概念
  3. Docker アーキテクチャ
  4. Docker のインストール
  5. Dockerfile
  6. Docker コマンド詳細
  7. Docker Compose
  8. Docker ネットワーキング
  9. Docker ボリュームとバインドマウント
  10. Docker セキュリティベストプラクティス
  11. Podman:Docker の代替
  12. Buildah と Skopeo
  13. コンテナオーケストレーション概要
  14. トラブルシューティング
  15. ベストプラクティスまとめ
  16. 参考文献

1. はじめに

コンテナ技術は、アプリケーションの開発・デプロイ・運用において革命的な変化をもたらした。OS レベルの仮想化によって軽量で高速な分離環境を提供し、「一度ビルドすれば、どこでも動く」というポータビリティを実現する。

本ドキュメントでは、Linux コンテナの基礎技術、Docker、Podman、および関連ツールについて、基礎概念から実践的な運用ノウハウまでを網羅的に解説する。


2. コンテナの基本概念

2.1 名前空間(Namespaces)

Linux 名前空間は、プロセスが見えるシステムリソースを分離する カーネル機能である。

名前空間分離対象フラグ
PIDプロセス IDCLONE_NEWPID
NETネットワークスタックCLONE_NEWNET
MNTマウントポイントCLONE_NEWNS
UTSホスト名・ドメイン名CLONE_NEWUTS
IPCプロセス間通信CLONE_NEWIPC
USERユーザー/グループ IDCLONE_NEWUSER
Cgroupcgroup ルートCLONE_NEWCGROUP
Timeシステム時刻(Linux 5.6+)CLONE_NEWTIME
# コンテナの名前空間を確認
$ docker inspect --format '{{.State.Pid}}' my-container
12345

$ ls -la /proc/12345/ns/
total 0
lrwxrwxrwx 1 root root 0 Apr 10 10:00 cgroup -> 'cgroup:[4026532456]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 ipc -> 'ipc:[4026532454]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 mnt -> 'mnt:[4026532451]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 net -> 'net:[4026532457]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 pid -> 'pid:[4026532455]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Apr 10 10:00 uts -> 'uts:[4026532453]'

# 名前空間に入る(デバッグ用)
$ nsenter -t 12345 -m -u -i -n -p -- /bin/bash

2.2 cgroups(コントロールグループ)

cgroups はプロセスのリソース使用量を制限・監視する機能である。

# cgroups v2 の確認
$ stat -fc %T /sys/fs/cgroup/
cgroup2fs

# コンテナの cgroup 情報
$ cat /sys/fs/cgroup/system.slice/docker-<container-id>.scope/memory.max
8589934592    # 8 GiB

$ cat /sys/fs/cgroup/system.slice/docker-<container-id>.scope/cpu.max
100000 100000    # CPU 100%

# Docker でリソース制限を指定
$ docker run -d \
    --memory=512m \
    --memory-swap=1g \
    --cpus=2.0 \
    --cpu-shares=512 \
    --pids-limit=100 \
    --blkio-weight=300 \
    nginx:latest

主要な cgroups コントローラ:

コントローラ制限対象Docker オプション
memoryメモリ使用量--memory, --memory-swap
cpuCPU 使用率--cpus, --cpu-shares
cpusetCPU コア/メモリノード--cpuset-cpus, --cpuset-mems
blkio/ioブロック I/O--blkio-weight, --device-read-bps
pidsプロセス数--pids-limit

2.3 ユニオンファイルシステム

ユニオンファイルシステムは、複数のファイルシステムレイヤーを重ね合わせて一つのファイルシステムとして見せる技術である。

┌────────────────────────────┐
│   コンテナレイヤー (R/W)     │  ← コンテナ固有の変更
├────────────────────────────┤
│   イメージレイヤー 3 (R/O)   │  ← COPY app.jar
├────────────────────────────┤
│   イメージレイヤー 2 (R/O)   │  ← RUN apt-get install
├────────────────────────────┤
│   イメージレイヤー 1 (R/O)   │  ← FROM ubuntu:24.04
└────────────────────────────┘

主要なストレージドライバ:

ドライバ特徴推奨環境
overlay2標準的、高性能ほとんどの環境(推奨)
btrfsBtrfs ファイルシステム用Btrfs ボリューム
zfsZFS ファイルシステム用ZFS ボリューム
devicemapperLVM thin provisioningRHEL 旧版
# 使用中のストレージドライバを確認
$ docker info | grep "Storage Driver"
 Storage Driver: overlay2

2.4 コンテナ vs 仮想マシン

項目コンテナ仮想マシン
起動時間数秒数十秒〜数分
リソース消費軽量(数 MB〜)重い(数百 MB〜)
分離レベルプロセスレベルハードウェアレベル
カーネルホストと共有独自カーネル
ポータビリティ高い中程度
セキュリティ中程度高い
密度高い(数百/ホスト)低い(数十/ホスト)

3. Docker アーキテクチャ

3.1 Docker エンジンの構成

┌─────────────────────────────────────────────┐
│               Docker CLI                     │
│         (docker コマンド)                     │
├─────────────────────────────────────────────┤
│            Docker API (REST)                 │
├─────────────────────────────────────────────┤
│           Docker Daemon (dockerd)            │
│  ┌────────────┐  ┌────────────────┐        │
│  │ イメージ管理 │  │ ネットワーク管理 │        │
│  └────────────┘  └────────────────┘        │
│  ┌────────────┐  ┌────────────────┐        │
│  │ ボリューム   │  │  プラグイン     │        │
│  └────────────┘  └────────────────┘        │
├─────────────────────────────────────────────┤
│              containerd                      │
│       (コンテナランタイム管理)                 │
├─────────────────────────────────────────────┤
│               runc (OCI runtime)             │
│        (コンテナの実行)                       │
├─────────────────────────────────────────────┤
│           Linux カーネル                      │
│    (namespaces, cgroups, seccomp)            │
└─────────────────────────────────────────────┘

3.2 Docker デーモン

# Docker デーモンの設定ファイル
$ cat /etc/docker/daemon.json
{
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-address-pools": [
    {"base": "172.17.0.0/16", "size": 24}
  ],
  "live-restore": true,
  "userland-proxy": false,
  "experimental": false,
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 64000,
      "Soft": 64000
    }
  }
}

# デーモンの再起動
$ sudo systemctl restart docker

3.3 containerd と runc

# containerd の状態確認
$ sudo systemctl status containerd

# containerd の直接操作(ctr コマンド)
$ sudo ctr images ls
$ sudo ctr containers ls

# runc の直接操作
$ runc --version
runc version 1.1.12
spec: 1.0.2-dev

3.4 Docker レジストリ

レジストリURL特徴
Docker Hubhub.docker.com公式、最大のパブリックレジストリ
GitHub Container Registryghcr.ioGitHub 統合
Amazon ECR.dkr.ecr..amazonaws.comAWS 統合
Google Artifact Registry*.pkg.devGCP 統合
Azure Container Registry*.azurecr.ioAzure 統合
Harbor自己ホストOSS プライベートレジストリ

4. Docker のインストール

4.1 RHEL/CentOS へのインストール

# 古いバージョンの削除
$ sudo dnf remove docker docker-client docker-client-latest \
    docker-common docker-latest docker-latest-logrotate \
    docker-logrotate docker-engine

# リポジトリの追加
$ sudo dnf install -y yum-utils
$ sudo yum-config-manager --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# インストール
$ sudo dnf install docker-ce docker-ce-cli containerd.io \
    docker-buildx-plugin docker-compose-plugin

# サービスの起動
$ sudo systemctl enable --now docker

# 動作確認
$ sudo docker run hello-world

4.2 Ubuntu へのインストール

# 古いパッケージの削除
$ sudo apt remove docker docker-engine docker.io containerd runc

# リポジトリの設定
$ sudo apt update
$ sudo apt install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# インストール
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io \
    docker-buildx-plugin docker-compose-plugin

4.3 インストール後の設定

# 一般ユーザーで Docker を使用可能にする
$ sudo usermod -aG docker $USER
$ newgrp docker

# Docker の情報確認
$ docker info
Client: Docker Engine - Community
 Version:    26.1.0
 Context:    default
Server:
 Server Version: 26.1.0
 Storage Driver: overlay2
 Cgroup Driver: systemd
 Cgroup Version: 2
 Kernel Version: 6.8.0
 Operating System: Rocky Linux 9.4
 Architecture: x86_64
 CPUs: 8
 Total Memory: 31.25GiB

5. Dockerfile

5.1 基本命令

# FROM: ベースイメージの指定
FROM ubuntu:24.04

# LABEL: メタデータの付加
LABEL maintainer="admin@example.com"
LABEL version="1.0"
LABEL description="My application container"

# ENV: 環境変数の設定
ENV APP_HOME=/app \
    APP_USER=appuser \
    NODE_ENV=production

# ARG: ビルド時の変数(実行時には残らない)
ARG BUILD_VERSION=1.0.0

# RUN: コマンドの実行
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl \
        ca-certificates \
        python3 && \
    rm -rf /var/lib/apt/lists/*

# WORKDIR: 作業ディレクトリの設定
WORKDIR ${APP_HOME}

# COPY: ファイルのコピー(ビルドコンテキストから)
COPY --chown=appuser:appuser . .

# ADD: ファイルの追加(tar 展開や URL ダウンロードも可能)
ADD https://example.com/config.tar.gz /tmp/

# USER: 実行ユーザーの変更
RUN useradd -r -s /bin/false ${APP_USER}
USER ${APP_USER}

# EXPOSE: 公開するポートの宣言
EXPOSE 8080

# VOLUME: ボリュームマウントポイントの宣言
VOLUME ["/data"]

# HEALTHCHECK: ヘルスチェックの定義
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
    CMD curl -f http://localhost:8080/health || exit 1

# ENTRYPOINT: コンテナのエントリーポイント
ENTRYPOINT ["python3"]

# CMD: デフォルトの引数(ENTRYPOINT と組み合わせ)
CMD ["app.py"]

ENTRYPOINT と CMD の違い:

項目ENTRYPOINTCMD
役割メインコマンドデフォルト引数
オーバーライド--entrypoint で可能docker run の引数で可能
推奨用途実行バイナリの指定デフォルトパラメータ
# 組み合わせ例
ENTRYPOINT ["python3", "app.py"]
CMD ["--port", "8080"]

# docker run myapp → python3 app.py --port 8080
# docker run myapp --port 9090 → python3 app.py --port 9090

5.2 マルチステージビルド

# ステージ 1: ビルド環境
FROM golang:1.22-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

# ステージ 2: 実行環境(最小イメージ)
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata && \
    adduser -D -g '' appuser
WORKDIR /app
COPY --from=builder /build/app .
USER appuser
EXPOSE 8080
ENTRYPOINT ["./app"]
# Java アプリケーションのマルチステージビルド
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=build /build/target/*.jar app.jar
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
    CMD wget -qO- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]

5.3 ベストプラクティス

# 1. 軽量なベースイメージを使用
FROM alpine:3.19          # 最小(~7MB)
FROM distroless/base      # Google Distroless(~20MB)
FROM ubuntu:24.04         # フル機能(~78MB)

# 2. レイヤー数を最小化(RUN 命令を結合)
# 悪い例:
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

# 良い例:
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

# 3. .dockerignore を活用
# .dockerignore ファイル
.git
node_modules
*.md
Dockerfile
docker-compose.yml
.env

# 4. 非 root ユーザーで実行
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
USER appuser

# 5. COPY を ADD より優先(明示的)
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

# 6. 固定バージョンのタグを使用
FROM python:3.12.3-slim    # 良い
FROM python:latest         # 悪い(予測不能)

6. Docker コマンド詳細

6.1 コンテナ操作

# コンテナの起動
$ docker run -d \
    --name web-app \
    --hostname web-app \
    -p 8080:80 \
    -v /host/data:/container/data \
    -e APP_ENV=production \
    --restart unless-stopped \
    --memory=512m \
    --cpus=1.0 \
    nginx:1.25

# コンテナの一覧
$ docker ps -a
CONTAINER ID   IMAGE        COMMAND                  CREATED        STATUS        PORTS                  NAMES
abc123def456   nginx:1.25   "/docker-entrypoint.…"   2 hours ago    Up 2 hours    0.0.0.0:8080->80/tcp   web-app

# コンテナの停止・起動・再起動
$ docker stop web-app
$ docker start web-app
$ docker restart web-app

# コンテナに入る
$ docker exec -it web-app /bin/bash
$ docker exec -it web-app sh    # Alpine 系

# コンテナのログ
$ docker logs web-app
$ docker logs -f web-app              # フォロー(リアルタイム)
$ docker logs --tail 100 web-app      # 最後の100行
$ docker logs --since 1h web-app      # 直近1時間

# コンテナの詳細情報
$ docker inspect web-app
$ docker inspect --format '{{.NetworkSettings.IPAddress}}' web-app

# コンテナのリソース使用状況
$ docker stats
CONTAINER ID   NAME      CPU %   MEM USAGE / LIMIT   MEM %   NET I/O       BLOCK I/O
abc123def456   web-app   0.05%   12.5MiB / 512MiB    2.44%   1.2kB / 0B    0B / 0B

# コンテナの削除
$ docker rm web-app
$ docker rm -f web-app               # 強制削除(実行中でも)

# 停止中の全コンテナを削除
$ docker container prune

# コンテナからファイルをコピー
$ docker cp web-app:/etc/nginx/nginx.conf ./nginx.conf
$ docker cp ./index.html web-app:/usr/share/nginx/html/

6.2 イメージ操作

# イメージのビルド
$ docker build -t myapp:1.0 .
$ docker build -t myapp:1.0 -f Dockerfile.prod .
$ docker build --no-cache -t myapp:1.0 .
$ docker build --build-arg VERSION=2.0 -t myapp:2.0 .

# イメージの一覧
$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
myapp        1.0       sha256:abc...  2 hours ago    150MB
nginx        1.25      sha256:def...  3 days ago     187MB

# イメージの取得
$ docker pull nginx:1.25
$ docker pull ghcr.io/org/repo:tag

# イメージのプッシュ
$ docker tag myapp:1.0 registry.example.com/myapp:1.0
$ docker push registry.example.com/myapp:1.0

# イメージの削除
$ docker rmi myapp:1.0
$ docker image prune              # 未使用イメージの削除
$ docker image prune -a           # タグなし + 未使用の全削除

# イメージの履歴(レイヤー確認)
$ docker history myapp:1.0
IMAGE          CREATED        CREATED BY                                      SIZE
abc123def456   2 hours ago    CMD ["python3" "app.py"]                        0B
bcd234efg567   2 hours ago    COPY . . # buildkit                             15.2MB
cde345fgh678   2 hours ago    RUN /bin/sh -c pip install -r requirements...   45.3MB

# イメージの保存とロード
$ docker save myapp:1.0 -o myapp.tar
$ docker load -i myapp.tar

6.3 ネットワーク操作

# ネットワーク一覧
$ docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
abc123def456   bridge     bridge    local
bcd234efg567   host       host      local
cde345fgh678   none       null      local

# カスタムネットワークの作成
$ docker network create \
    --driver bridge \
    --subnet 172.20.0.0/16 \
    --gateway 172.20.0.1 \
    my-network

# コンテナをネットワークに接続
$ docker network connect my-network web-app
$ docker network disconnect my-network web-app

# ネットワークの詳細
$ docker network inspect my-network

6.4 ボリューム操作

# ボリュームの作成
$ docker volume create my-data

# ボリューム一覧
$ docker volume ls

# ボリュームの詳細
$ docker volume inspect my-data
[
    {
        "CreatedAt": "2026-04-10T10:00:00Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-data/_data",
        "Name": "my-data",
        "Options": {},
        "Scope": "local"
    }
]

# ボリュームを使用してコンテナを起動
$ docker run -d -v my-data:/app/data myapp:1.0

# 未使用ボリュームの削除
$ docker volume prune

6.5 その他の操作

# システムの情報
$ docker info
$ docker version

# ディスク使用量
$ docker system df
TYPE            TOTAL   ACTIVE  SIZE      RECLAIMABLE
Images          15      5       3.2GB     1.8GB (56%)
Containers      8       3       25MB      15MB (60%)
Local Volumes   10      4       500MB     200MB (40%)
Build Cache     20      0       800MB     800MB (100%)

# 全クリーンアップ(注意)
$ docker system prune -a --volumes

7. Docker Compose

7.1 docker-compose.yml の構造

# docker-compose.yml の基本構造
version: "3.9"

services:
  # サービス定義
  service-name:
    image: image:tag
    # または
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "host:container"
    volumes:
      - volume:/path
    environment:
      - KEY=value
    depends_on:
      - other-service
    networks:
      - my-network
    restart: unless-stopped

volumes:
  volume-name:
    driver: local

networks:
  my-network:
    driver: bridge

7.2 実践的な構成例

# Web アプリケーション + データベース + キャッシュの構成
version: "3.9"

services:
  # Web アプリケーション
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - BUILD_ENV=production
    container_name: myapp
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
      - REDIS_URL=redis://cache:6379
      - NODE_ENV=production
    volumes:
      - app-logs:/app/logs
      - ./config:/app/config:ro
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    networks:
      - frontend
      - backend
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # PostgreSQL データベース
  db:
    image: postgres:16-alpine
    container_name: myapp-db
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5
    secrets:
      - db_password

  # Redis キャッシュ
  cache:
    image: redis:7-alpine
    container_name: myapp-cache
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - cache-data:/data
    networks:
      - backend
    restart: unless-stopped

  # Nginx リバースプロキシ
  nginx:
    image: nginx:1.25-alpine
    container_name: myapp-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - app
    networks:
      - frontend
    restart: unless-stopped

volumes:
  db-data:
    driver: local
  cache-data:
    driver: local
  app-logs:
    driver: local

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

secrets:
  db_password:
    file: ./secrets/db_password.txt

7.3 Compose コマンド

# サービスの起動
$ docker compose up -d

# サービスの停止
$ docker compose down

# サービスの停止(ボリュームも削除)
$ docker compose down -v

# サービスの再ビルドと起動
$ docker compose up -d --build

# 特定のサービスのみ起動
$ docker compose up -d app db

# サービスのスケーリング
$ docker compose up -d --scale app=3

# ログの表示
$ docker compose logs -f app

# サービスの状態確認
$ docker compose ps

# コンテナ内でコマンド実行
$ docker compose exec app bash

# 設定の検証
$ docker compose config

8. Docker ネットワーキング

8.1 ブリッジネットワーク

# デフォルトブリッジ(docker0)
$ docker run -d --name web1 nginx
$ docker run -d --name web2 nginx
# web1 と web2 は IP アドレスでのみ通信可能

# カスタムブリッジ(DNS サービスディスカバリ付き)
$ docker network create my-bridge
$ docker run -d --name web1 --network my-bridge nginx
$ docker run -d --name web2 --network my-bridge nginx
# web1 と web2 はコンテナ名で通信可能

# カスタムブリッジからの ping テスト
$ docker exec web1 ping web2
PING web2 (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.089 ms

8.2 ホストネットワーク

# ホストネットワーク(ポートマッピング不要、最高性能)
$ docker run -d --name web --network host nginx
# ホストの 80 番ポートで直接アクセス可能

8.3 オーバーレイネットワーク

# Swarm モードで使用(マルチホスト通信)
$ docker network create --driver overlay --attachable my-overlay

8.4 macvlan

# macvlan ネットワーク(物理ネットワークに直接接続)
$ docker network create -d macvlan \
    --subnet=192.168.1.0/24 \
    --gateway=192.168.1.1 \
    -o parent=eth0 \
    my-macvlan

9. Docker ボリュームとバインドマウント

9.1 ボリューム

# 名前付きボリューム(推奨)
$ docker run -d -v my-data:/app/data myapp

# 匿名ボリューム
$ docker run -d -v /app/data myapp

# ボリュームのバックアップ
$ docker run --rm \
    -v my-data:/source:ro \
    -v $(pwd):/backup \
    alpine tar czf /backup/my-data-backup.tar.gz -C /source .

# ボリュームの復元
$ docker run --rm \
    -v my-data:/target \
    -v $(pwd):/backup \
    alpine tar xzf /backup/my-data-backup.tar.gz -C /target

9.2 バインドマウント

# バインドマウント(ホストディレクトリを直接マウント)
$ docker run -d \
    -v /host/path:/container/path \
    -v $(pwd)/config:/app/config:ro \
    myapp

# --mount 構文(より明示的)
$ docker run -d \
    --mount type=bind,source=/host/data,target=/app/data,readonly \
    myapp

9.3 tmpfs マウント

# tmpfs マウント(メモリ上の一時ファイルシステム)
$ docker run -d \
    --tmpfs /tmp:rw,noexec,nosuid,size=100m \
    myapp

10. Docker セキュリティベストプラクティス

イメージのセキュリティ

# 1. 信頼できるベースイメージを使用
FROM docker.io/library/nginx:1.25-alpine

# 2. イメージの脆弱性スキャン
$ docker scout cves myapp:1.0
$ trivy image myapp:1.0

# 3. 固定ダイジェストを使用(再現性の保証)
FROM nginx@sha256:abc123def456...

ランタイムのセキュリティ

# 非 root ユーザーで実行
$ docker run -d --user 1000:1000 myapp

# read-only ルートファイルシステム
$ docker run -d --read-only --tmpfs /tmp myapp

# capabilities の制限
$ docker run -d \
    --cap-drop ALL \
    --cap-add NET_BIND_SERVICE \
    myapp

# seccomp プロファイルの適用
$ docker run -d --security-opt seccomp=./seccomp-profile.json myapp

# no-new-privileges の設定
$ docker run -d --security-opt no-new-privileges myapp

# リソース制限
$ docker run -d \
    --memory=512m \
    --cpus=1.0 \
    --pids-limit=100 \
    myapp

ネットワークのセキュリティ

# 内部ネットワーク(外部アクセス不可)
$ docker network create --internal backend

# 特定の IP にバインド
$ docker run -d -p 127.0.0.1:8080:80 myapp

11. Podman:Docker の代替

11.1 Podman の概要

Podman (Pod Manager) は Red Hat が開発したコンテナエンジンで、Docker の代替として設計されている。

Docker との主な違い:

項目DockerPodman
アーキテクチャクライアント-サーバー(デーモン必須)デーモンレス
実行権限デフォルトで rootルートレスが標準
Pod サポートなし(Compose のみ)ネイティブ Pod サポート
systemd 統合限定的ネイティブ統合
OCI 準拠はいはい
CLI 互換性-Docker CLI と互換
セキュリティデーモンが root で動作fork/exec モデル

11.2 デーモンレスアーキテクチャ

Docker:                          Podman:
┌──────────┐                     ┌──────────┐
│ docker   │                     │ podman   │
│ CLI      │                     │ CLI      │
└────┬─────┘                     └────┬─────┘
     │                                │
     ▼                                ▼
┌──────────┐                     ┌──────────┐
│ dockerd  │ (デーモン)           │ conmon   │ (コンテナモニタ)
└────┬─────┘                     └────┬─────┘
     │                                │
     ▼                                ▼
┌──────────┐                     ┌──────────┐
│containerd│                     │ runc/    │
└────┬─────┘                     │ crun     │
     │                           └──────────┘
     ▼
┌──────────┐
│   runc   │
└──────────┘

11.3 ルートレスコンテナ

# Podman のインストール
$ sudo dnf install podman        # RHEL系
$ sudo apt install podman         # Ubuntu

# ルートレスでのコンテナ実行(一般ユーザー)
$ podman run -d --name web -p 8080:80 nginx:latest

# ルートレスの確認
$ podman info | grep rootless
  rootless: true

# ユーザー名前空間のマッピング確認
$ podman unshare cat /proc/self/uid_map
         0       1000          1
         1     100000      65536

# subuid/subgid の設定確認
$ cat /etc/subuid
user:100000:65536
$ cat /etc/subgid
user:100000:65536

11.4 Pod コンセプト

Podman の「Pod」は Kubernetes の Pod と同じ概念で、複数のコンテナをグループ化する。

# Pod の作成
$ podman pod create --name my-pod -p 8080:80

# Pod にコンテナを追加
$ podman run -d --pod my-pod --name web nginx:latest
$ podman run -d --pod my-pod --name app myapp:latest

# Pod 内のコンテナは localhost で相互通信可能

# Pod の一覧
$ podman pod ls
POD ID         NAME     STATUS    CREATED        INFRA ID       # OF CONTAINERS
abc123def456   my-pod   Running   2 hours ago    bcd234efg567   3

# Pod の停止
$ podman pod stop my-pod

# Pod の削除
$ podman pod rm my-pod

# Kubernetes YAML の生成
$ podman generate kube my-pod > my-pod.yaml

# Kubernetes YAML からの実行
$ podman play kube my-pod.yaml

11.5 Podman コマンド

# Docker 互換(ほぼ同じコマンド体系)
$ podman run -d --name web -p 8080:80 nginx
$ podman ps -a
$ podman logs web
$ podman exec -it web bash
$ podman stop web
$ podman rm web
$ podman images
$ podman build -t myapp:1.0 .
$ podman push myapp:1.0 registry.example.com/myapp:1.0

# Docker エイリアスの設定
$ alias docker=podman

# systemd ユニットファイルの生成
$ podman generate systemd --new --files --name web
# /home/user/.config/systemd/user/container-web.service が生成される

# systemd でコンテナを管理
$ systemctl --user enable --now container-web.service
$ systemctl --user status container-web.service

# Quadlet(Podman 4.4+、systemd ネイティブ統合)
$ cat ~/.config/containers/systemd/web.container
[Container]
Image=nginx:latest
PublishPort=8080:80
Volume=web-data.volume:/usr/share/nginx/html

[Service]
Restart=always

[Install]
WantedBy=default.target

$ systemctl --user daemon-reload
$ systemctl --user start web

12. Buildah と Skopeo

12.1 Buildah

Buildah はコンテナイメージをビルドするための専用ツールで、Dockerfile なしでもイメージを構築できる。

# Buildah のインストール
$ sudo dnf install buildah

# Dockerfile からのビルド
$ buildah bud -t myapp:1.0 .

# スクリプトによるビルド(Dockerfile 不要)
$ container=$(buildah from alpine:3.19)
$ buildah run $container -- apk add --no-cache python3 pip
$ buildah copy $container ./app /app
$ buildah config --workingdir /app $container
$ buildah config --entrypoint '["python3", "app.py"]' $container
$ buildah config --port 8080 $container
$ buildah commit $container myapp:1.0

# レイヤーの制御が柔軟
$ buildah config --label maintainer="admin@example.com" $container
$ buildah config --env APP_ENV=production $container

12.2 Skopeo

Skopeo はコンテナイメージの検査・コピー・署名を行うツールである。

# Skopeo のインストール
$ sudo dnf install skopeo

# イメージの検査(ダウンロード不要)
$ skopeo inspect docker://docker.io/library/nginx:1.25
{
    "Name": "docker.io/library/nginx",
    "Digest": "sha256:abc123...",
    "RepoTags": ["1.25", "1.25.0", "1.25.1", ...],
    "Created": "2026-03-15T12:00:00Z",
    "Architecture": "amd64",
    "Os": "linux"
}

# レジストリ間のイメージコピー
$ skopeo copy \
    docker://docker.io/library/nginx:1.25 \
    docker://registry.example.com/nginx:1.25

# ローカルディレクトリにコピー
$ skopeo copy docker://nginx:1.25 dir:/tmp/nginx-image

# OCI イメージとしてコピー
$ skopeo copy docker://nginx:1.25 oci:/tmp/nginx-oci:1.25

# イメージの削除
$ skopeo delete docker://registry.example.com/myapp:old

# レジストリのタグ一覧
$ skopeo list-tags docker://docker.io/library/nginx

13. コンテナオーケストレーション概要

13.1 Kubernetes 基礎

Kubernetes(K8s)はコンテナオーケストレーションの事実上の標準である。

# 基本的な Pod 定義
apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    app: web
spec:
  containers:
    - name: web
      image: nginx:1.25
      ports:
        - containerPort: 80
      resources:
        requests:
          memory: "128Mi"
          cpu: "250m"
        limits:
          memory: "256Mi"
          cpu: "500m"
# Deployment 定義
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:1.25
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

Kubernetes の主要コンポーネント:

コンポーネント役割
kube-apiserverAPI サーバー(全操作のエントリーポイント)
etcd分散 KVS(クラスタの状態管理)
kube-schedulerPod のスケジューリング
kube-controller-managerコントローラの管理
kubeletノード上のコンテナ管理
kube-proxyネットワークプロキシ

13.2 Docker Swarm

# Swarm の初期化
$ docker swarm init

# サービスのデプロイ
$ docker service create \
    --name web \
    --replicas 3 \
    -p 80:80 \
    nginx:1.25

# サービスの一覧
$ docker service ls

# スケーリング
$ docker service scale web=5

14. トラブルシューティング

コンテナが起動しない

# ログの確認
$ docker logs my-container
$ docker logs --tail 50 my-container

# コンテナの詳細情報
$ docker inspect my-container

# イベントの確認
$ docker events --since "1h"

# 起動に失敗するコンテナをデバッグ
$ docker run -it --entrypoint /bin/sh myapp:1.0

ネットワークの問題

# DNS 解決の確認
$ docker exec my-container nslookup other-container

# ネットワーク接続の確認
$ docker exec my-container ping other-container
$ docker exec my-container curl http://other-container:8080

# ネットワークの詳細
$ docker network inspect bridge

ディスク容量不足

# Docker のディスク使用量
$ docker system df -v

# クリーンアップ
$ docker system prune          # 停止コンテナ、未使用ネットワーク、ダングリングイメージ
$ docker system prune -a       # + 未使用イメージ全て
$ docker volume prune          # 未使用ボリューム
$ docker builder prune         # ビルドキャッシュ

パフォーマンスの問題

# リソース使用状況の確認
$ docker stats --no-stream

# コンテナ内のプロセス
$ docker top my-container

# ファイルシステムの変更確認
$ docker diff my-container

15. ベストプラクティスまとめ

イメージのビルド

  1. 軽量なベースイメージを使用する(Alpine、Distroless)
  2. マルチステージビルドでイメージサイズを最小化する
  3. .dockerignore を活用してビルドコンテキストを制限する
  4. レイヤーキャッシュを意識した命令順序にする
  5. 固定バージョンのタグを使用する

セキュリティ

  1. 非 root ユーザーでコンテナを実行する
  2. read-only ルートファイルシステムを使用する
  3. 必要最小限の capabilities のみ付与する
  4. イメージの脆弱性スキャンを CI/CD に組み込む
  5. シークレットは環境変数ではなく、Docker Secrets や外部管理を使う

運用

  1. ログドライバとローテーションを設定する
  2. ヘルスチェックを定義する
  3. リソース制限(メモリ、CPU)を設定する
  4. restart ポリシーを適切に設定する
  5. Docker Compose/Podman Compose で構成を管理する

Podman 固有

  1. ルートレスコンテナをデフォルトで使用する
  2. systemd (Quadlet) でコンテナのライフサイクルを管理する
  3. Pod を活用してコンテナをグループ化する
  4. podman generate kube で Kubernetes への移行パスを確保する

16. 参考文献


本ドキュメントは 2026年4月時点の情報に基づいています。最新の情報は各ソフトウェアの公式ドキュメントを参照してください。