k3s をインストールしてみた

こんにちは。サイオステクノロジー OSS サポート担当 Y です。

今回は、最近話題の k3s をシングルノード構成でインストールしてみました。(※以下の内容は CentOS 7.6/k3s v0.2.0 にて検証しています。)

■はじめに

今回は、Rancher Labs が開発した k3s を試してみました。

こちらのページにも記載されていますが、k3s は “軽量な Kubernetes (Lightweight Kubernetes)” です。

名前の由来は “5 less than k8s” であり、通常の Kubernetes から 5つの要素が変更 (及び削除) され、より軽量な実装になっているようです。通常の Kubernetes からの変更内容については GitHub の README に記載されています。

■k3s のインストール

それではさっそく、検証してみようと思います。

まずはインストールですが、k3s はシングルバイナリで提供されているため、そのバイナリを 1つダウンロードするだけです。(1つのバイナリの中に “API Server”, “Controller Manager”, “Scheduler” 等の Kubernetes のコンポーネントがまとめられているそうです)

[root@k3s-master ~]# cd /usr/local/bin/
[root@k3s-master bin]# 
[root@k3s-master bin]# wget https://github.com/rancher/k3s/releases/download/v0.2.0/k3s

~(中略)~

2019-03-29 16:07:20 (109 KB/s) - 'k3s' saved [37735552/37735552]

[root@k3s-master bin]# 
[root@k3s-master bin]# ls -l ./k3s     
-rw-r--r--. 1 root root 37735552 Mar  9 11:48 ./k3s
[root@k3s-master bin]# 
[root@k3s-master bin]# chmod 755 ./k3s 
[root@k3s-master bin]# 
[root@k3s-master bin]# ls -l ./k3s 
-rwxr-xr-x. 1 root root 37735552 Mar  9 11:48 ./k3s

■k3s 起動

では、ダウンロードしたバイナリを使って k3s を起動してみます。

Quick start に記載されている通り、シングルノード構成 (Master のみ起動する) であれば、1コマンドで起動してくれるようです。

[root@k3s-master ~]# k3s server &
[1] 7301
[root@k3s-master ~]# INFO[0000] Preparing data dir /var/lib/rancher/k3s/data/e44f7a46cadac4cec9a759756f2a27fdb25e705a83d8d563207c6a6c5fa368b4 
INFO[2019-03-29T16:09:54.806708216+09:00] Starting k3s v0.2.0 (2771ae1)                
INFO[2019-03-29T16:09:56.655759768+09:00] Running kube-apiserver --watch-cache=false --cert-dir /var/lib/rancher/k3s/server/tls/temporary-certs --allow-privileged=true --authorization-mode Node,RBAC --service-account-signing-key-file /var/lib/rancher/k3s/server/tls/service.key --service-cluster-ip-range 10.43.0.0/16 --advertise-port 6445 --advertise-address 127.0.0.1 --insecure-port 0 --secure-port 6444 --bind-address 127.0.0.1 --tls-cert-file /var/lib/rancher/k3s/server/tls/localhost.crt --tls-private-key-file /var/lib/rancher/k3s/server/tls/localhost.key --service-account-key-file /var/lib/rancher/k3s/server/tls/service.key --service-account-issuer k3s --api-audiences unknown --basic-auth-file /var/lib/rancher/k3s/server/cred/passwd --kubelet-client-certificate /var/lib/rancher/k3s/server/tls/token-node.crt --kubelet-client-key /var/lib/rancher/k3s/server/tls/token-node.key 
INFO[2019-03-29T16:09:57.859363977+09:00] Running kube-scheduler --kubeconfig /var/lib/rancher/k3s/server/cred/kubeconfig-system.yaml --port 10251 --address 127.0.0.1 --secure-port 0 --leader-elect=false 
INFO[2019-03-29T16:09:57.861980258+09:00] Running kube-controller-manager --kubeconfig /var/lib/rancher/k3s/server/cred/kubeconfig-system.yaml --service-account-private-key-file /var/lib/rancher/k3s/server/tls/service.key --allocate-node-cidrs --cluster-cidr 10.42.0.0/16 --root-ca-file /var/lib/rancher/k3s/server/tls/token-ca.crt --port 10252 --address 127.0.0.1 --secure-port 0 --leader-elect=false 
Flag --address has been deprecated, see --bind-address instead.
INFO[2019-03-29T16:09:58.175879088+09:00] Creating CRD listenerconfigs.k3s.cattle.io   
INFO[2019-03-29T16:09:58.278159768+09:00] Creating CRD addons.k3s.cattle.io            
INFO[2019-03-29T16:09:58.289000446+09:00] Creating CRD helmcharts.k3s.cattle.io        
INFO[2019-03-29T16:09:58.356016822+09:00] Waiting for CRD addons.k3s.cattle.io to become available 
INFO[2019-03-29T16:09:58.857861109+09:00] Done waiting for CRD addons.k3s.cattle.io to become available 
INFO[2019-03-29T16:09:58.857906242+09:00] Waiting for CRD helmcharts.k3s.cattle.io to become available 
INFO[2019-03-29T16:09:59.359129840+09:00] Done waiting for CRD helmcharts.k3s.cattle.io to become available 
INFO[2019-03-29T16:09:59.362419610+09:00] Listening on :6443                           
INFO[2019-03-29T16:10:00.209554234+09:00] Node token is available at /var/lib/rancher/k3s/server/node-token 
INFO[2019-03-29T16:10:00.209587670+09:00] To join node to cluster: k3s agent -s https://10.1.1.21:6443 -t ${NODE_TOKEN} 
INFO[2019-03-29T16:10:00.213282980+09:00] Writing manifest: /var/lib/rancher/k3s/server/manifests/coredns.yaml 
INFO[2019-03-29T16:10:00.213478225+09:00] Writing manifest: /var/lib/rancher/k3s/server/manifests/traefik.yaml 
INFO[2019-03-29T16:10:00.466295407+09:00] Wrote kubeconfig /etc/rancher/k3s/k3s.yaml   
INFO[2019-03-29T16:10:00.466325821+09:00] Run: k3s kubectl                             
INFO[2019-03-29T16:10:00.466353276+09:00] k3s is up and running                        
INFO[2019-03-29T16:10:00.527756870+09:00] Logging containerd to /var/lib/rancher/k3s/agent/containerd/containerd.log 
INFO[2019-03-29T16:10:00.528155373+09:00] Running containerd -c /var/lib/rancher/k3s/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/k3s/agent/containerd 
INFO[2019-03-29T16:10:00.548474695+09:00] Waiting for containerd startup: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /run/k3s/containerd/containerd.sock: connect: no such file or directory" 
containerd: exit status 1

