k0sを使って簡単Kubernetesクラスター構築
この記事は Kubernetes2 Advent Calendar 2020 の 1 日目です。
みなさんは k?s
といったキーワードを聞いた時に何を思い浮かべるでしょうか?
k8s
、これは紛れもなく皆さん知っていますよね。Kubernetes を略す時によく使われます。( Kubernetes
の k
と s
の間は 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
は何をしてくれるのか?というと Kubeadm
や minikube
や kind
と似たようなもの、と考えるのが一番早いかもしれません。
もともとは 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-apiserver
や kube-controller-manager
等が動く Node)は完全に分離されたものとして動かす思想になっています。つまり明示的に指定しない限り、control-plane では kubelet
は動きません。ここらへんは kubeadm
とコンセプトが違うので面白いですね。
v0.7.0
では k0s
がいろいろ作業する場所が /var/lib/k0s
になっていて変更ができません。(次のバージョンから --data-dir
が実装される)
/var/lib/k0s
は k0s
が作成してくれるのですが、 /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 に表示されますが、これの中身は実は kubelet
の bootstrap
用の 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
--role
に worker
以外の文字列が渡された場合、生成される 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
の状態を確認することができます。( --namespace
で k8s.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 依存やパッケージ依存が少ないのもポイントですね。
これからいろいろ機能が充実していくのではないかと思いますので、期待しましょう!あと、今ならコントリビュートのチャンスかもですよ!