k0sを使って簡単Kubernetesクラスター構築

Kubernetes2 Advent Calendar 2020 1 日目

makocchi
14 min readNov 30, 2020

この記事は Kubernetes2 Advent Calendar 2020 の 1 日目です。

https://www.mirantis.com/blog/congratulations-to-the-k0s-team-on-their-new-kubernetes-distribution/

みなさんは k?s といったキーワードを聞いた時に何を思い浮かべるでしょうか?

k8s、これは紛れもなく皆さん知っていますよね。Kubernetes を略す時によく使われます。( Kubernetesks の間は 8 文字あることから)

k3s 、これも有名ですよね。Rancher がメインで開発している軽量な Kubnernetes のバイナリです。

k9s 、これは知っている人は知っているんですが terminal 上で Kubernetes をモニタリングしたり、操作したり、いわゆる IDE の機能を提供してくれるものです。便利ですよ!

さて、今日ご紹介するのは k0s です。

(ちなみに数字が一桁のやつは k0s/k3s/k8s/k9s 以外の数字は自分が調べた感じ無さそうでした。さらにちなむと k14s (Kubernetes tools)というのが vmware から開発されているみたいですね。名前が carvelになったぽいですが)

TL;DR

Single Node 構成 (control-plane と worker node を同居) の場合

$ sudo k0s server --enable-worker

Multi Node 構成の場合

control-plane $ sudo k0s serverworker nodeN $ sudo k0s worker (token)

で Kubernetes のクラスターが自動的に立ち上がります。なんて簡単。

k0s とは

Mirantis 社が先日 OSS として公開しました。

これ系のツールはよく Kubernetes 自体に手を入れたバイナリを使いがちなのですが、ピュアな Kubernetes (Upstrem そのまま) でクラスターを構築することが可能です。新しく出してきたこともあって、Kubernetes の version も現時点での最新である 1.19 で動かすことができます。そして x86_64 はもちろん、 arm64 にも最初から対応しているのもポイントですね。

結局 k0s は何をしてくれるのか?というと Kubeadmminikubekind と似たようなもの、と考えるのが一番早いかもしれません。

もともとは Mirantis Kubernetes Engine(MKE) で動いていたもの・・だそうです (ソースは reddit の書き込み)

k0s をインストールする

インストールの仕方は非常に簡単です。バイナリを直接入手して配置するか、インストールの shell を使うか、どちらでも可能です。

バイナリの場合は github の release から入手します。

インストールの shell は get.k0s.sh ( k0s.sh だけでもいける) が用意されています。こちらの shell を使う場合には /usr/bin/k0s にバイナリが配置されますので、ほとんどの環境では root権限が必要になるでしょう。特定の PATH にインストールしたい場合はバイナリを直接入手する方法をお勧めします。

$ curl -sSLf get.k0s.sh | sudo sh

現時点では最新の v0.7.0 がインストールされます。get.k0s.sh で特定のバージョンをインストールしたい場合は環境変数で K0S_VERSION を指定すれば OK です。

これからの本記事の内容は v0.7.0 での動作を元に書いています。

k0s で control-plane を立ち上げる

k0s では control-plane(いわゆる etcd kube-apiserverkube-controller-manager 等が動く Node)は完全に分離されたものとして動かす思想になっています。つまり明示的に指定しない限り、control-plane では kubelet は動きません。ここらへんは kubeadm とコンセプトが違うので面白いですね。

v0.7.0では k0s がいろいろ作業する場所が /var/lib/k0s になっていて変更ができません。(次のバージョンから --data-dir が実装される)

/var/lib/k0sk0s が作成してくれるのですが、 /var/lib に対する書き込み権限、いわゆる root 権限が必要になっています。

control-plane を立ち上げるのは非常に簡単で k0s server これだけです。

# 実行には root 権限が必要になる
$ sudo k0s server

これを実行すると control-plane に必要なバイナリ達が /var/lib/k0s/bin/ にどさどさ用意されます。

# こんな感じで用意される
$ ls -1 /var/lib/k0s/bin/
containerd
containerd-shim
containerd-shim-runc-v1
containerd-shim-runc-v2
etcd
konnectivity-server
kube-apiserver
kube-controller-manager
kubelet
kube-scheduler
runc

そして k0s 自体が supervisor 役となって、daemon で動かす必要があるやつを子プロセスとして実行します。

コンテナとしてプロセスを稼働させるわけではなく、プロセスとして実行されるという点で control-plane にはコンテナのランタイムの依存が無くて済むということになります。(worker node としても稼働させる場合には必要になってきます)

k0s の log level を変更する

k0s の特徴の1つになるのですが、各種プロセスを supervisor しているので、子プロセスの logが全て流れてくる実装になっています。 k0s は実行してもプロセスはそのまま foreground で動きますので、terminal にぶわーっといろいろなコンポーネントの log が出てきます。

正直そのままだと非常に見難いので、各種 control-plane の log levelを変更するのがいいと思います。log level は --logging で指定することができます。

デフォルトでは etcd と containerd は info でそれ以外のコンポーネントは -v=1 で稼働します。

例えば etcdの log level を panic にしたい場合は --logging etcd=panic と指定しておきます。 kube-* 系の log 全部要らない!って場合は --logging kube-apiserver=0,kube-controller-manager=0,kube-scheduler=0,kubelet=0 とかにしておくといいかもしれません。

