海外の格安VPSでk8sクラスタを構築してみた

k8s何もわかりません。はやく完全に理解したいです。

ところで、k8sの勉強のためにk8sクラスタが必要ですよね。おうちにはNUCがあるので早くおうちクラスタを整備しようと思っていたのですが、これがかなり面倒でした。なので、今回は雑に海外VPSを使って建ててみることにしました。

※内容自体ははてなブログ([これ](https://musaprg.hatenablog.com/entry/2019/12/06/041224)）と同じものです

# Time4VPSとは

↓ここからTime4VPSに登録すると僕の実験費用を支援できるのでよろしくお願いします（？）
[Time4VPS - VPS Hosting in Europe](https://www.time4vps.eu/?affid=2048)

海外の格安VPSはいくつかあるのですが、今回は「Time4VPS」というものを選択しました。

Time4VPSは、ヨーロッパを中心に展開している企業で、リトアニアに拠点を置いています。データセンターもリトアニアにあります。メインとしているのはVPSのホスティングサービスで、VPNとかも提供しています。

Time4VPSの売りはなんといってもランニングコストの低さです。

以下は、日本の主要なVPSとの価格比較の表です。スペックは各社まちまちなので単純に比較できませんが、ここではTime4VPSの一番安価なプラン（RAMが2GB）と同容量のメモリを提供するプランを選択して比較しています。

||Time4VPS|ConoHa|さくらのVPS|
|---|---|---|---|
|プラン|Linux2|2GBプラン|2GBプラン|
|vCPU|1 x 2.6GHz(Intel® Xeon® Gold 6132)|3 x ?GHz(?)|3 x ?GHz(?)|
|RAM|2GB|2GB|2GB|
|ストレージ|20GB(HDD or SSD)|50GB(SSD)|100GB(SSD)|
|通信量（external）|2TB(100Mbps)[^1]|無制限(100Mbps)|無制限(100Mbps)|
|価格（月あたり）|3.99EUR(だいたい480円)|1,750円|1,580円（石狩DC）|

[^1]: 超過すると翌月まで10Mbpsになる

ソースにしたのはそれぞれ以下のページ。

https://www.time4vps.com/linux-vps/

https://www.conoha.jp/vps/pricing/

https://vps.sakura.ad.jp/specification/

国内企業と比べてる時点で適切な比較になっていない気がしますが、これだけみると明らかにTime4VPSが安いです。単純に1/3くらいです。externalの通信量に制限があるとはいえ、本番環境ではない実験用途というのを加味すると許容範囲だと思います。

ちなみに、Time4VPSはこれでもかというほどよくキャンペーンを行っています。具体的には、以下の時期（やイベント）にキャンペーンが行われることが多いです。

- バレンタインデー
- イースター
- ワールドカップ等のスポーツ系イベント開催時期
- 夏
- ハロウィン
- ブラックフライデー
- サイバーマンデー
- クリスマス

キャンペーンを併用すると大抵の場合は半額になります。さらに1年まとめて契約すると17%引きになります。そんなに割引して大丈夫なのかという気持ちになるくらい頻繁にセールをやってます。

キャンペーンは、Time4VPSの公式Twitterが告知をしているので、見ておくといいかもしれません。

https://twitter.com/time4vps

# 構成

さて、今回の構成はこんな感じにしました。k8sについてはあまり詳しくないので、特に面白みのない、無難な構成です。

| | |
|---|---|
|Master Node|Linux16 x 1|
|Worker Node|Linux2 x 3|
|OS|Ubuntu 18.04 LTS|
|Deployment Tool|kubespray|
|Container Runtime|Docker|
|CNI|Calico|

なんでMasterだけLinux16か（正直MasterもLinux2でいい）というと、1年前に「自作アプリを公開するぞ」と調子乗って契約したまま無を貫いていた子を流用してるからです。Resource Utilization大事（？）

Master Nodeの契約が来年の6月くらいまでなので、契約切れたらMasterをランニングコストが低いやつに差し替える予定です。移行の過程でMulti Master構成が試せていいですね。

構築を[kubeadm](https://github.com/kubernetes/kubeadm)でやろうと意気込んでいたのですが詰むと困る（チキン）ので[kubespray](https://github.com/kubernetes-sigs/kubespray)を使いました。

CNIはFlannelとCalicoで悩んだのですが、Flannelの開発が最近あまりアクティブではないことからCalicoにしてみました。業界の標準もCalicoに寄せているような印象です。（これについてはあまり詳しくないので詳しい人にいろいろ聞きたいのですが）

# 構築

さて、さっそくやっていきたいと思います。

まずはkubesprayをcloneして、ansibleの設定を含んだフォルダをコピーします。

```
$ git clone https://github.com/kubernetes-sigs/kubespray
$ cd kubespray
$ cp -rfp inventory/sample inventory/mycluster
```

次にクラスタの構成をansibleの構成ファイル（`inventory/mycluster/inventory.ini`）に書き込みます。以下のような感じにしました。

```
node1 ansible_host=114.51.48.10
node2 ansible_host=114.51.48.11
node3 ansible_host=114.51.48.12
node4 ansible_host=114.51.48.13

[kube-master]
node1

[etcd]
node1
node2
node3

[kube-node]
node2
node3
node4

[calico-rr]

[k8s-cluster:children]
kube-master
kube-node
calico-rr
```

詳しいことは以下参照。

https://github.com/kubernetes-sigs/kubespray/blob/master/docs/ansible.md

`mycluster/group_vars`以下は必要に応じて修正してください。今回はいじりません。

いじる際はそれぞれ以下ファイルの中身を確認してみてください。

- その他全体に関すること: `inventory/mycluster/group_vars/all/all.yml`
- k8sクラスターに関する設定（CNI等）: `inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml`

ちなみに、初期設定だとkubectl用のconfigが出力されないので、以下を参考にgroup_varsを書き換えます。

https://medium.com/@leonardo.bueno/setting-up-a-kubernetes-cluster-with-kubespray-1bf4ce8ccd73

`inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml`の`kubeconfig_localhost`を`true`にすると出力されます。

その他に、2箇所ほど変更します。

- PVCを使えるように`local_volume_provisioner_enabled: true`にします
- Let's Encryptをのちのち使うかもしれないので`cert_manager_enabled: true`にします

以下コマンドを叩くとansibleのplaybookが実行されます。

```
$ ansible-playbook -i inventory/mycluster/hosts.yml cluster.yml -b -v --private-key=~/.ssh/private_key
```

というわけで、無事構築が終わりました。

# 動作確認

構築が正しくできているかkubectlから確認してみます。

kubectlはHomebrew経由で簡単にインストールできます。

```
$ brew install kubernetes-cli
```

Linux環境やWindows環境の方は公式ドキュメントを参照してください。

https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/

```
$ export KUBECONFIG=$PWD/kubespray/inventory/mycluster/artifacts/admin.conf
```

設定を確認できるか試してみます。

```
$ kubectl config view
```

確認ができたら、クラスタの情報を取得してみましょう。

```
$ kubectl cluster-info
```

以下コマンドでノードの状態を確認し、正常に立ち上がっていることを確認してください。

```
$ kubectl get nodes
```

ここまで正常に実行ができれば、ひとまずデプロイは成功しています。お疲れさまでした。

# やること

- ingress-nginx
- minio
- MetalLB
- cert-manager

あたりを導入するやつをやります。

PVを使えるようにしてあるので、kubevirtとかが動くかもやってみたいですね。

後はおうちクラスタとおうちネットワークを早急に作らなければ…

# 参考文献

- https://ladicle.com/post/k8s-home-cluster/