[1]+  Exit 1                  k3s server
[root@k3s-master ~]# 

しかし、上記の様なエラーになってしまいました。

このエラーについて調べてみたところ、いくつかの類似する Issues あるようであり、それらの内容を見ると /etc/hosts にホスト名を記載すると事象が改善するという情報があったので、試してみました。

[root@k3s-master ~]# tail -n 1 /etc/hosts
127.0.0.1   k3s-master.example.com
[root@k3s-master ~]# k3s server &
[1] 7384
[root@k3s-master ~]# INFO[2019-03-29T16:12:10.045436976+09:00] Starting k3s v0.2.0 (2771ae1)                
INFO[2019-03-29T16:12:10.046896713+09:00] Running kube-apiserver --watch-cache=false --cert-dir /var/lib/rancher/k3s/server/tls/temporary-certs --allow-privileged=true --authorization-mode Node,RBAC --service-account-signing-key-file /var/lib/rancher/k3s/server/tls/service.key --service-cluster-ip-range 10.43.0.0/16 --advertise-port 6445 --advertise-address 127.0.0.1 --insecure-port 0 --secure-port 6444 --bind-address 127.0.0.1 --tls-cert-file /var/lib/rancher/k3s/server/tls/localhost.crt --tls-private-key-file /var/lib/rancher/k3s/server/tls/localhost.key --service-account-key-file /var/lib/rancher/k3s/server/tls/service.key --service-account-issuer k3s --api-audiences unknown --basic-auth-file /var/lib/rancher/k3s/server/cred/passwd --kubelet-client-certificate /var/lib/rancher/k3s/server/tls/token-node.crt --kubelet-client-key /var/lib/rancher/k3s/server/tls/token-node.key 
INFO[2019-03-29T16:12:10.237101874+09:00] Running kube-scheduler --kubeconfig /var/lib/rancher/k3s/server/cred/kubeconfig-system.yaml --port 10251 --address 127.0.0.1 --secure-port 0 --leader-elect=false 
INFO[2019-03-29T16:12:10.239400669+09:00] Running kube-controller-manager --kubeconfig /var/lib/rancher/k3s/server/cred/kubeconfig-system.yaml --service-account-private-key-file /var/lib/rancher/k3s/server/tls/service.key --allocate-node-cidrs --cluster-cidr 10.42.0.0/16 --root-ca-file /var/lib/rancher/k3s/server/tls/token-ca.crt --port 10252 --address 127.0.0.1 --secure-port 0 --leader-elect=false 
Flag --address has been deprecated, see --bind-address instead.
INFO[2019-03-29T16:12:10.587535026+09:00] Listening on :6443                           
INFO[2019-03-29T16:12:10.694976126+09:00] Node token is available at /var/lib/rancher/k3s/server/node-token 
INFO[2019-03-29T16:12:10.695061557+09:00] To join node to cluster: k3s agent -s https://10.1.1.21:6443 -t ${NODE_TOKEN} 
INFO[2019-03-29T16:12:10.698546209+09:00] Writing manifest: /var/lib/rancher/k3s/server/manifests/coredns.yaml 
INFO[2019-03-29T16:12:10.698799294+09:00] Writing manifest: /var/lib/rancher/k3s/server/manifests/traefik.yaml 
INFO[2019-03-29T16:12:10.820298416+09:00] Wrote kubeconfig /etc/rancher/k3s/k3s.yaml   
INFO[2019-03-29T16:12:10.820343262+09:00] Run: k3s kubectl                             
INFO[2019-03-29T16:12:10.820356995+09:00] k3s is up and running                        
INFO[2019-03-29T16:12:10.912675876+09:00] Logging containerd to /var/lib/rancher/k3s/agent/containerd/containerd.log 
INFO[2019-03-29T16:12:10.913887304+09:00] Running containerd -c /var/lib/rancher/k3s/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/k3s/agent/containerd 
INFO[2019-03-29T16:12:10.929450459+09:00] Waiting for containerd startup: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /run/k3s/containerd/containerd.sock: connect: connection refused" 
WARN[2019-03-29T16:12:11.953653919+09:00] failed to write value 1 at /proc/sys/net/bridge/bridge-nf-call-iptables: open /proc/sys/net/bridge/bridge-nf-call-iptables: no such file or directory 
INFO[2019-03-29T16:12:11.954703327+09:00] Connecting to wss://localhost:6443/v1-k3s/connect 
INFO[2019-03-29T16:12:11.954755360+09:00] Connecting to proxy                           url="wss://localhost:6443/v1-k3s/connect"
INFO[2019-03-29T16:12:11.960526648+09:00] Handling backend connection request [k3s-master.example.com] 
WARN[2019-03-29T16:12:11.962176214+09:00] Disabling CPU quotas due to missing cpu.cfs_period_us 
INFO[2019-03-29T16:12:11.962763120+09:00] Running kubelet --healthz-bind-address 127.0.0.1 --read-only-port 0 --allow-privileged=true --cluster-domain cluster.local --kubeconfig /var/lib/rancher/k3s/agent/kubeconfig.yaml --eviction-hard imagefs.available<5%,nodefs.available<5% --eviction-minimum-reclaim imagefs.available=10%,nodefs.available=10% --fail-swap-on=false --cgroup-driver cgroupfs --root-dir /var/lib/rancher/k3s/agent/kubelet --cert-dir /var/lib/rancher/k3s/agent/kubelet/pki --seccomp-profile-root /var/lib/rancher/k3s/agent/kubelet/seccomp --cni-conf-dir /var/lib/rancher/k3s/agent/etc/cni/net.d --cni-bin-dir /var/lib/rancher/k3s/data/e44f7a46cadac4cec9a759756f2a27fdb25e705a83d8d563207c6a6c5fa368b4/bin --cluster-dns 10.43.0.10 --container-runtime remote --container-runtime-endpoint unix:///run/k3s/containerd/containerd.sock --address 127.0.0.1 --anonymous-auth=false --client-ca-file /var/lib/rancher/k3s/agent/client-ca.pem --hostname-override k3s-master.example.com --cpu-cfs-quota=false --runtime-cgroups /systemd/user.slice/user-0.slice --kubelet-cgroups /systemd/user.slice/user-0.slice 
Flag --allow-privileged has been deprecated, will be removed in a future version
INFO[2019-03-29T16:12:12.391708233+09:00] waiting for node k3s-master.example.com: nodes "k3s-master.example.com" not found 
INFO[2019-03-29T16:12:14.393831404+09:00] waiting for node k3s-master.example.com CIDR not assigned yet 
INFO[2019-03-29T16:12:16.396318069+09:00] waiting for node k3s-master.example.com CIDR not assigned yet 
INFO[2019-03-29T16:12:18.398246129+09:00] waiting for node k3s-master.example.com CIDR not assigned yet 
INFO[2019-03-29T16:12:20.400212293+09:00] waiting for node k3s-master.example.com CIDR not assigned yet 

