Ubuntu 16.04サーバでマルチノードKubernetesクラスタを設定する方法 

このチュートリアルでは、**Alibaba Cloud Elastic Compute Service (ECS)**を使用して**Ubuntu** 16.04サーバ上にマルチノード**Kubernetes** Clusterを設定します。

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

###前提条件
- 2つの新鮮なAlibaba Cloud [Elastic Compute Service (ECS)](https://www.alibabacloud.com/ja/product/ecs)インスタンスにUbuntu 16.04サーバがインストールされています。
- 1つ目のインスタンス（マスター）には192.168.0.103の静的IPアドレスが、2つ目のインスタンス（スレーブ）には192.168.0.104の静的IPアドレスが設定されています。
- インスタンスごとに最低2GBのRAMを使用しています。
- 各インスタンスにRootパスワードが設定されています。

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

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

`apt-get update -y`

###ECS サーバーの設定
始める前に、各サーバーでhostsファイルとホスト名を設定し、各サーバーがホスト名を使って通信できるようにする必要があります。

まず、最初のサーバで/etc/hostsファイルを開きます。

`nano /etc/hosts`

以下の行を追加します。

```
192.168.0.103 master-node
192.168.0.104 slave-node
```

保存して終了したらファイルを閉じ、以下のコマンドを実行してhostnameを設定します。

`hostnamectl set-hostname master-node`

次に、2台目のサーバーの /etc/hosts ファイルを開きます。

`nano /etc/hosts`

以下の行を追加します。

```
192.168.0.103 master-node
192.168.0.104 slave-node
```

終了したらファイルを保存して閉じ、以下のコマンドを実行してホスト名を設定します。

`hostnamectl set-hostname slave-node `

次に、各サーバのスワップメモリを無効にする必要があります。なぜなら、kubelets はスワップメモリをサポートしていないので、スワップが有効になっていたり、/etc/fstab ファイルにスワップが存在していたりすると動作しないからです。

以下のコマンドでスワップメモリの使用を無効にすることができます。

`swapoff -a`

etc/fstab のスワップファイルをコメントアウトすることで永久的に無効にすることができます。

`nano /etc/fstab`

下記のようにスワップラインをコメントアウトしてください。

```
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda4 during installation
UUID=6f612675-026a-4d52-9d02-547030ff8a7e /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda6 during installation
#UUID=46ee415b-4afa-4134-9821-c4e4c275e264 none            swap    sw              0       0
/dev/sda5 /Data               ext4   defaults  0 0
```

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

###Dockerのインストール
始める前に、マスターサーバーとスレーブサーバーの両方にDockerをインストールする必要があります。デフォルトでは、Ubuntu 16.04のリポジトリには最新版のDockerがないため、Dockerのリポジトリを追加する必要があります。

まず、以下のコマンドでDockerリポジトリを追加するために必要なパッケージをインストールします。

`apt-get install apt-transport-https ca-certificates curl software-properties-common -y`

次に、以下のコマンドでDockerのGPGキーをダウンロードして追加します。

`curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -.`

次に、以下のコマンドでDockerリポジトリを追加します。

`add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”`

次に、リポジトリを更新し、以下のコマンドでDockerをインストールします。

```
apt-get update -y
apt-get install docker-ce -y
```

###Kubernetesのインストール
次に、両方のサーバーにkubeadm、kubectl、kubeletをインストールする必要があります。まず、以下のコマンドでキーをダウンロードしてGPGキーを追加します。

`curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - - -` でダウンロードします。

次に、以下のコマンドでKubernetesリポジトリを追加します。

`echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list`

最後にリポジトリを更新し、以下のコマンドでKubernetesをインストールします。

```
apt-get update -y
apt-get install kubelet kubeadm kubectl -y
```

#マスターノードの設定
必要なパッケージはすべて両サーバにインストールされています。それでは、Kubernetes Master Nodeを設定しましょう。

まず、以下のコマンドでプライベートIPアドレスを使用してクラスタを初期化します。

`kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertis-address=192.168.0.103`

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

```
Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

kubeadm join --token 62b281.f819128770e900a3 192.168.0.103:6443 --discovery-token-ca-cert-hash sha256:68ce767b188860676e6952fdeddd4e9fd45ab141a3d6d50c02505fa0d4d44686
```

注：上記の出力からトークンをメモしておきます。これは次のステップでスレーブノードをマスターノードに結合するために使用します。

次に、以下のコマンドを実行してkubectlツールの設定を行います。

```
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
```

次に、以下のコマンドを実行してマスターノードの状態を確認します。

`kubectl get nodes`

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

```
NAME          STATUS     ROLES     AGE       VERSION
master-node   NotReady   master    14m       v1.9.4
```

上記の出力では、マスターノードが準備ができていないと表示されていることがわかるはずです。クラスタには CNI (Container Networking Interface) がないためです。

以下のコマンドでマスターノードにCalico CNIをデプロイしてみましょう。

`kubectl apply -f https://docs.projectcalico.org/v2.6/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml`

以下のコマンドを実行して、Calicoが正しくデプロイされたことを確認します。

`kubectl get pods --all-namespaces`

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

```
NAMESPACE     NAME                                      READY     STATUS              RESTARTS   AGE
kube-system   calico-etcd-p2gbx                         0/1       ContainerCreating   0          35s
kube-system   calico-kube-controllers-d554689d5-v5lb6   0/1       Pending             0          34s
kube-system   calico-node-667j2                         0/2       ContainerCreating   0          35s
kube-system   etcd-master-node                          1/1       Running             0          15m
kube-system   kube-apiserver-master-node                1/1       Running             0          15m
kube-system   kube-controller-manager-master-node       1/1       Running             0          15m
kube-system   kube-dns-6f4fd4bdf-7rl74                  0/3       Pending             0          15m
kube-system   kube-proxy-hqb98                          1/1       Running             0          15m
kube-system   kube-scheduler-master-node                1/1       Running             0          15m
```

もう一度 kubectl get nodes コマンドを実行すると、マスターノードが Ready として表示されているのがわかるはずです。

`kubectl get nodes`

出力します。

```
NAME          STATUS    ROLES     AGE       VERSION
master-node   Ready     master    7m        v1.9.4
```

###Kubernetes Clusterにスレーブノードを追加する
次に、スレーブノードにログインしてクラスタに追加する必要があります。マスターノード初期化コマンドの出力にあるjoinコマンドを覚えておいて、以下のようにスレーブノードで発行します。

`kubeadm join --token 62b281.f819128770e900a3 192.168.0.103:644 --discovery-token-ca-cert-hash sha256:68ce767b188860676e6952fdeddd4e9fd45ab141a3d6d50c02505fa0d4d44686`

ノードが正常に結合されると、以下のような出力が表示されるはずです。

```
[discovery] Trying to connect to API Server "192.168.0.103:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.104:6443"
[discovery] Requesting info from "https://192.168.0.104:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.0.104:6443"
[discovery] Successfully established connection with API Server "192.168.0.103:6443"

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.
```

さて、マスターノードに戻り、kubectl get nodesコマンドを発行してスレーブノードの準備ができたことを確認します。

`kubectl get nodes`

出力します。

```
NAME          STATUS    ROLES     AGE       VERSION
master-node   Ready     master    35m       v1.9.4
slave-node    Ready     <none>    7m        v1.9.4
```

###Apache コンテナをクラスタにデプロイする
Kubernetes Clusterの準備ができましたので、Apacheコンテナをデプロイしましょう。

マスターノードで、以下のコマンドを実行してApacheデプロイメントを作成します。

`kubectl create deployment apache --image=apache`

出力します。

`デプロイメント「apache」が作成されました。`

以下のコマンドでデプロイメントを一覧表示することができます。

`kubectl get deployments`

出力します。

```
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
apache    1         1         1            0           16s
```

以下のコマンドでApacheのデプロイメントの詳細を見ることができます。

`kubectl describe deployment apache`

出力します。

```
Name:                   apache
Namespace:              default
CreationTimestamp:      Mon, 19 Mar 2018 19:04:03 +0530
Labels:                 app=apache
Annotations:            deployment.kubernetes.io/revision=1
Selector:               app=apache
Replicas:               1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=apache
  Containers:
   apache:
    Image:        apache
    Port:         <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   apache-5fcc8cd4bf (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  43s   deployment-controller  Scaled up replica set apache-5fcc8cd4bf to 1
```

次に、コマンドでApacheコンテナをネットワークで利用できるようにする必要があります。

`kubectl create service nodeport apache --tcp=80:80`

次に、以下のコマンドを実行して、現在のサービスをリストアウトします。

`kubectl get svc`

30267番ポートが割り当てられたApacheサービスが表示されているはずです。

```
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
apache       NodePort    10.107.95.29   <none>        80:30267/TCP   15s
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        37m
```

今、あなたのウェブブラウザを開き、URL [http://192.168.0.104:30267](http://192.168.0.104:30267/?spm=a2c65.11461447.0.0.2305cf0doK4hOa) (Slave Node IP)を入力してください、あなたはデフォルトのApacheウェルカムページが表示されるはずです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b2e22d87-5f38-dae3-de10-60c8c705a8c1.png)

おめでとうございます。お使いのApacheコンテナがKubernetes Clusterにデプロイされました。

###関連するアリババクラウド製品
Kubernetes Clusterを完成させた後、それを本番用にスケールすることは完璧に理にかなっています。これがコンテナを使用する設計コンセプト全体です。そのためには、アプリケーション用のデータベースをセットアップする必要があります。理想的には、本番環境では、自分でデータベースを作ることはお勧めしません。代わりに、Alibaba Cloudのデータベース製品群のいずれかを選択することができます。

[ApsaraDB for Redis](https://www.alibabacloud.com/ja/product/apsaradb-for-redis)は、開発者が複数のプロセス、アプリケーション、またはサーバーにまたがって共有されるデータストレージを管理するための自動化されたスケーラブルなツールです。

Redisプロトコルと互換性のあるツールとして、ApsaraDB for Redisは、卓越した読み書き機能を提供し、メモリとハードディスクストレージを使用してデータの永続性を確保します。ApsaraDB for Redisは、インメモリキャッシュからデータを取得することで高速なデータの読み書き機能を提供し、メモリとハードディスクの両方のストレージモードを使用することでデータの永続性を確保します。

[Data Transmission Service（DTS）](https://www.alibabacloud.com/ja/product/data-transmission-service)は、リレーショナルデータベース、NoSQL、OLAPなどのデータストレージタイプ間のデータ移行を支援します。このサービスは、異なるデータストレージタイプ間の均質な移行だけでなく、異質な移行もサポートしています。

また、DTSは高可用性を備えた継続的なデータレプリケーションにも利用できます。さらに、DTSを利用することで、ApsaraDB for RDSの変更データ機能の加入を支援することができます。DTSを利用することで、データ移行、リモートリアルタイムデータバックアップ、リアルタイムデータ統合、キャッシュリフレッシュなどのシナリオを簡単に実装することができます。

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