--logging ですが、実は v0.7.0 では機能しません。指定しても log level 変わらないんですよ。なので PR 送って直してもらいましたv0.8.0 には入るかも?なので現状は main を build しないと修正バイナリは手に入りません・・( v0.8.0-rc1 にも入ってない)

k0s で worker node を立ち上げる

worker node では kubelet 及び containerd が立ち上がります。control-plane と同居する場合と worker node 単体で動かす場合で起動の仕方が変わってきます。

control-plane で worker node を立ち上げる場合は control-plane を立ち上げる時に --enable-worker を一緒に指定してあげます。

# worker node も兼任させるには --enable-worker を指定する
$ sudo k0s server --enable-worker

control-plane とは別に worker node を用意する場合は kubeadm と同じように token を生成して worker node 側から join してあげます

# token を生成する (--role のデフォルトは "worker" なので省略化)
control-plane $ k0s token crate --role=worker
H4sIAAAAAAAC/3RVzW7ruhnc5yn8AudcSrbS2kAXl......
# worker node 側で token を使って join する
node1 $ sudo k0s worker <上記の token>

k0s token create すると token が terminal に表示されますが、これの中身は実は kubeletbootstrap用の kubeconfig になります。

# token の中身を見てみよう
$ echo -n ${TOKEN} | base64 --decode | gzip -d -
apiVersion: v1
clusters:
- cluster:
server: https://1.2.3.4:6443
...
...
users:
- name: kubelet-bootstrap
user:
token: c883mj.srdswebd4eggei8v

--roleworker 以外の文字列が渡された場合、生成される kubeconfig は内容が少し変わり、server の port が 9443 になります。

これは k0s 自体の api port のようです。証明書や etcd の情報を取ってくることができるみたいで、おそらく control-plane を複数立てる場合はこちらでやれということなんだと思います。

# k0s server にも token を渡すことができる
$ sudo k0s server <token>

これで control-plane の冗長化ができるかなと思ったんですが、ちょっと上手く行きませんでした・・・時間がある時に debug してみようと思います。

worker node のコンテナランタイムは containerd が使われます。 ctr を使うことで containerd の状態を確認することができます。( --namespacek8s.io を指定する必要がある)

# /run/k0s/containerd.sock を指定してあげればいろいろ操作可能
$ sudo ctr -a /run/k0s/containerd.sock --namespace k8s.io containers ls
....

containerd 起動時には /etc/k0s/containerd.toml を読むように起動されます。ですのであらかじめ containerd.toml を用意しておけばカスタマイズが可能になっています。そう、例えば gVisor を使いたい場合もありますよね?そういった場合でも対応することができます。

gVisor の組み込みはこちらの手順を参考にしてください。

出来上がったクラスターに接続する

接続するための kubeconfig は /var/lib/k0s/pki/admin.conf を使います。このファイルは root 権限なくても読めます。しかし接続先が https://localhost:6443 になっているので、リモートからアクセスしたい場合は admin.confは適宜修正する必要がありますね。

作成されるクラスターをカスタマイズする

基本的には全てデフォルトの設定でクラスターが立ち上がってくれるとは思うのですが、いろいろカスタマイズしたくなる場合もありますよね。その場合はある程度カスタマイズすることが可能です。

k0s default-config でデフォルトの設定を書き出すことができます。お好みに応じて設定ファイルを編集して、それを k0s 起動時に読み込ませることが出来ます。

# 例えば /etc/k0s/k0s.yaml に書き出す
$ sudo mkdir /etc/k0s
$ k0s default-config | sudo tee -a /etc/k0s/k0s.yaml
# 設定変える
$ sudo vi /etc/k0s/k0s.yaml
# その設定で起動する
$ sudo k0s --config /etc/k0s/k0s.yaml server

デフォルトでは CNI には calico が使われますが、変更したりすることができます。また k0s の特徴にもなりますが、backend のストレージに etcd 以外を選択することができます。これは内部的に kine を使用することで実現しています。MySQL や PostgreSQL を backend のストレージにすることが可能です。

CNI や coredns や metrics-server といったコンポーネントは自動で起動されます。config ではその image も指定することが可能です。例えば docker.io からの pull limit 食らった・・・なんて場合には quay.io から pull するように image を書き換える・・といったことが可能です。

konnectivity について

k0s では control-plane と worker node 間の通信に konnectivity が使われています。control-plane のネットワークと worker node のネットワークが完全に分断されていた場合には ssh tunnel とかしないといけなかったんですが、これを gRPC or HTTP で出来るようにしたもの・・という認識です。(あってるかな?)

これは MKE の内部でそういう作りになっていたから、k0s もそのまま引き継いでいるのかなと予想してます。Cloud を提供する側からすると master が使用するネットワークは利用者にはアクセスさせないことが多いですよね。

手元で動かす分には konnectivity の恩恵はほぼ無いに等しいので、今後どうなるか注目ですね。

まとめ

k0s いかがだったでしょうか。まだまだ開発途中ということもあって完成度は kubeadm 等に比べると物足りない部分もありますが、control-plane を完全に分離させて環境を作ることができるのが k0s のメリットかなと思います。クラスター構築に必要なバイナリを落としてきて実行させるコンセプトなので OS 依存やパッケージ依存が少ないのもポイントですね。

これからいろいろ機能が充実していくのではないかと思いますので、期待しましょう!あと、今ならコントリビュートのチャンスかもですよ!

参考リンク

--

--

makocchi

Makoto Hasegawa | kubernetes | CKA(#CKA-1700–0150–0100) | CKAD(CKAD-1800–0005–0100) | docker | container | OpenStack