この記事は WESEEK Advent Calendar 2020 18日目の記事です。
こんにちは! WESEEK, Inc. で長期インターンをさせていただいております [yamagai] (https://twitter.com/yamagai_0919)と申します。
今回は、
「Kubernetesクラスタを構築したいものの、全てのクラウドサービスの無料クレジットを使い切ってしまった。。。」
「とはいえ GKE や EKS などのクラスタ運用に払えるほどお金はない。。。」
という苦学生のために、出来るだけお安くクラスタを構築する方法を書いてみようと思います!
(2021/01/10 追記) 「RKE2 のインストール」のインストールの章に 2. service から起動する方法
を加えました。
VPSを立てよう
安さとスペックのバランスを考えると結局VPSに辿り着きました。
今回はそのVPSの中でも圧倒的に安いと言われる TIME4VPS を使って構築していきます。
圧倒的な安さの TIME4VPS ですが、実は欠点があって、データセンターがリトアニアにあるため
$ ping 80.209.234.201
PING 80.209.234.201 (80.209.234.201): 56 data bytes
64 bytes from 80.209.234.201: icmp_seq=0 ttl=51 time=262.969 ms
64 bytes from 80.209.234.201: icmp_seq=1 ttl=51 time=283.641 ms
64 bytes from 80.209.234.201: icmp_seq=2 ttl=51 time=303.660 ms
RTT が 300ms 程度とだいぶ長めで、ターミナルの反応速度がちょっと遅いです。
(日本 - アメリカ西海岸だと 100ms 程度)
さて、スペックについてですが、クラスタ構築に使用するツールにもよりますが今回は以下のようにしました。
Linux VPS - Linux 4×2台(master1台, worker1台)
- OS: Ubuntu 20.04 (64-bit)
- Processor: 1 x 2.6 GHz
- Memory: 4096 MB
- Hard disk: 40 GB
- Bandwidth: 1000 Mbps (Monthly limit: 4 TB)
k3s や k0s など軽量なものを使う場合は Linux 2 で十分だと思います。(この場合、月々1000円です!!)
クラスタを構築しよう
クラスタを構築するのにどのツールを使うか迷ったのですが、今回は Rancher社の RKE2 を使ってみようと思います。
公式によると、RKE2 は k3s と RKE の良いとこ取りらしいです。
意図せず世間をざわつかせた kubernetes 1.20 の docker非推奨問題についても、こちらにある通り問題無いようです。
ちなみに、kubernetes 1.20 の docker非推奨問題については、以下の記事がとてもわかりやすかったです。
RKE2 のインストール
公式ドキュメント → https://docs.rke2.io/
事前準備
RKE を使うと、OS の設定や docker のインストールなどの事前準備が必要だったのですが、RKE2 では firewall の設定以外は不要でした。
それでは、firewall の設定をしていきましょう。
以下のポートを ufw を使って開けていくだけです。 master と worker 両方で行ってください!
(引用: https://docs.rke2.io/install/requirements/#networking)
ufw を有効化
$ sudo ufw enable
ポートを開けていく
$ sudo ufw allow 9345/tcp
これだけで事前準備は完了です!
ちなみに 22/tcp を開け忘れてログアウトすると ssh が出来なくなってしまうので忘れずに開けましょう。
もしやってしまった時はこちらの記事を参考にしてください!
インストール
基本的にドキュメント通りです。
そういえば、RKE では(というか k3s, k0s でも) masterノードのことを server
、workerノードのことを agent
と呼ぶので適宜読み替えてください。
- 直接 rke2 コマンドを叩く方法
- service から起動する方法(←オススメ)
- 準備(master, worker共に)
まずは curl -sfL https://get.rke2.io | sh -
で rke2 コマンドを打てるようにしましょう
1. 直接 rke2 コマンドを叩く方法(この次の「2.service から起動する方法」での構築をお勧めします)
master ノード起動
公式には、rke2 server
で server として起動させると書いていますが、こうするとシェルからログアウトした際にプロセスが kill されてしまい正常に動きません。
ですので、バックグラウンドかつログアウトしてもプロセスがkillされないように nohup
と &
を使って
$ nohup rke2 server &
としましょう。
自分は、起動時のログがみたかったので
$ nohup rke2 server > rke2-server-log.txt &
で別ファイルに書き出して、別タブで tail -f
してログを見ていました。
起動時のログを見ていると etcd や api-server のログで以下のエラーが出ましたが、
これは起動を待ってるだけで後から両方ともetcd data store connection OK
やKube API server is now running
と出て正常動作するのでご安心ください。
ERRO[0035] Failed to check local etcd status for learner management: context deadline exceeded
{"level":"warn","ts":"2020-12-13T08:39:05.726+0200","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"passthrough:///https://127.0.0.1:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: connection error: desc = \"transport: Error while dialing dial tcp 127.0.0.1:2379: connect: connection refused\""}
また、起動時のログ内に、以下のようにクラスタに agent を追加する際に必要な token の場所、 agent登録時のコマンド、kubeconfig の場所が載ってるので注意してください。
INFO[0000] Node token is available at /var/lib/rancher/rke2/server/token
INFO[0000] To join node to cluster: rke2 agent -s https://(serverノードのIP):9345 -t ${NODE_TOKEN}
INFO[0000] Wrote kubeconfig /etc/rancher/rke2/rke2.yaml
worker ノードをクラスタに追加
まずは/var/lib/rancher/rke2/server/token
に置いてあるNODE_TOKEN
をコピーしましょう。
次にノードを agent としてクラスタに参加させます。
その際、上記のログではrke2 agent -s https://(serverノードのIP):9345 -t ${NODE_TOKEN}
で worker として起動させると書いていますが、
これも master 側と同じくバックグラウンドかつログアウトしてもプロセスがkillされないように nohup
と &
を使って
$ nohup rke2 agent -s https://(serverノードのIP):9345 -t ${NODE_TOKEN} &
としましょう。
2. service から起動する方法
後になって気付いたのですが、rke2 のインストール(curl -sfL https://get.rke2.io | sh -
)により service に rke2-server
と rke2-agent
が登録されます。
これを使って起動していきましょう。
master ノード起動
rke2-server
サービスの自動起動を有効化
$ systemctl enable rke2-server.service
rke2-server
サービスを起動
$ systemctl start rke2-server.service
rke2-server
サービスのログを追うなら
$ journalctl -u rke2-server -f
worker ノードをクラスタに追加
rke2-agent
サービスの自動起動を有効化
$ systemctl enable rke2-agent.service
server ノードを識別するためのrke2-agent
サービスの設定
# 設定用のファイルを作成
$ mkdir -p /etc/rancher/rke2/
$ vim /etc/rancher/rke2/config.yaml
# 作成した config.yaml に設定を記入
server: https://(serverノードのIP):9345
token: (NODE_TOKEN)
rke2-agent
サービスを起動
$ systemctl start rke2-agent.service
rke2-agent
サービスのログを追うなら
$ journalctl -u rke2-agent -f
これだけでクラスタは完成です!!!簡単ですね!!
kubectl を叩こう
/etc/rancher/rke2/rke2.yaml
を見て, ~/.kube/config
に追記しましょう。
クラスタの名前は密林をイメージしてjukai
にしました。ダサくてごめんなさい。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
23qa.l.time4vps.cloud Ready <none> 4d21h v1.18.12+rke2r1
23qb.l.time4vps.cloud Ready etcd,master 4d21h v1.18.12+rke2r1
無事、クラスタとして動いていますね。感無量です。
アプリを立ててみる
アプリの helm chart をデプロイしてみる
こちらの記事で GitOps を導入している対象のalcatraz
という自作アプリをデプロイしてみましょう。
使用するマニフェストリポジトリは以下です。Helm で管理しています。
さて、デプロイですが、RKE2 では helm を使用する際も特に設定は不要です。
カスタマイズする時はこちら→ https://docs.rke2.io/helm/
今回使う helm のバージョンは以下の通り。
(⎈ |jukai:alcatraz)❯ helm version
version.BuildInfo{Version:"v3.3.4", GitCommit:"a61ce5633af99708171414353ed49547cf05013d", GitTreeState:"clean", GoVersion:"go1.14.9"}
DB デプロイ
~/bamboooo/alcatraz-manifests main
(⎈ |jukai:alcatraz)❯ helm install alcatraz-db ./alcatraz-db
API デプロイ
~/bamboooo/alcatraz-manifests main
(⎈ |jukai:alcatraz)❯ helm install alcatraz-api ./alcatraz-api
UI デプロイ
~/bamboooo/alcatraz-manifests main
(⎈ |jukai:alcatraz)❯ helm install alcatraz-ui ./alcatraz-ui
ingress 設定
RKE2 では nginx-ingress
が kube-system namespace に rke2-nginx-ingress
という名前でデフォルトで入っており、使い方は nginx-ingress
と同じになります。
詳しくは 公式 を参照してください。
~/bamboooo/alcatraz-manifests main
(⎈ |jukai:alcatraz)❯ kubectl apply -f ingress.yaml
IP がふられたか確認してみましょう。
(⎈ |jukai:alcatraz)❯ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ui <none> * 80.209.234.201 80 4d21h
おお〜いけてそう
ブラウザで確認
最後に
無事に TIME4VPS と RKE2 で簡単でお安くクラスタ構築出来ました!
「金かかんのかよ!」と思ったそこの苦学生たち、近々【完全無料】編も書くから待っておきなさい...
参考リンク
-
RKE2公式
-
kubernetes 1.20 の docker非推奨問題について
-
Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ
※この記事は WESEEK Tips wiki に 2020/12/18 に投稿された記事の転載です。
Tips wiki では、IT企業の技術的な情報やプロジェクトの情報を公開可能な範囲で公開しています。