Kubernetes on Amazon EC2 環境構築編 ~新人がやってみた(1)~

このシリーズは、入社1年目の新人がEC2上にKubernetes環境構築を色々試行錯誤して、上手くいった手順をまとめたものです。



#はじめに
本シリーズは、EC2上にKubernetesクラスターを構築する環境構築編(本記事)と
KubernetesクラスターにPodやServiceなど5つのリソースを作成するリソース作成編、
最後に、KubernetesクラスターにElasticSearchとKibanaを導入する運用監視編の三部構成になっています。

この記事ではEC2上にKubernetesクラスターを構築するまでの手順を書いてます。
リソース作成編や運用監視編の記事は、以下になります。

- Kubernetes on Amazon EC2 環境構築編　(本記事)：EC2上にKubernetesクラスターを構築するまでの手順を書いてます。
- [Kubernetes on Amazon EC2 リソース作成編(今後公開予定)]()：Kubernetesの5つのリソース(PodやServiceなど)を作成する手順を書いてます。
- [Kubernetes on Amazon EC2 運用監視編(今後公開予定)]()：Kubernetes環境にElasticSearchとKibanaを導入するまでの手順を書いてます。

※この記事は手順に焦点を当てているので、Kubernetesに関する用語の詳細な説明は省略しています。

https://kubernetes.io/ja/docs/home/

