猫でもわかるWebプログラミングと副業

本業エンジニアリングマネージャー。副業Webエンジニア。Web開発のヒントや、副業、日常生活のことを書きます。

個人で VPS で Kubernetes クラスタを組むなら kubeadm (vs Kubespray)

はじめに

私はいくつか個人でアプリを出しているんですが、それを VPS にいい感じにデプロイしたいなと思いました。

VPS とは、さくらのVPSや、ConoHaなど、サーバーを1台だけ貸してくれるようなサービスです。

めっちゃサクッとデプロイするなら、Heroku でいいんですが、Heroku は

  • サーバーが海外にあって遅い
  • バッチ処理を実行するのが面倒
  • 凝ったことをやると割高

といった欠点があると思っています。

そこで、Kubernetes の勉強も兼ねて、VPS で Kubernetes クラスタを構築してみることにしました。

Kubernetes 概要

Kubernetes は、 Kubernetes クラスタを作成して、ここに対して kubectl コマンドで、デプロイ、設定変更などを行う仕組みになっています。

kubectl コマンドは、自分のPCで実行してもいいですし、どこかのサーバーで実行してもいいですし、CIなどから実行してもいいと思います。

kubectl コマンドについて

とりあえず、自分の PC には kubectl コマンドをインストールしておくと便利です。

インストールの方法はこちら

kubernetes.io

Kubernetes クラスタの構築

アプリケーションをデプロイするための Kubernetes クラスタを構築する必要があります。

indigo VPS を利用

今回は indigo という NTT が提供する VPS を利用しようと思います。

web.arena.ne.jp



今回は kubeadm というツールを使って kubernetes クラスタを構築していくのですが、 kubeadm が要求しているのが「1台あたり2GB以上のメモリ、2コア以上のCPU」となっているので、2GB, 2vCPU のマシン2台で構築してみようと思います。

f:id:yoshiki_utakata:20220318110453p:plain



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 クラスタには、「コントロールプレーン」という、クラスタの管理をする部分と、「データプレーン」という、コンテナをデプロイする部分があります。

コントロールプレーンのノードを「マスターノード」、テータプレーンのノードを「ワーカーノード」と呼びます。

kubectl と Kubernetes クラスタ
kubectl と Kubernetes クラスタ
マスターノード・ワーカーノード
マスターノード・ワーカーノード

(図は https://aws.amazon.com/jp/blogs/startup/techblog-container-k8s-1/ より)



今回はサーバー2台なので、マスターノード1台、ワーカーノード1台の構成で組みます。

先ほど「冗長構成ではない」と言ったのはこの点で、現在マスターノードもワーカーノードも1台しかないため、どちらかが壊れたらクラスタは機能しなくなります。

kubeadm を使った Kubernetes クラスタ構築の手順

Kubernetes クラスタの構築の手順については、この記事が非常にわかりやすかったです。この手順の通りにやります。

knowledge.sakura.ad.jp

先ほど述べたように、サーバーは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

今回はここまで

取り合えす今回はクラスタ構築できたのでここまでです。

アプリのデプロイの方法はまた別の記事で書こうと思います。