[root@k3s-master ~]# 
[root@k3s-master ~]# 
[root@k3s-master ~]# k3s kubectl get node     
NAME                     STATUS   ROLES    AGE     VERSION
k3s-master.example.com   Ready       8m52s   v1.13.4-k3s.1

すると、上記の様に正常に起動することができました。

■動作検証 (Pod のデプロイ)

最後に、起動した k3s 上にコンテナ (Pod) をデプロイしてみます。

今回は、こちらの記事で利用したものと同じマニフェスト (YAML ファイル) を作成し、k3s kubectl apply コマンドで適用します。

[root@k3s-master ~]# cat << EOF > ~/k3s-yaml/nginx-test.yaml 
> apiVersion: v1
> kind: Service
> metadata:
>   name: nginx-test-service
>   labels:
>     app: nginx-test
> spec:
>   selector:
>     app: nginx-test
>   type: NodePort
>   ports:
>   - protocol: TCP 
>     port: 80
>     targetPort: 80
>     nodePort: 30080
> ---
> apiVersion: apps/v1
> kind: Deployment
> metadata:
>   name: nginx-test-deployment
> spec:
>   replicas: 3
>   selector:
>     matchLabels:
>       app: nginx-test
>   template:
>     metadata:
>       labels:
>         app: nginx-test
>     spec:
>       containers:
>       - name: nginx-container
>         image: nginx:1.15.9
>         ports:
>         - containerPort: 80
>         lifecycle:
>           postStart:
>             exec:
>               command:
>                 - /bin/sh
>                 - -c
>                 - echo "NGINX container!" > /usr/share/nginx/html/index.html && echo "Pod name is \$(hostname) ." >> /usr/share/nginx/html/index.html
> EOF
[root@k3s-master ~]# k3s kubectl apply -f ~/k3s-yaml/nginx-test.yaml 
service/nginx-test-service created
deployment.apps/nginx-test-deployment created