# 目次
[全体的な作業の流れ](#-全体的な作業の流れ)
[0.本記事で構築する環境について](#0-本記事で構築する環境について)
[1.Kubernetes on Amazon EC2環境構築に必要な事前準備](#1-kubernetes-on-amazon-ec2環境構築に必要な事前準備)
[2.Kubernetes on Amazon EC2環境構築](#2-kubernetes-on-amazon-ec2環境構築)

# 全体的な作業の流れ
この記事で行う作業の全体的な流れは、以下のようになってます。

1. EC2を3台起動させます。(Master1台、Worker2台)
2. 全ノードにDocker、kubelet、kubeadm、kubectlをインストールします。
3. Masterノードでkubeadmを初期化して、Masterノードの設定をします。
4. Workerノードをクラスターに追加します。

#0. 本記事で構築する環境について
本記事では、新人が勉強の目的で構築した手順を紹介するため、シンプルな構築になっています。
Masterノード1台、Workerノード2台で全3台構成のKubernetes環境を構築します。
コンテナランタイムはDockerを使用します。
![kubernetes on aws3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163626/6bd1d608-a461-30cf-8d3f-b953e53bce66.png)

使用したものは以下になります。

- docker-CE 19.03.6-ce
- Kubernetes v1.20.1
- Flannel v0.13.0-rc2

#1. Kubernetes on Amazon EC2環境構築に必要な事前準備
事前準備では、EC2インスタンスとセキュリティグループを作成します。

※EC2を作成する前に、VPCとパブリックサブネットを作成しておきます。

**1. EC2インスタンスを作成します。**
本記事ではAMIにAmazon Linux2を選択しています。
インスタンスタイプはt2.medium以上の性能を選択してください。
※Kubernetesを導入するのに、メモリ2GB以上、2CPU以上が必要なためです。
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

**2. MasterノードとWorkerノードで開くポートが異なるため、セキュリティグループを2つ作成します。**
Masterノードにアタッチするセキュリティグループは以下のように設定してください。

| ポート番号 | 用途 | アクセス許可元 |
| :---: | :---: | :---: |
| 6443/TCP | Kubernetes API | VPCのCIDR |
| 2379,2380/TCP | etcd server client API | VPCのCIDR |
| 10250/TCP | kubelet API | VPCのCIDR |
| 10251/TCP | kube-scheduler | VPCのCIDR |
| 10252/TCP | kube-controller-manager |  VPCのCIDR |

**3. Workerノードにアタッチするセキュリティグループは以下のように設定してください。**

| ポート番号 | 用途 | アクセス許可元 |
| :---: | :---: | :---: |
| 10250/TCP | kubelet API | VPCのCIDR |
| 30001-30003/TCP | Node Port Service | 自PCのIPアドレス |

#2. Kubernetes on Amazon EC2環境構築
本章では、大まかに以下の流れで環境構築をしていきます。
**1. 必要なモジュールをインストール(Dockerやkubeletなど)**
**2. kubeadmを使用して、Masterノードを構築**
**3. kubeadmを使用して、Workerノードを構築し、クラスターに追加**

>[事前準備](#1-事前準備)で作成したEC2インスタンスに接続します。
以下のように、接続するインスタンスを選択し、「接続」を押下することでEC2インスタンスに接続できます。
本記事ではEC2への接続に、AWS Systems Managerを使用しています。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163626/af9b0bd8-21f1-0991-87d4-629aaa06b7fc.png)

##2-1. (全ノード)Dockerのインストール
まず、全ノードにDockerをインストールします。
(1)デフォルトでインストールされているパッケージをアップデートします。

    $ sudo yum update -y

(2)amazon-linux-extrasコマンドを使用して、Dockerをインストールします。

    $ sudo amazon-linux-extras install -y docker

(3)インストールが終わったらDockerを起動し、EC2インスタンスを再起動しても、Dockerが自動で起動するように設定します。

    $ sudo systemctl start docker && sudo systemctl enable docker

##2-2. (全ノード)kubelet、kubeadm、kubectlのインストール
Kubernetes環境を構築するのに必要なモジュールをインストールします。
(1)kubelet、kubeadm、kubectlをインストールするためにレポジトリを作成します。

    $ sudo vi /etc/yum.repos.d/kubernetes.repo
```repo:/etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
```
(2)kubelet, kubeadm, kubectlをインストールします。

    $ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

※SELinuxが有効の場合、SELinuxを無効化してから上記コマンドを叩いてください。

    $ setenforce 0

(3)kubeletを起動させ、EC2インスタンスを再起動しても自動で起動するようにします。

    $ sudo systemctl enable kubelet && sudo systemctl start kubelet

##2-3. (Masterノード)kubeadm
kubeadmを初期化して、Masterノードの設定を行います。
この手順は、Masterノードのみで行ってください。

(1)kubeadmを初期化します。
実行結果の最後に、以下のような文が表示されるので、`kubeadm join ~`の一文をコピーしておきます。
(後で、Workerノードをクラスターに追加するときに使用します。)

    $ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
      (省略)
      Then you can join any number of worker nodes by running the following on each as root:
      kubeadm join MaserノードのプライベートIPアドレス:6443 --token トークン番号 --discovery-token-ca-cert-hash sha256:XXXXXXXXXX

(2)非rootユーザがkubectlコマンドを実行できるように、以下のコマンドを叩きます。

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

(3)flannelをデプロイします。
※falnnelとは、Kubernetesクラスターのネットワークモデルを構築するプラグインの1つです。

https://github.com/flannel-io/flannel#flannel

    $ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

(4)STATUSがReadyになっていることを確認してください。

    $ kubectl get nodes
      NAME      STATUS   ROLES                   AGE    VERSION
      master    Ready    control-plane,master    5m     v1.20.1

##2-4. (Workerノード)クラスターにWorkerノードを追加
kubeadmを使用して、WorkerノードをKubernetesクラスターに追加します。
この手順は、クラスターに追加する全Workerノードで行ってください。

(1)[kubeadmの初期化](#2-3-masterノードkubeadm)の(1)でコピーしておいた`kubeadm join ~`の一文をペーストし、root権限で実行します。

    $ sudo kubeadm join MasterノードのプライベートIPアドレス:6443 --token トークン番号 --discovery-token-ca-cert-hash sha256:XXXXXXXXXX

(2)Workerノードがクラスターに追加されたことを確認します。

    $ kubectl get nodes
    NAME      STATUS   ROLES                    AGE   VERSION
    master    Ready    control-plane,master     14m   v1.20.1
    worker1   Ready    <none>                   11m   v1.20.1
    worker2   Ready    <none>                   11m   v1.20.1


これで、Kubernetesクラスターの構築が完了です。
次は、構築したKubernetesクラスター上にpodやserviceを作成していきます。
[Kubernetes on Amazon EC2 リソース作成編(今後公開予定)]()

#あとがき
なぜEC2上にKubernetes環境を構築したのかというと、新人研修後にAWS、コンテナ技術などを勉強していると、先輩に「AWS上にKubernetes環境を構築したら、AWSとKubernetesの勉強が一緒にできるね」とアドバイスを頂き、やってみたという流れです。

AWSもKubernetesも分からなかった当時の私には、EC2の作成やクラスターの構築方法が分からず困りました。
その中でも特に苦労したのは、EC2のセキュリティグループの設定でした。
セキュリティグループで設定しなければいけないポートがどこなのかが分からず、大変でした。

-------------------------------------------

※商標類について：
- Amazon Web Services、“Powered by Amazon Web Services”ロゴ、［およびかかる資料で使用されるその他のAWS商標］は、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。
- DockerおよびDockerロゴは、Docker Inc. の米国およびその他の国における登録商標もしくは商標です。
- KubernetesおよびKubernetesロゴは、The Linux Foundationの米国およびその他の国における登録商標または商標です。
- その他記載されている会社名、製品名はそれぞれ各社の商標および登録商標です。