LoginSignup
4
5

More than 5 years have passed since last update.

DockerのSwarmモードでクラスタを構築するメモ

Last updated at Posted at 2018-06-06

以前にDocekrをクラスタ管理するためにDocker Swarmを使ってオーケストレーションしてみたことが過去あったのですが、Docker Swarmを使った構築は、ConsulなどのKVSを別途用意したり大変だったりで、クラスタ構築が大変だったのですが、

最近はSwarmモードというのが追加されているらしく、結構簡単にできるとのことだったので、ホントに簡単にSwarmモードなるものでクラスタを簡単構築できるか調査してみました。
以下は、その時のメモになります。

ちなみに、現在では「Docker Swarm」というと、一般的にはSwarmモードのことを指すらしいです。

クラスタ環境の構成

  • Managerノード
    • 仮想マシンのホスト名: manager1, manager2
    • CentOS7
  • Workerノード
    • 仮想マシンのホスト名: worker1, worker2
    • CentOS7 ## 仮想マシンの準備とDockerのインストール

Vagrantfileをこんな感じで用意しておきました。

IPアドレスやらホスト名やらはお好みで。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # Managerサーバ#1
  config.vm.define "manager1" do |node|
    node.vm.provider "virtualbox" do |vm|
      vm.name = "manager1"
      vm.customize ["modifyvm", :id, "--memory", "512"]
    end
    node.vm.box = "centos/7"
    node.vm.hostname = "manager1"
    node.vm.network "private_network", ip: "192.168.33.41"
  end

  # Managerサーバ#2 (あとでクラスタを追加したいために用意)
  config.vm.define "manager2" do |node|
    node.vm.provider "virtualbox" do |vm|
      vm.name = "manager2"
      vm.customize ["modifyvm", :id, "--memory", "512"]
    end
    node.vm.box = "centos/7"
    node.vm.hostname = "manager2"
    node.vm.network "private_network", ip: "192.168.33.42"
  end

  # Workerサーバ#1
  config.vm.define "worker1" do |node|
    node.vm.provider "virtualbox" do |vm|
      vm.name = "worker1"
      vm.customize ["modifyvm", :id, "--memory", "512"]
    end
    node.vm.box = "centos/7"
    node.vm.hostname = "worker1"
    node.vm.network "private_network", ip: "192.168.33.51"
  end

  # Workerサーバ#2
  config.vm.define "worker2" do |node|
    node.vm.provider "virtualbox" do |vm|
      vm.name = "worker2"
      vm.customize ["modifyvm", :id, "--memory", "512"]
    end
    node.vm.box = "centos/7"
    node.vm.hostname = "worker2"
    node.vm.network "private_network", ip: "192.168.33.52"
  end

end

仮想マシンを起動

$ vagrant up
$ vagrant ssh-config >> ~/.ssh/config

Docker CEのインストール

コミュニティエディションでインストールします。
Managerサーバ、Workerサーバで以下のコマンドを実行してインストールします。

$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

$ sudo yum install -y docker-ce

バージョンでも確認しておきます。

$ docker -v

Docker version 18.03.1-ce, build 9ee9f40

Dockerの起動

Managerサーバ、Workerサーバで以下のコマンドを実行して起動します。

$ sudo systemctl start docker
$ sudo systemctl enable docker

ここまででインストール完了したので、
次はSwarmでクラスタを構築します。

Docker Swarmでクラスタを構築

クラスタの初期化

$ sudo docker swarm init --advertise-addr 192.168.33.41
Swarm initialized: current node (7i9tnczzu1usm5bijr532j7ou) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-4ieqe6ymrsxevbyo0875l8h20q54ma80lddvmrqwep0nib51dd-ele3qb3mxsioopz2fqcjteux3 192.168.33.41:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