マニフェストの詳細は割愛しますが、大雑把に説明すると以下の様な設定を実施しています。

・NGINX コンテナ (Pod) を 3つデプロイ。
・k3s をインストールした仮想サーバの 30080番 port 宛の通信を、いずれかの NGINX コンテナの 80番 port に転送。

また、どの NGINX コンテナ (Pod) からのレスポンスであるかを判断できるように、Pod 名をレスポンス (index.html) に含めるようにしています。

デプロイが完了すると、各リソースの状態が以下の様になると思います。

[root@k3s-master ~]# k3s kubectl get deployment
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
nginx-test-deployment   3/3     3            3           71s
[root@k3s-master ~]# 
[root@k3s-master ~]# k3s kubectl get service
NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes           ClusterIP   10.43.0.1              443/TCP        2d22h
nginx-test-service   NodePort    10.43.34.173           80:30080/TCP   80s
[root@k3s-master ~]# 
[root@k3s-master ~]# k3s kubectl get pod
NAME                                     READY   STATUS    RESTARTS   AGE
nginx-test-deployment-56fdfc565c-49xm9   1/1     Running   0          87s
nginx-test-deployment-56fdfc565c-jdd6m   1/1     Running   0          87s
nginx-test-deployment-56fdfc565c-m4mjp   1/1     Running   0          87s

それでは、実際に k3s をインストールした仮想サーバの 30080番 port 宛てに HTTP リクエストを投げてみます。

[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-m4mjp .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-m4mjp .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-jdd6m .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-49xm9 .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-m4mjp .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-49xm9 .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-49xm9 .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-jdd6m .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-jdd6m .
[root@k3s-master ~]# 
[root@k3s-master ~]# curl -XGET https://10.1.1.21:30080/
NGINX container!
Pod name is nginx-test-deployment-56fdfc565c-49xm9 .

すると、上記の様に正常に HTTP レスポンスが返ってきました。

何回かリクエストを実行すると、レスポンスに含まれている Pod 名が変わっている (複数の NGINX コンテナ宛てにリクエストが振り分けられている) ことも確認できます。

上記の通り基本的な機能については、k3s が通常の Kubernetes と同じように動作 (Pod のデプロイや Service での負荷分散等) していることが確認できました。

■まとめ

今回は、最近話題の k3s を試してみました。

Lightweight Kubernetes という記載の通り、実際に利用したバイナリのサイズを確認してみると約 36MB となっていました。

[root@k3s-master ~]# du -h /usr/local/bin/k3s 
36M     /usr/local/bin/k3s

また、こちらのページに記載されているシステム要件も以下の様になっており、スペックの低いマシンでも動作させることができるようです。

Minimum System Requirements

  Linux 3.10+
  512 MB of ram per server
  75 MB of ram per node
  200 MB of disk space
  x86_64, ARMv7, ARM64

実際に、今回の検証は CPU 1 core / Memory 2GB の仮想サーバ上で実施していますし、コマンド 1つで簡単に起動できるので、ちょっとした Kubernetes の動作検証には丁度良いかもしれません。

まだリリースされて日が浅く、本記事の執筆時点では Server HA 等の機能が実装されていないため、本番環境での利用は難しそうですが、よりシンプルかつ軽量な Kubernetes として今後に期待できそうです。

機会があれば、複数ノードを利用した k3s クラスタ構築にも挑戦してみようと思います。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です