はじめに
私はいくつか個人でアプリを出しているんですが、それを VPS にいい感じにデプロイしたいなと思いました。
VPS とは、さくらのVPSや、ConoHaなど、サーバーを1台だけ貸してくれるようなサービスです。
めっちゃサクッとデプロイするなら、Heroku でいいんですが、Heroku は
- サーバーが海外にあって遅い
- バッチ処理を実行するのが面倒
- 凝ったことをやると割高
といった欠点があると思っています。
そこで、Kubernetes の勉強も兼ねて、VPS で Kubernetes クラスタを構築してみることにしました。
Kubernetes 概要
Kubernetes は、 Kubernetes クラスタを作成して、ここに対して kubectl コマンドで、デプロイ、設定変更などを行う仕組みになっています。
kubectl コマンドは、自分のPCで実行してもいいですし、どこかのサーバーで実行してもいいですし、CIなどから実行してもいいと思います。
kubectl コマンドについて
とりあえず、自分の PC には kubectl コマンドをインストールしておくと便利です。
インストールの方法はこちら
Kubernetes クラスタの構築
アプリケーションをデプロイするための Kubernetes クラスタを構築する必要があります。
indigo VPS を利用
今回は indigo という NTT が提供する VPS を利用しようと思います。
今回は kubeadm というツールを使って kubernetes クラスタを構築していくのですが、 kubeadm が要求しているのが「1台あたり2GB以上のメモリ、2コア以上のCPU」となっているので、2GB, 2vCPU のマシン2台で構築してみようと思います。
2台で1400円になります。料金が安いので indigo を選択しています。
kubernetes のドキュメントに「2GBの場合、アプリ用のスペースはほとんどありません」と書いてあるので、今回はあくまでもお試しのつもりでお願いします。また、2台の場合は冗長構成にならないので、1台でもサーバーが止まったらクラスタは止まってしまいます。
OS は Ubuntu を選択しました。
kubeadm vs kubespray
Kubernetes クラスタの構築について調べると、 kubeadm または kubespray を使ってクラスタを構築している記事が多いです。
基本的に、Kubernetes クラスタの構築には kubeadm を利用します。
kubespray は Ansible になっています。結局中で使われているのは kubeadm なのですが、多数のサーバーに一気に kubeadm をインストール&クラスタのセットアップができます。サーバーの台数が多い時には便利だと思われます。
しかし、 kubespray を使うには、kubeadm についてある程度分かってないと厳しいです。
今回はサーバーが2台と少ないですし、僕も kubeadm を全くわかってないので、 kubeadm を直接使って構築します。
Kubernetes クラスタのマスターノードとワーカーノード
クラスタを構築するにあたり、「マスターノード」と「ワーカーノード」について知る必要があります。
「ノード」というのは、1台のサーバーのことを指します。
Kubernetes クラスタには、「コントロールプレーン」という、クラスタの管理をする部分と、「データプレーン」という、コンテナをデプロイする部分があります。
コントロールプレーンのノードを「マスターノード」、テータプレーンのノードを「ワーカーノード」と呼びます。
(図は https://aws.amazon.com/jp/blogs/startup/techblog-container-k8s-1/ より)
今回はサーバー2台なので、マスターノード1台、ワーカーノード1台の構成で組みます。
先ほど「冗長構成ではない」と言ったのはこの点で、現在マスターノードもワーカーノードも1台しかないため、どちらかが壊れたらクラスタは機能しなくなります。
kubeadm を使った Kubernetes クラスタ構築の手順
Kubernetes クラスタの構築の手順については、この記事が非常にわかりやすかったです。この手順の通りにやります。
先ほど述べたように、サーバーは2台(マスターノード1台、ワーカーノード1台)。OS は Ubuntu です。
全てのノードで実行
以下の手順は、マスターノードとワーカーノードの両方で実行します。
docker のインストール
$ sudo apt-get install -y docker.io $ docker --version Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2 $ sudo systemctl start docker
kubeadm のインストール
# root ユーザーで実行します $ sudo su - $ wget https://packages.cloud.google.com/apt/doc/apt-key.gpg $ apt-key add apt-key.gpg $ apt-get install -y apt-transport-https $ echo deb https://apt.kubernetes.io/ kubernetes-xenial main > /etc/apt/sources.list.d/kubernetes.list $ apt-get update $ apt-get install -y kubeadm kubectl
続いて、kubeadm を systemd で起動するようにします。
/etc/docker/daemon.json
に以下の設定を記述します。root ユーザーで作成します。
なお、最低限必要なのは "exec-opts": ["native.cgroupdriver=systemd"]
の部分で、それ以外はログの設定なので、必須ではありません。
{ "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" }
設定したら Docker を再起動します。
# root ユーザーで実行します $ systemctl daemon-reload $ systemctl restart docker $ docker info | grep Cgroup Cgroup Driver: systemd Cgroup Version: 1
ここまでで、各ノードの kubeadm の設定は終了です。
マスターノードで実行
続いて、マスターノードの設定をします。以下は、マスターノードになる予定のサーバーでのみ実行します。
まず、 kubeadm init
するのですが、この時にネットワークのアドレス領域を設定します。これは、 kubernetes クラスタ内で利用される、プライベートネットワークのIPアドレス帯です。
クラスタ内で起動しているコンテナ間で通信するための IP アドレスの領域です。プライベートIPの領域内であればなんでもいいです。今回は 10.1.0.0/16
としました。
$ kubeadm init --pod-network-cidr=10.1.0.0/16
init コマンドに成功すると、取り合えすマスターノード1台のクラスタが完成します。init コマンドの最後に、以下のような文字が最後に出てくると思います。
$ kubeadm join XXX.XXX.XXX.XXX:6443 --token secret \ --discovery-token-ca-cert-hash sha256:xxxxxxxx
これは、このクラスタに新しくノードを参加させるためのコマンドです。この後にワーカーノードを構築する時に利用するので、メモっておきましょう。
なお、token には24時間の期限があるため、24時間過ぎてしまったら、もう一回 token を発行する必要があります。その時のコマンドは以下です。
$ kubeadm token create --print-join-command
クラスタの構築が完了すると、 /etc/kubernetes/admin.conf
という設定ファイルができます。この設定ファイルを kubectl コマンドに読み込ませると、このクラスタの状態が確認できたり、デプロイができたりします。
例えば、手元のPCに kubectl コマンドをインストールして、クラスタに接続するものとします。
マスターノードの /etc/kubernetes/admin.conf
を、手元のPCの ~/.kube/config
にコピーします。 kubectl get node
でノード一覧が取得できます。
$ kubectl get node NAME STATUS ROLES AGE VERSION i-12100000271451 NotReady control-plane,master 10m v1.23.4
まだ NotReady なので、ネットワーク周りの設定をして Ready にしてやる必要があります。
ここからの作業は、 kubectl コマンドが動くPCで行います。
まず、ファイルをダウンロードします。
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
このファイルに、以下のような記述があります。この Network の部分を、マスターノード構築の時に指定したローカルIPのアドレス帯に変更します。
デフォルトでは 10.244.0.0/16
になっているので、今回の場合であれば、これを 10.1.0.0/16
に変更します。
... data: ... net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } ...
修正したら、 kubectl apply
コマンドを使って設定を適用させます。
$ kubectl apply -f kube-flannel.yml Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created
これで status が Ready になると思うので、マスターノードのセットアップは終了です。
$ kubectl get node NAME STATUS ROLES AGE VERSION i-12100000271451 Ready control-plane,master 21m v1.23.4
ワーカーノードの構築
こちらは簡単で、ワーカーノードとしてクラスタに参加させたいサーバーで、先ほどの kubeadm join
コマンドを実行するだけです。
kubeadm join XXX.XXX.XXX.XXX:6443 --token secret \ --discovery-token-ca-cert-hash sha256:xxxxxxxx
kubectl コマンドで見てみると、ノードが増えているはずです。
$ kubectl get node NAME STATUS ROLES AGE VERSION i-12100000271451 Ready control-plane,master 31m v1.23.4 i-14100000271452 NotReady <none> 29s v1.23.4
今回はここまで
取り合えす今回はクラスタ構築できたのでここまでです。
アプリのデプロイの方法はまた別の記事で書こうと思います。