上記に記載のコマンドによって、あとでワーカーノード(Worker#1, Worker#2)をクラスタに追加します。トークンは実行環境によって異なるので注意してください。

また、注意が必要ですが、マネージャノード(Manager#2)をクラスタに追加する際のトークンが異なります。

マネージャをクラスタに追加するためのトークンは以下のコマンドで確認できます。

$ sudo docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-4ieqe6ymrsxevbyo0875l8h20q54ma80lddvmrqwep0nib51dd-02ym4vkgpi7r895buzxne1sl3 192.168.33.41:2377
$ sudo docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
7i9tnczzu1usm5bijr532j7ou *   manager1            Ready               Active              Leader              18.03.1-ce

クラスタに追加

ワーカーノードをクラスタに追加

ワーカーノードをクラスタに追加します。

Worker#1, Worker#2で実行してください。

$ sudo docker swarm join --token SWMTKN-1-4ieqe6ymrsxevbyo0875l8h20q54ma80lddvmrqwep0nib51dd-ele3qb3mxsioopz2fqcjteux3 192.168.33.41:2377
This node joined a swarm as a worker.

マネジャーノードをクラスタに追加

今度は、Manager#2をマネジャノードとしてクラスタに追加します。
トークンがワーカーノードで実行した時のものと異なっていることに注意してください。

$ sudo docker swarm join --token SWMTKN-1-4ieqe6ymrsxevbyo0875l8h20q54ma80lddvmrqwep0nib51dd-02ym4vkgpi7r895buzxne1sl3 192.168.33.41:2377
This node joined a swarm as a manager.

クラスタ構築できたか確認する

クラスタのどこかのノードで実行して確認してください。
以下のようになっていればOKです。

[vagrant@manager1 ~]$ sudo docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
7i9tnczzu1usm5bijr532j7ou *   manager1            Ready               Active              Leader              18.03.1-ce
woryol5l22uwaw20cgkdeni8c     manager2            Ready               Active              Reachable           18.03.1-ce
y2ix3jsrefb46u4ibvhxzsvhz     worker1             Ready               Active                                  18.03.1-ce
gs5bzrxb76glo40wn92psl0f3     worker2             Ready               Active                                  18.03.1-ce

*がついているのノードがこのコマンドを実行しているノードです。

デプロイ

Alpine Linuxからdocker.comにpingを行うサービスを追加します。起動するコンテナ数は1つです。

$ sudo docker service create --replicas 1 --name helloworld alpine ping docker.com
rr5zwn0fyamykt79ihr08c5te
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged

起動しているサービス一覧にhelloworldが追加されている事を確認します。

$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
rr5zwn0fyamy        helloworld          replicated          1/1                 alpine:latest

サービス内(helloworld)でどのようなコンテナを実行しているかを確認するためには、以下のコマンド。

$ sudo docker service ps helloworld
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
wxjc7ttz1u3h        helloworld.1        alpine:latest       worker1             Running             Running about a minute ago

スケールアウト

サービスを1から5に変更します。

$ sudo docker service scale helloworld=5
helloworld scaled to 5
overall progress: 5 out of 5 tasks
1/5: running
2/5: running
3/5: running
4/5: running
5/5: running
verify: Service converged
$ sudo docker service ps helloworld
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
wxjc7ttz1u3h        helloworld.1        alpine:latest       worker1             Running             Running 4 minutes ago
2wiqq5ff537d        helloworld.2        alpine:latest       manager1            Running             Running about a minute ago
ah46fj4uwq5k        helloworld.3        alpine:latest       manager2            Running             Running about a minute ago
o6om7iyhtf5e        helloworld.4        alpine:latest       manager2            Running             Running about a minute ago
22ptlffc7bmd        helloworld.5        alpine:latest       worker2             Running             Running about a minute ago

備忘録

Docker Swarmは過半数のマネージャーを失うとタスクを評価できなくなり自動的に回復できなくなる。
そのため、マネージャーノードは奇数台で構築するのがよさそう。

用語

  • ノード
    • Swarm内に参加する Docker Engineインスタンス。
  • マネージャーノード
    • アプリケーションをswarmにデプロイするには、マネージャノード(manager node)にサービス定義を送信します。マネージャはワーカーノードへタスクと呼ばれる単位を送ります。
    • マネージャノードはswarmの期待状態(desired state)を維持するために、オーケストレーションと管理機能を処理。マネージャはオーケストレーションタスクを処理するため、単一のリーダーを選出(elect)する。
  • ワーカーノード
    • ワーカ・ノード(worker nodes) はマネージャ・ノードから送られてきたタスクの受信して処理する。
    • デフォルトでは、マネージャノードはワーカーノードも兼ねるが、マネージャのみのノード(manager-only node)としてもマネージャを設定可能。割り当てられたタスクの現在の状況をマネージャノードに伝えることによって、マネージャは期待状態を維持できます。
  • サービス
    • アプリケーションを作り上げるための様々なタスクを、どのように実行するかという定義
    • サービスの作成時に指定するのは、どのコンテナのイメージを使い、コンテナ内でどのようなコマンドを実行するか
    • 以下のサービスがある。
      • 複製サービス
        • 期待状態の指定に基づき、swarm マネージャがノード間に複製タスク(replica task)を指定した数だけ分散する
      • グローバル・サービス
        • 特定のタスクをクラスタ内の全ノード上で利用可能になるようにswarmが実行する。
  • タスク
    • Dockerコンテナを運び、コンテナ内でコマンドを実行する。swarmにおける最小スケジューリング単位です。
    • マネージャノードはワーカノードに対してタスクを割り当てる。割り当てる数はサービスのスケールで設定されたレプリカ数に応じる。
4
5
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
4
5