featured_image
2022-11-25

せっかくのブラックフライデーだし、格安海外VPSを買いまくってk0sで自前Kubernetes環境を作ってみよう

格安VPSをいっぱい買って、実験用のマルチノードクラスタを安価に組むお話

KEY POINTS
  • 格安VPSを多数買えば遊べるKubernetesを組める
  • 海外の格安VPSは元々安い上にブラックフライデー&サイバーマンデーにてセールを積極的に行っている
  • みんなk0sで自前Kubernetes環境を作ろう

個人でKubernetes・・・と言うのは良くある話です。とはいえ大抵は1台に全部詰め込んだall-in-one環境が主流でしょう。

サーバー1台ではKubernetesの醍醐味を味わうには不十分だと思います。かといって物理サーバーいっぱい置くのはいろいろハードルが高いし、電気代だってバカにならないです。また 昔あった激安物理サーバー なんてものは今はないし、ラズパイだって気軽に大量買いできる情勢ではありません。

でもVPSなら割と安価に大量のノードを揃えることができるかもしれません。そして現在(2022年11月後半)ちょうどブラックフライデーのために格安VPS事業者がセールをやっています。手を出すなら今がチャンスではないでしょうか?

というわけで、みんなk0sで自前Kubernetes環境を作ってみませんか?

Disclaimer

ここに書いてあることは自分がやったことを元にしていますが100%動く保証はないです。というより動かない確率の方が高いでしょう。

私の環境とあなたの環境は違うので、書いてあることをコピペしただけでは動かないかもしれません。その場合は各自が工夫する必要があります。

また最後に書いていますが、k0sには標準状態で本当に何も入っていません。自分で考えて好きなものを入れる必要があります。

コストの話

これはある意味一番重要なので、最初に書いておきます。

コントロールプレーン1台、ワーカーノード2台で過去に私が作ったやつだとこんな感じです。

これは正月・旧正月セールを使用しています。

メモリ コア数 ディスク 1台・1年あたりのコスト 日本円換算(1USD=150JPY) 備考
コントロールプレーン 1GB 1コア 12GB 11.88USD 1782JPY
ワーカーノード 2.5GB 2コア 35GB 22.38USD 3357JPY 2台借りてる

合計8496JPY/年です。高そうに見えますが、700JPY/月です。これで3台借りています。

ちなみに主要な国内VPSは現在こんな感じです。まあ勝負にならないでしょう。(色々明文化されてない変な規制もあるし・・・)

メモリ コア数 ディスク 1年あたりのコスト 備考
Conoha 2GB 3コア 100GB 6420JPY VPS割引きっぷ12ヶ月
WebArena Indigo 2GB 2コア 40GB 8388JPY 699JPY/month
さくらVPS 2GB 3コア 100GB 19118JPY 1年契約・石狩

ところでなぜk0s?

https://k0sproject.io/

k0sはいわゆる軽量Kubernetesディストリビューションのひとつです。

以下の理由からk0sを選んでいます

  • 単純に軽い
  • 標準状態でcalicoを使えて、wireguardによる暗号化通信を非常に簡単に使える
    • バラバラのVPSを接続するということは、通信は何の加護もないグローバルなネットワークを通すことになるということ
    • ワーカーノード間は暗号化を使うべき(Flannel素通しとかは論外)
  • 標準状態でkineを使える
    • シングルノードのコントロールプレーンでお手軽運用するのならetcdから逃げることができる
  • 自動ツールk0sctlの存在
    • こだわりがないなら結構実用的に使える
    • 不満がいろいろ出てきたら、自力でansibleか何か使えば良いと思う
      • というか自分は現在k0sctl使わずansibleで管理してる
  • 余計なものが何も入っていない
    • これはインストールしただけでは何もできないということを意味する
    • しかし自分の好きなものを好き放題ぶち込めるという利点でもある

まずはVPSを買う

まあ買わないことには始まらないです。適当なものを探して多々買いましょう。

VPSのセール情報はどこで調べると良い?

LowEndTalkという格安サーバー専門フォーラムがあるので、それを使うと良いでしょう。

もちろん英語です。全体的なノリは良くも悪くも軽めです。VPSの中の人とかも普通に出てきます。

