Docker Swarm

DevOpsコンテナDockerSwarmオーケストレーションクラスタリングサービス管理

DevOpsツール

Docker Swarm

概要

Docker Swarmは、Dockerネイティブのクラスタリング・オーケストレーションツールです。Dockerと統合されており、シンプルな設定でコンテナクラスターを構築可能で、学習コストが低いのが特徴です。

詳細

Docker Swarm(ドッカースウォーム)は、Dockerが開発したコンテナオーケストレーションプラットフォームです。2014年にDocker社によりリリースされ、2016年のDocker 1.12でDocker Engineに統合されました。複数のDockerホストを単一の仮想Dockerホストとして管理し、コンテナの配布、スケーリング、負荷分散、高可用性を実現します。Kubernetesに比べてシンプルで学習コストが低く、既存のDocker知識をそのまま活用可能。宣言的サービス定義、ローリングアップデート、セルフヒーリング、サービスディスカバリ、ロードバランシング機能を内蔵し、Docker Stackコマンドによりdocker-compose.yml形式での複雑なアプリケーションデプロイが可能です。暗号化されたクラスター通信、RBAC、Secrets管理等のセキュリティ機能も提供。小〜中規模環境やDocker環境からの移行、プロトタイピング、エッジコンピューティング等での利用に適しており、シンプルさを重視する場面でKubernetesの代替選択肢として活用されています。

メリット・デメリット

メリット

  • シンプル: Docker知識だけで容易にクラスター構築
  • ネイティブ統合: Docker Engineに統合済み
  • 学習コスト低: 既存Docker スキルをそのまま活用
  • Compose互換: docker-compose.yml形式での定義可能
  • 軽量: Kubernetesより少ないリソースで動作
  • セキュリティ: TLS暗号化とSecrets管理内蔵
  • 運用簡単: 複雑な設定ファイルや概念が少ない
  • 移行容易: 既存Docker環境からのスムーズな移行

デメリット

  • 機能制限: Kubernetesほどの高度なオーケストレーション機能なし
  • エコシステム: サードパーティツールやアドオンが少ない
  • スケーラビリティ: 大規模環境での制約
  • カスタマイズ: 高度なネットワーク・ストレージ設定が困難
  • 監視・ログ: 統合監視ソリューションが限定的
  • 開発速度: Kubernetesほど活発な開発でない
  • 企業サポート: エンタープライズ向けサポートが限定的
  • 永続化: StatefulSet相当の機能が限定的

主要リンク

書き方の例

Swarmクラスター初期化

# マネージャーノードでクラスター初期化
docker swarm init --advertise-addr 192.168.1.100

# 出力例からワーカー参加コマンドを確認
# To add a worker to this swarm, run the following command:
#     docker swarm join --token SWMTKN-1-xxx 192.168.1.100:2377

# ワーカーノードで実行
docker swarm join --token SWMTKN-1-xxx 192.168.1.100:2377

# マネージャー追加トークン取得
docker swarm join-token manager

# ノード確認
docker node ls
docker node inspect node-name

サービス作成・管理

# 基本サービス作成
docker service create --name web --replicas 3 -p 80:80 nginx:alpine

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

# アップデート
docker service update --image nginx:latest web

# ローリングアップデート設定
docker service update --update-parallelism 1 --update-delay 10s web

# サービス確認
docker service ls
docker service ps web
docker service inspect web

# サービス削除
docker service rm web

Docker Stack(Compose形式)

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      placement:
        constraints:
          - node.role == worker
    configs:
      - source: nginx_config
        target: /etc/nginx/nginx.conf
    secrets:
      - ssl_certificate
    networks:
      - frontend

  app:
    image: myapp:latest
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
    depends_on:
      - db
    networks:
      - frontend
      - backend

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.database == true
    secrets:
      - db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - backend

networks:
  frontend:
    driver: overlay
    attachable: true
  backend:
    driver: overlay

volumes:
  postgres_data:
    driver: local

configs:
  nginx_config:
    external: true

secrets:
  ssl_certificate:
    external: true
  db_password:
    external: true
# Stackデプロイ
docker stack deploy -c docker-compose.yml myapp

# Stack確認
docker stack ls
docker stack ps myapp
docker stack services myapp

# Stack削除
docker stack rm myapp

Secrets管理

# Secret作成
echo "my-secret-password" | docker secret create db_password -

# ファイルからSecret作成
docker secret create ssl_cert ssl_certificate.pem

# Secret一覧
docker secret ls

# サービスでSecret使用
docker service create \
  --name myapp \
  --secret db_password \
  --env POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
  postgres:13

# Secret削除
docker secret rm db_password

Config管理

# Config作成
docker config create nginx_config nginx.conf

# サービスでConfig使用
docker service create \
  --name web \
  --config source=nginx_config,target=/etc/nginx/nginx.conf \
  nginx:alpine

# Config一覧・削除
docker config ls
docker config rm nginx_config

ネットワーク管理

# Overlayネットワーク作成
docker network create --driver overlay --attachable mynetwork

# サービス作成時にネットワーク指定
docker service create --name web --network mynetwork nginx:alpine

# 実行中サービスのネットワーク更新
docker service update --network-add backend web
docker service update --network-rm frontend web

# ネットワーク情報確認
docker network ls
docker network inspect mynetwork

ヘルスチェック・制約

# docker-compose.yml でのヘルスチェック
version: '3.8'
services:
  web:
    image: nginx:alpine
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == worker
          - node.labels.zone == us-west-1
        preferences:
          - spread: node.labels.zone

ローリングアップデート詳細設定

# 段階的アップデート
docker service update \
  --image myapp:v2.0 \
  --update-parallelism 1 \
  --update-delay 30s \
  --update-monitor 60s \
  --update-failure-action rollback \
  --update-max-failure-ratio 0.1 \
  myapp

# ロールバック
docker service rollback myapp

# アップデート履歴確認
docker service ps myapp --no-trunc

クラスター管理

# ノード情報・ラベル管理
docker node update --label-add zone=us-west-1 node1
docker node update --label-add database=true node2
docker node update --availability drain node3  # メンテナンスモード

# クラスター離脱
docker swarm leave --force  # マネージャーノード
docker swarm leave          # ワーカーノード

# 証明書更新
docker swarm ca --rotate
docker swarm unlock-key

# バックアップ
sudo systemctl stop docker
sudo tar -zvcf swarm-backup.tar.gz /var/lib/docker/swarm
sudo systemctl start docker

モニタリング・ログ

# サービスログ
docker service logs -f web
docker service logs --tail 100 web

# ノード・クラスター情報
docker system df
docker system events
docker node ps $(docker node ls -q)

# リソース使用状況(要・外部ツール)
docker stats $(docker ps --format "table {{.Names}}")