Terraformを使って3ノードDocker Enterprise 2.1クラスタを構築する方法

この記事では、**Terraform**を使って3ノードの**Docker** Enterprise 2.1クラスタのビルドを完全に自動化する方法を紹介します。

#Dockerエンタープライズ版
[Docker Enterprise 2.1](https://docs.mirantis.com/docker-enterprise/v3.0/dockeree-products/index.html)は、セキュアなソフトウェアサプライチェーンを実現し、多様なアプリケーションをオンプレミスとクラウドの両方の異種インフラストラクチャ上で高可用性を実現するコンテナ・アズ・ア・サービス（CaaS）プラットフォームです。マルチテナントのLinux、Windows Server 2016、IBM Z環境にまたがるアプリケーションの構築とオーケストレーションを行うための、セキュアでスケーラブルでサポートされたコンテナ・プラットフォームです。

私がDockerについていつも気に入っていることの1つは、彼らのシンプルさと顧客中心主義です。今回のEnterprise 2.1のリリースでも、まさにそれが実現されました。Docker EE 2.1では、選択の自由が得られるようになりました。

- WindowsとLinuxの両方のコンテナを確実にサポートします。
- クラウドプラットフォームやオンプレミスのデータセンターでホストされている。
- Docker SwarmとKubernetesオーケストレーションの両方を互換的に使用できます。


レガシーアプリケーションをコンテナに移行するプロジェクトに着手しようとしている企業のお客様や、新しいアプリケーションの開発にDevOpsを積極的に取り入れたいと考えているお客様には、CaaSプラットフォームとしてDocker EE 2.1を強くお勧めします。

小規模から始めて、コンテナベースの成長に合わせてクラスタを拡張することができます。初期のオーケストレーションにはシンプルなDocker Swarmを利用し、必要に応じて後からKubernetesに切り替えることもできます。

Docker EE 2.1クラスタには、以下のようなコンポーネントも含まれています。

- Docker UCP - クラスタ全体に単一のガラス窓を提供します。
- Docker Trusted Registry - コンテナイメージを安全にホストします。
また、暗号化通信、アプリケーション分離、イメージの脆弱性スキャンなどのエンタープライズセキュリティ機能も備えています。

#Terraform
Terraformは私のお気に入りのオーケストレーション/IaCツールの一つだ。あらゆるパブリッククラウドプラットフォームに新しいサービスをデプロイするために、Terraformが提供するパワーと柔軟性が気に入っています。必要なものを定義して、Terraformに頼んで構築してもらうだけ。とてもシンプルです。

私はこの自動化のためにTerraformを選びました。どのクラウド・サービス・プロバイダーにも同じテンプレートを使うことはできませんが、特定のクラウド・プラットフォーム用に開発されたテンプレートは、別のプロバイダーにカスタマイズすることも簡単にできます。

[Terraformの詳細](https://www.alibabacloud.com/blog/Run-Bolt-with-Docker-and-Terraform-with-Alibaba-Cloud_452914?spm=a2c65.11461447.0.0.34ca49a5kExk0H)については、[HashiCorpのウェブサイト](https://www.terraform.io/?spm=a2c65.11461447.0.0.34ca49a5eka904)を参照するか、MVPであるAlberto Roura氏のTech Shareの記事を参照してほしい。

#Dockerエンタープライズクラスターの構築
今回のデモでは、小さな3ノードのDocker Enterprise 2.1クラスタを構築することにしました。

1.  Docker UCPとDocker Trusted Registry (DTR)の両方をホストするAlibaba Cloud [ECS Linuxサーバー](https://www.alibabacloud.com/ja/product/ecs)1台。同じノードをDocker Swarm ManagerとKubernetes Masterとしても構成します。
2.  UCPホストが作成したDocker Swarmにワーカーノードとして自動的に参加する1台のLinuxホスト。
3.  3. UCPホストが作成したDocker Swarmにワーカーノードとして自動的に参加するWindowsホスト1台。

クラスタ構築をすぐに始めたい場合は、私の[GitHubリポジトリ](https://github.com/sajiv3m/docker-terraform-alicloud?spm=a2c65.11461447.0.0.34ca49a5tPJ9Jr)にアクセスして指示に従ってください。

前提条件の準備ができれば、30分もかからずにクラスタを構築することができます。

#Terraformファイルの説明
行動に移す前にまずテンプレートを理解したいという方のために、以下のセクションではTerraformファイルの詳細を説明します。

私のGitHubリポジトリにある`Terraform`の設定ファイルや、`bash` & `powershell`スクリプトには十分なコメントがついているので、より理解しやすくなっています。この記事では、それらのテンプレートやスクリプトのそれぞれの目的を中心に説明したいと思います。

ご存知のように、Terraformは、ユーザーが必要なものを定義することで、HCL（High-level Configuration Language）を使用してインフラストラクチャのデプロイを支援します。Terraformは、この定義に基づいて詳細な実行計画を構築し、指定されたプラットフォーム上にインフラストラクチャをデプロイします。

Terraformは幅広い[クラウドサービスプロバイダ]()をサポートしており、[主要なクラウドプロバイダやVMWare vSphereをオンプレミス・データセンター]()向けにサポートしています。
`定義ファイルで指定することができますが、メンテナンスと読みやすさを考慮して、複数の.tfファイルに分割することをお勧めします。メインフォルダ内のすべての`.tf`ファイルは、`root`（メイン）モジュールの一部を形成します。

Terraformは、フォルダ内のすべての設定ファイル（`.tf`ファイル）をアルファベット順にロードします。設定ファイル内で定義されている変数、リソースなどの順番は関係ありません。Terraformの設定は宣言的なものなので、他のリソースや変数への参照は、定義された順番には関係ありません。

###変数
入力変数はTerraformモジュールのパラメータとして機能します。すべての変数は`.tf`ファイル（例：variables.tf）で宣言され、その値は実行中にコマンドラインで渡されるか、別の`.tfvars`ファイル（例：terraform.tfvars）で渡されなければなりません。

入力変数名には、ローカル変数や terraform リソース名を使って定義された terraform ローカル変数と区別できるように、大文字小文字を使用することをお勧めします。また、変数の値を別の `terraform.tfvars` ファイルに格納しておくと、アカウントの秘密鍵やパスワードなどが含まれている可能性があるため、他の人と共有する際にこのファイルを送信しないようにすることもできます。実行中に terraform が .tfvars ファイルを見つけられず、変数のデフォルト値が定義されていない場合は、ユーザーにプロンプトを表示します。

###プロバイダ
`provider.tf`
このファイルは、Alicloudに接続するためのキーと作成するリソースのリージョンを定義します。

###ネットワークとセキュリティ
`network-security.tf`
このファイルは、VPC、vSwitch、Security Group、セキュリティ/ファイアウォールルールを定義し、dockerホストへのアクセスを制限します。

このファイルで定義されたvSwitchとSecurityグループはECS (Elastic Compute Service)の定義でホストにマッピングされます。

いくつかの注意点があります。

- セキュリティロールの優先度は1～100の範囲です。値が小さいほど優先度が高くなります。
- RDP、WinRM、SSHアクセスは特定のIP、つまり自分のパブリックIPからのみ許可されます。
- Kubernetes、Docker、アプリケーションへのアクセスはどこからでも許可される


###Docker UCP Managerのための計算
`docker-host.tf`

このファイルはDocker UCPとDTRをインストールするメインホストを定義します。Docker UCPのインストールの一環として、他のホストがワーカーノードとして参加するDocker Swarmの作成を開始します。

いくつかの注意点があります。

-` internet_max_bandwidth_out`属性は、VM作成の一部としてPublic IPを確実に割り当てます。
- このPublic IPは、ファイルプロビジョナーがインストールスクリプトをコピーしたり、リモートexecプロビジョナーがDocker EE、UCP、DTRのセットアップを自動的に実行したりするための接続定義で使用されます。
- UCP ホストと linux ワーカーノードの `ssh key pair`は、`key-pair.tf `で定義されています。


#Docker Workerノードの計算
`linux-worker.TF`
このファイルはlinuxのワーカーノードを定義しています。docker-host.tfファイルとよく似ていますが、Docker EEをインストールしてワーカーノードとして参加するためのスクリプトのみが含まれています。

`windows-worker.tf`
このファイルはwindowsワーカーノードを定義しています。Linuxノードの定義との主な違いは以下の通りです。

- Linuxイメージの代わりにWindowsイメージを使用しています。
- ssh-keyペアにLinuxで使用されるkey_name属性の代わりにpassword属性を使用しています。
- ユーザーデータ属性は、WinRM の設定を含む VM のブートストラップに使用され、WinRM を使用してスクリプトを実行できるようにします。
- 接続タイプはLinuxホストで使用しているsshではなくwinRMです。

###出力
`output.tf`
このファイルは、モジュールが返す値を定義します。これらの値は、Terraformが正常に実行を完了すると出力されます。

`output.tf`に定義された値は、実行に成功した後、terraform outputコマンドを使用していつでも出力することができます。

Terraformの実行の詳細を取得するには、terraform showを使用します。

#Dockerコンポーネントのビルドを自動化するスクリプト
Linux ホストのブートストラップに使用されるスクリプトは lin-files フォルダにあります。これらはECS VM定義のremote-execプロビジョナーを使って呼び出されます。

これらのスクリプトは、DockerのWebサイトのドキュメントに従って、Docker Enterprise、Docker UCP、Docker Trusted Registryを設定するために使用します。

Windowsホストをブートストラップするために使用されるスクリプトは、win-filesフォルダにあります。これらはECS VM定義のremote-execプロビジョナーを使って呼び出されます。

これらのスクリプトはDocker Enterpriseのセットアップや、ワーカーノードとして参加する際に使用します。Docker UCPとDocker Trusted RegistryはWindowsホストにはインストールできません。ワーカーノードにしかなれません。

Windowsスクリプトの注意点

Docker APIへのアクセス時にInvoke-RestMethodが正常に動作するようにするために、Docker APIを呼び出す前にスクリプト内で以下の変更を行う必要がありました。

1、powershellのデフォルトTLSバージョンを1.0から1.2に変更する。
2、Docker APIへの接続時に証明書エラーを無視するようにした。

#結論
この記事は、Docker Enterpriseの基本的な概念と、Terraformを使ってAlibaba Cloudでのデプロイを自動化する方法を紹介することのみを目的としています。GitHubリポジトリにある定義ファイルとスクリプトは、基本的なDocker Enterpriseクラスタのセットアップに役立つだけでなく、他のインストールにも使えるヒントを提供してくれます。

以降の記事では、ロードバランサや追加ノードを使ってクラスタをスケールする方法や、Docker SwarmやKubernetesオーケストレーションを使ってコンテナをデプロイする方法の詳細を見ていきます。

#主な参考文献
このセクションでは、Docker、Terraform、Automationについて詳しく知りたい場合に役立つ参考文献をいくつか挙げています。

1.  Dockerエンタープライズ
[https://docs.docker.com/ee/](https://docs.mirantis.com/docker-enterprise/v3.0/dockeree-products/index.html)
[https://www.docker.com/products/docker-enterprise](https://www.mirantis.com/software/docker/docker-enterprise/?spm=a2c65.11461447.0.0.34ca49a5ATz9O9)

2.  テラフォーム
[https://www.terraform.io](https://www.terraform.io/?spm=a2c65.11461447.0.0.34ca49a5N9DQVI)
[https://www.terraform.io/docs/providers/alicloud/index.html](https://www.terraform.io/docs/providers/alicloud/index.html?spm=a2c65.11461447.0.0.34ca49a5pYYUbt)

3.  私のGitHubリポジトリ
[https://github.com/sajiv3m/docker-terraform-alicloud](https://github.com/sajiv3m/docker-terraform-alicloud?spm=a2c65.11461447.0.0.34ca49a5Swd0ic)

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