https://lowendtalk.com/

選び方

基本的には以下を満たしている必要なスペックを持つサーバーを買えばOKだと思います。

  • 仮想化にKVM使っている
  • 新しめのディストロに対応している
  • グローバルなIPが降ってくる
    • NATって書いてるやつは選んではいけない
  • IPv6専用ではない
    • IPv6対応してない格安VPSは意外に多いので、複数台買って繋げる前提だと問題になる

何台買う?

醍醐味を味わうなら 最低3台(コントロールプレーン1台、ワーカーノード2台) 買うのがおすすめです。もちろん数はあればあるほど遊べます。

あと、今慌てて大量に買う必要はないです。Kubernetesなのでワーカーノードなんて後で好きなだけ好きな時に足せばよいわけです。

セールはブラックフライデー&サイバーマンデーだけじゃないです。この後クリスマスも正月も旧正月もあります。

どれくらいのスペックが良い?

基本的にメモリだけ見ていれば良いと思っています。他の性能は価格に応じて適度に割り当てられるので、じたばたするだけ無駄だと思ってます。

一応メモリ1GBでも動くとは書かれていますが、実際運用してみるとキツキツであまり遊べません。なので 2GB以上を選ぶのが無難 です。

物理場所に注意

あまり日本から遠すぎるサーバーを選ぶとSSHが辛いです。

また安く済むからといってサーバー同士の距離がむっちゃ離れていて通信に時間を要する組み合わせ(例:アメリカとドイツとシンガポールのサーバーを組み合わせる)もあまり推奨できないです。

日本からの使用を前提に無難で安価な選択肢を選ぶのであれば、全てのサーバーを アメリカ西海岸の都市から選ぶと良い のではと思います。日本からのアクセスが割と高速で、物件も多いです。

初期セットアップ

この作業は多くの場合必須です。おそらくVPSをいろんな会社から購入することになりますが、それらの仕様はたいていバラバラなので揃える必要があります。

  • 初期ユーザーがrootかもしれないし、そうではないかもしれない
    • 作業で使うユーザー名を揃えないと自動化がしんどい
  • SSHログインがパスワードだけかもしれない
    • 公開鍵認証使うべき
  • あとで使う k0sctlではパスワードレスsudoが要求される
  • minimal仕様で、普通に入ってそうなものが入ってないかもしれない
    • sudoすらできないかもしれない
  • Linuxディストリビューションを揃えられないかもしれない
    • よくある事例だと、UbuntuとDebian混成を余儀なくされたりとか
    • 初期状態で入っているものがあまりにもバラバラすぎると辛いので、揃えられる範囲で頑張ればよいはず

どうする?

やり方はいろいろあります。

台数が少ないなら手動でユーザー作成とか、apt installとかやっても良いんじゃないでしょうか。

ちなみに私は手作業が好きではないのでansibleを使用しています。以下は自分が実際使っているやつでRackNerdという業者のVPSを初期化するのに使用しているものです。だいたいどんなことやってるかは、Ansibleわからなくても雰囲気は伝わると思います。

---
- hosts: racknerd
  vars:
    ansible_user: root
    ansible_ssh_pass: "{{ racknerd_default_ssh_pass }}"
  tasks:
  - name: Add tpdn
    user:
      name: tpdn
      groups: sudo
      password: "{{ ansible_sudo_pass | password_hash('sha512') }}"
      shell: /bin/bash

  - name: Put public key
    authorized_key:
      user: tpdn
      key: '{{ public_key_for_ssh }}'

  - name: Run apt update, if it does not exist /var/lib/apt/lists/lock
    command: apt update
    args:
      creates: /var/lib/apt/lists/lock

  - name: Update all packages to the latest version
    apt: update_cache=yes upgrade=yes

  - name: Install sudo
    apt: 
      name: sudo
      update_cache: yes

  - name: Edit sudoers
    lineinfile:
      path: /etc/sudoers
      state: present
      regexp: 'tpdn'
      line: 'tpdn ALL=(ALL) NOPASSWD: ALL'

  - name: Copy sshd_config
    copy:
      src: sshd_config
      dest: /etc/ssh/sshd_config

