CentOS 7に「Docker」をインストールしてDocker Swarm Modeを設定

**Docker Swarm**は、**Docker**コンテナのネイティブクラスタリングツールで、**Docker**ノードの**クラスタ**を1つの仮想システムとして管理することができます。
このチュートリアルでは、CentOS 7上で3ノードの**Docker Swarmクラスタ**を構成する方法をステップバイステップで説明します。

本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-install-and-configure-docker-swarm-mode-on-centos-7_583495)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

###必要条件
- CentOS 7をインストールした3台のAlibabaクラウドインスタンス。そのうち1台のサーバーがManagerノードとして動作し、2台のサーバーがWorkerノードとして動作します。
- すべてのインスタンスに固定IPアドレスを設定しています。ここでは、Managerノードに192.168.0.102、Workerノード1に192.168.0.103、Workerノード2に192.168.0.104のIPアドレスを使用します。

###アリババクラウドECSインスタンスの起動
まず、[https://ecs.console.aliyun.com/?spm=a3c0i.o25424en.a3.13.388d499ep38szx](https://account.alibabacloud.com/login/login.htm?spm=a2c65.11461447.0.0.2f151ac6U0eSN1&oauth_callback=)Alibaba Cloud ECS Consoleにログインします。新しい[ECSインスタンス]((https://www.alibabacloud.com/help/ja/doc-detail/25424.htm))を作成し、少なくとも2GBのRAMを搭載したオペレーティングシステムとしてCentOS 7を選択します。[ECSインスタンス](https://www.alibabacloud.com/help/ja/doc-detail/25424.htm)に接続し、rootユーザーとしてログインします。

CentOS 7インスタンスにログインしたら、以下のコマンドを実行して、ベースシステムを最新の利用可能なパッケージでアップデートします。

`yum update -y`

###はじめに
始める前に、各ノードがホスト名で通信できるように、各ノードの/etc/hostsファイルを設定しておく必要があります。

以下のように各ノードの/etc/hostsファイルを更新します。

```
nano /etc/hosts

192.168.0.102  managernode
192.168.0.103  workernode1
192.168.0.104  workernode2
```

保存して終了したらファイルを閉じます。

次に、/etc/hostsファイルの通りに各ノードのhostnameを設定する必要があります。

以下のコマンドを各ノードで1つずつ実行することで行うことができます。

**管理者ノード**

`hostnamectl set-hostname managernode`

**Worker node1**

`hostnamectl set-hostname workernode1`

**Worker node2**

`hostnamectl set-hostname workernode2`

###Dockerエンジンのインストール

次に、すべてのノードにDocker Community Editionをインストールする必要があります。デフォルトでは、最新版のDocker CEはCentOS 7のリポジトリにはありません。そのため、Docker CEのリポジトリをシステムに追加する必要があります。

これは以下のコマンドを全ノードで実行することで行うことができます。

`wget https://download.docker.com/linux/centos/docker-ce.repo - O /etc/yum.repos.d/docker.repo`

Dockerリポジトリをインストールしたら、以下のコマンドを実行してDocker CEをインストールします。

`yum install docker-ce -y`

次にDockerサービスを起動し、以下のコマンドで起動時に起動できるようにします。

```
systemctl start docker
systemctl enable docker
```

###ファイアウォールの設定
次に、スウォームクラスタが正常に動作するためには、ファイアウォール上のポート7946、4789、2376、2377、および80を開く必要があります。

すべてのノードで以下のコマンドを実行します。

```
firewall-cmd --permanent --add-port=2376/tcp
firewall-cmd --permanent --add-port=2377/tcp
firewall-cmd --permanent --add-port=7946/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=7946/udp
firewall-cmd --permanent --add-port=4789/udp
```

最後に、ファイアウォールとDockerサービスをリロードして、すべての変更を適用します。

```
firewall-cmd --reload
systemctl restart docker
```

### Swarmを作成する
次に、Managerノードで Swarmを初期化する必要があります。これはdocker swarm initコマンドを実行することで行うことができます。このコマンドを実行することで、ノードをManagerノードにしてIPをアドバタイズします。

`docker swarm init --advertise-addr 192.168.0.102`

以下のような出力が表示されるはずです。

```
Swarm initialized: current node (viwovkb0bk0kxlk98r78apopo) is now a manager.

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

    docker swarm join --token SWMTKN-1-3793hvb71g0a6ubkgq8zgk9w99hlusajtmj5aqr3n2wrhzzf8z-    1s38lymnir13hhso1qxt5pqru 192.168.0.102:2377

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

注: 上記の出力のトークンを覚えておいてください。これは、後でworkerノードをManagerノードに結合するために使用します。

Swarmクラスタの状態を確認するには、以下のコマンドを使用します。

`docker info`

出力します。

```
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: devicemapper
 Pool Name: docker-253:0-618740-pool
 Pool Blocksize: 65.54kB
 Base Device Size: 10.74GB
 Backing Filesystem: xfs
 Udev Sync Supported: true
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data loop file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 11.8MB
 Data Space Total: 107.4GB
 Data Space Available: 3.817GB
 Metadata Space Used: 581.6kB
 Metadata Space Total: 2.147GB
 Metadata Space Available: 2.147GB
 Thin Pool Minimum Free Space: 10.74GB
 Deferred Removal Enabled: true
 Deferred Deletion Enabled: true
 Deferred Deleted Device Count: 0
 Library Version: 1.02.140-RHEL7 (2017-05-03)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: active
 NodeID: viwovkb0bk0kxlk98r78apopo
 Is Manager: true
 ClusterID: ttauawqrc8mmd0feluhcr1b0d
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
  Force Rotate: 0
 Autolock Managers: false
 Root Rotation In Progress: false
 Node Address: 192.168.0.102
 Manager Addresses:
  192.168.0.102:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 89623f28b87a6004d4b785663257362d1658a729
runc version: b2567b37d7b75eb4cf325b77297b140ea686ce8f
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-693.11.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.102GiB
Name: centOS-7
ID: DN4N:BHHJ:6DJ7:SZPG:FJJC:XP6T:23R4:CESK:E5PO:SJ6B:BOST:HZQ5
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
```

また、以下のコマンドでクラスタ内のノードの一覧を確認することができます。

`docker node ls`

出力します。

```
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
viwovkb0bk0kxlk98r78apopo *   centOS-7            Ready               Active              Leader
```

###Worker ノードを Manager ノードに結合する
これでManagerノードの準備は完了です。次に、WorkerノードをManagerノードに追加する必要があります。

以下のように両方のWorkerノードでdocker swarm joinコマンドを実行することで行うことができます。

`docker swarm join --token SWMTKN-1-3793hvb71g0a6ubkgq8zgk9w99hlusajtmj5aqr3n2wrhzzf8z-1s38lymnir13hhso1qxt5pqru 192.168.0.102:2377`

出力します。

`This node joined a swarm as a worker.`

Managerノードで、以下のコマンドを実行して、ノードがアクティブかどうか、ノードの状態を確認します。

`docker node ls`

すべてがうまくいった場合は、以下のような出力が表示されるはずです。

```
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
viwovkb0bk0kxlk98r78apopo *   managernode            Ready               Active              Leader
yf6nb2er69pydlp6drijdfmwd     workernode1            Ready               Active              
yyavdslji7ovmw5fd3v7l62g8     workernode2            Ready               Active              
```

いつでも参加トークンを失った場合。Managerノードで以下を実行することで取得できます。

`docker swarm join-token manager -q`

###Docker Swarmモードでサービスをデプロイする
Docker Swarmクラスタの準備が整いました。いよいよSwarm Modeでサービスをデプロイします。ここでは、Docker Swarm Modeで3つのコンテナでWebサーバサービスをデプロイします。

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

`docker service create -p 80:80 --name webservice --replicas 3 httpd`

出力します。

```
bky6uhg2agdxeqgc2b1a5tcsm
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 
```

上記のコマンドでwebserviceという名前のサービスを作成し、dockerイメージのhttpdからコンテナを起動します。

ここで、以下のコマンドでサービスの状態を一覧表示して確認することができます。

`docker service ls`

出力します。

```
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
bky6uhg2agdx        webservice          replicated          3/3                 httpd:latest        *:80->80/tcp

docker service ps webservice
```

出力します。

```
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE       ERROR           PORTS
xsa5wb0eg2ln        webservice.1        httpd:latest        managernode            Running             Running about a minute ago                                       
3sbscs7m9lnh        webservice.2        httpd:latest        workernode2            Running             Running about a minute ago                                      
yao2m5wi54kz        webservice.3        httpd:latest        workernode2            Running             Running about a minute ago                                 
```

ApacheのWebサービスは3つのノードに分散されていますので、以下のように好きなWebブラウザを使ってWorkerノードとManagerノードのいずれかにアクセスすることで、Webサーバにアクセスすることができます。

http://192.168.0.102
http://192.168.0.103
http://192.168.0.104

###コンテナのセルフヒーリング
docker スウォームモードの重要な機能の一つに、コンテナの自己修復があります。コンテナがダウンした場合、同じノードでも別のノードでも自動的に再起動されます。

コンテナのセルフヒーリング機能をテストするために、workernode2からコンテナを外して、新しいコンテナが起動するかどうかを見てみましょう。

始める前に、コンテナを削除するにはコンテナIDが必要です。Workernode2上で以下のコマンドを実行することでコンテナIDをリストアウトすることができます。

`docker ps`

出力します。

```
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
0dfc71537e18        httpd:latest        "httpd-foreground"   9 minutes ago       Up 9 minutes        80/tcp              webservice.3.yao2m5wi54kzs7iskefupuq6a
9b01b0a55cb7        httpd:latest        "httpd-foreground"   9 minutes ago       Up 9 minutes        80/tcp              webservice.1.xsa5wb0eg2ln5bud1sbjf9e9e
```

では、以下のコマンドを実行してID 9b01b0a55cb7のコンテナを削除します。

`docker rm 9b01b0a55cb7 -f`

ここで、Service from Managerノードを確認し、新しいコンテナが起動されているかどうかを確認します。

`docker service ps webservice`

下図のように、1つのコンテナが失敗し、別のコンテナがworkernode2上で起動していることがわかるはずです。

```
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE              ERROR                              PORTS
z1spatkk1jj7        webservice.1        httpd:latest        workernode2            Running             Preparing 29 seconds ago                                      
xsa5wb0eg2ln         \_ webservice.1    httpd:latest        workernode2            Shutdown            Failed 30 seconds ago      "task: non-zero exit (137)"        
```

また、要件に応じてコンテナをスケールアップしたり、スケールダウンしたりすることもできます。例えば、Managerノードで以下のコマンドを使用して、Webサービスのコンテナを3から5にスケールアップすることができます。

`docker service create -p 80:80 --name webservice --replicas 5 httpd`

Managerノードで以下のコマンドを実行することで、Webサービスの状態を確認できます。

`docker service ps webservice`

出力します。

```
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE       ERROR           PORTS
xsa5wb0eg2ln        webservice.1        httpd:latest        managernode            Running             Running about 10 minutes ago                                       
3sbscs7m9lnh        webservice.2        httpd:latest        workernode2            Running             Running about 10 minutes ago                                      
yao2m5wi54kz        webservice.3        httpd:latest        workernode2            Running             Running about 10 minutes ago                                 
dfg2mswa52sf        webservice.4        httpd:latest        workernode1            Running             Running about 15 seconds ago                                 
kah1j5hs14as        webservice.5        httpd:latest        workernode1            Running             Running about 15 seconds ago                                 
```

上記の出力では、workernode1で2つの新しいインスタンスが起動されていることがわかります。

###サーバーの保護
Dockerノードのクラスタをセットアップした後は、セキュリティの追加レイヤーを提供することでサーバを保護することをお勧めします。監視機能とファイアウォール機能の両方を備えたセキュリティソリューションを導入するのが良いでしょう。

Alibaba Cloud [Web Application Firewall](https://www.alibabacloud.com/ja/product/waf)（WAF）は、SQLインジェクション、クロスサイトスクリプティング（XSS）、悪意のあるボット、コマンド実行の脆弱性、その他の一般的なWeb攻撃を含むWebベースの攻撃からの保護を提供するために使用することができます。WAFは、多数の悪意のあるアクセス試行をフィルタリングし、サーバー上のハイパーテキスト転送プロトコル（HTTP）/HTTPセキュア（HTTPS）フラッド攻撃によるパフォーマンスへの影響を緩和します。

Alibaba Cloudの[CloudMonitor](https://www.alibabacloud.com/ja/product/cloud-monitor)を使用して、お客様のクラウド展開の詳細な洞察を提供することができます。CloudMonitorは、中央処理装置（CPU）の使用率やレイテンシなどの重要な指標について高度な分析を提供し、ビジネス要件に応じてパラメータをカスタマイズすることもできます。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*