- hosts: racknerd
  become: True
  tasks:
  - name: reboot
    reboot:

  - name: Debug
    debug:
      msg: Finish!

k0sctlで一気に構築

https://github.com/k0sproject/k0sctl

k0sにはk0sctlというお手軽管理ツールが存在しているので、ここではこれを使います。

もちろんクラスタ構築をやり込むと物足りなくなってくると思いますが、当面の間はこれで十二分に遊べるでしょう。

ツールのインストール

https://github.com/k0sproject/k0sctl#installation

書かれている通りにやりましょう。

初期configの生成

まずは初期configを生成します。

k0sctl init > k0sctl.yaml

だいたいこんな感じのものが生成されるでしょう。

apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-cluster
spec:
  hosts:
  - ssh:
      address: 10.0.0.1
      user: root
      port: 22
      keyPath: /root/.ssh/id_rsa
    role: controller
  - ssh:
      address: 10.0.0.2
      user: root
      port: 22
      keyPath: /root/.ssh/id_rsa
    role: worker
  k0s:
    version: 1.25.4+k0s.0
    dynamicConfig: false

config編集

最低限必要なものを入力します。

以下はあくまでも例で、私が必要だと思う本当に最低限のものしか入れてないです。

ドキュメントを見て各自必要な設定を入れると良いでしょう。

apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: my-k0s-cluster
spec:
  hosts:
  - ssh:
      address: server1.tpdn.kim # これはあくまでも例なので自分のサーバーのアドレス入れる必要あり
      user: tpdn # 当然ながら自分で作ったユーザー名を入れる必要がある
      port: 22
      keyPath: keys/id_ed25519 # 当然ながら自分のssh用鍵を入れる必要がある
    role: controller # コントロールプレーン
  - ssh:
      address: server2.tpdn.kim
      user: tpdn
      port: 22
      keyPath: keys/id_ed25519
    role: worker # ワーカー
  - ssh:
      address: server3.tpdn.kim
      user: tpdn
      port: 22
      keyPath: keys/id_ed25519
    role: worker # ワーカー
  k0s:
    version: 1.25.4+k0s.0
    config:
      apiVersion: k0s.k0sproject.io/v1beta1
      kind: ClusterConfig
      metadata:
        name: my-k0s-cluster
      spec:
        storage:
          kine: # kineでsqlite
            dataSource: sqlite:///var/lib/k0s/db/kine.db
          type: kine
        network:
          provider: calico
          calico:
            wireguard: true # これだけでwireguard使って通信するようになる

configの反映

k0sctl apply --config k0sctl.yaml

これを実行するだけで自分だけが使えるKubernetesが爆誕します。

kubeconfig.cfgを手に入れる

k0sctl kubeconfig --config k0sctl.yaml > kubeconfig.cfg

これでkubectlが使えるようになります。

root@3cf0f3793991 /w/server_cluster_ops (k0s)# KUBECONFIG="kubeconfig.cfg" kubectl get node
NAME              STATUS   ROLES    AGE     VERSION
racknerd-20ef0b   Ready    <none>   3m41s   v1.25.4+k0s
racknerd-6c6e35   Ready    <none>   3m41s   v1.25.4+k0s

その後は?

ここまでやればいろいろデプロイ可能です。でもこれは終わりではなく始まりでしかないです。

k0sには本当に最低限のものしか入っていないので、はっきり言ってできないことだらけでしょう。実用可能に持っていくにはやらなきゃいけないことがいっぱいあります。

例えばよくあるWebアプリの公開を想定するなら、少なく見積もっても以下が足りてないです。なので自前で対処する必要があります。

  • ロードバランサがない
    • 独自ドメイン取ってDNSラウンドロビン使うのが現実的
  • Ingressがないので、外部に公開するのが面倒
    • NginxとかTraefikとかを自前でインストールするのが必要
  • 永続ストレージがないので、データを保存できない
    • 無難にlocal使う
    • ノードが大量にあるならOpenEBSで夢を見るのもあり
    • 諦めるのも用途次第ではあり(外部のS3互換の何かに頼って、雑に運用する)