TL;DR
- めちゃくちゃ軽量なK8sディストリビューション「K3s」をUbuntu Serverで動かす
- マスター(server)1台、ワーカー(agent)2台のKubernetes(K3s)クラスタを組む
- deployment、service、ingressをデプロイする(サンプルymlあり)
構成
K3sをコントロールするマスター(server)を1台と、コンテナ(Pod)を動かすワーカー(agent)を2台用意します。
最低限しか書いていないので厳密にはもっと複雑ですが、こんな感じです。
クラウドVMでも、ローカルマシン上にVMを立てても、物理マシンを用意しても大丈夫です。
私の場合はローカルマシン(CPU:i5-10500)のHyper-V上にUbuntu Serverの仮想マシンを作成しました。
OSバージョン | 20.04.2 LTS (Focal Fossa) |
---|---|
CPU | 1コア |
メモリ | 1GB |
構築
以下の流れで構築していきます。
- ホスト名を一意に設定したUbuntu Serverを3台用意
- 各サーバで/etc/hostsを設定
- マスターノードでK3sインストール & 起動
- ワーカーノードでK3sインストール & クラスタに追加
- リソースのデプロイ
1. ホスト名を一意に設定したUbuntu Serverを3台用意する
ホスト名を重複させないようにするため、以下のように設定をしました。
マスターノード | ワーカーノード1 | ワーカーノード2 | |
---|---|---|---|
ホスト名 | k3s-master | k3s-wk1 | k3s-wk2 |
IPアドレス | 192.168.1.150 | 192.168.1.151 | 192.168.1.152 |
ホスト名が重複する場合は、環境変数もしくは起動時のオプションで一意なノード名を指定する必要があります。
環境変数の場合 $K3S_NODE_NAME
起動時のオプションの場合 --node-name ノード名
2. 各サーバで/etc/hostsを設定する
各ノードの/etc/hostsに情報を追記します。
- 単純に名前解決できたほうが楽
- issue「cannot run k3s server」の対応策としてhostsに定義を追加することが有効である
マスターノード(k3s-master)の/etc/hosts
root@k3s-master:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 k3s-master
192.168.1.150 k3s-master
192.168.1.151 k3s-wk1
192.168.1.152 k3s-wk2
ワーカーノード1(k3s-wk1)の/etc/hosts
root@k3s-wk1:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 k3s-wk1
192.168.1.150 k3s-master
192.168.1.151 k3s-wk1
192.168.1.152 k3s-wk2
ワーカーノード2(k3s-wk2)の/etc/hosts
root@k3s-wk2:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 k3s-wk2
192.168.1.150 k3s-master
192.168.1.151 k3s-wk1
192.168.1.152 k3s-wk2
3. マスターノードでK3sインストール & 起動
K3sが用意しているインストールスクリプトを使います。
root@k3s-master:~# curl -sfL https://get.k3s.io | sh -
[INFO] Finding release for channel stable
(中略)
[INFO] systemd: Starting k3s
root@k3s-master:~#
スクリプトの実行が完了するとK3sが起動しているはずです。
kubectlコマンドでnodeが起動していることを確認できます。
root@k3s-master:~# k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 2m3s v1.21.1+k3s1
次はワーカーノードの起動ですが、その前に...
クラスタに組み込むために必要な情報(トークン)がマスターノードにあるので確認しておきます。
root@k3s-master:~# cat /var/lib/rancher/k3s/server/token
K109adb1784f9ffbc3ff5e272a6956d9407d7f96f9fcf742586c9fc108a031fc9b9::server:1158cefa7ef95ea0894d3446079d9c4a
4. ワーカーノードでK3sインストール & クラスタに追加
マスターノードでの起動とトークン確認が終わったら、次はワーカーノードでの作業です。
マスターノードと同じようにインストールスクリプトを使って導入していきます。
ただし、ワーカーノードとして起動させるためのオプション指定があるため、少しコマンドが異なります。
- K3S_TOKENにマスターノードで確認した情報(トークン)を設定する
- K3S_URLにマスターノードの6443ポートを設定する
root@k3s-wk1:~# curl -sfL https://get.k3s.io |\
K3S_TOKEN="K109adb1784f9ffbc3ff5e272a6956d9407d7f96f9fcf742586c9fc108a031fc9b9::server:1158cefa7ef95ea0894d3446079d9c4a" \
K3S_URL=https://k3s-master:6443 sh -
[INFO] Finding release for channel stable
(中略)
[INFO] systemd: Starting k3s-agent
root@k3s-wk1:~#
マスターノードに戻って、kubectlコマンドでワーカーノードが追加されていることを確認できます。
root@k3s-master:~# k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 17m v1.21.1+k3s1
k3s-wk1 Ready <none> 20s v1.21.1+k3s1
もう一台のワーカーノードでも同じインストールコマンドを実行することで、同様にクラスタに追加されます。
root@k3s-wk2:~# curl -sfL https://get.k3s.io |\
> K3S_TOKEN="K109adb1784f9ffbc3ff5e272a6956d9407d7f96f9fcf742586c9fc108a031fc9b9::server:1158cefa7ef95ea0894d3446079d9c4a" \
> K3S_URL=https://k3s-master:6443 sh -
[INFO] Finding release for channel stable
(中略)
[INFO] systemd: Starting k3s-agent
------------------------------------------------------------------------
root@k3s-master:~# k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 24m v1.21.1+k3s1
k3s-wk1 Ready <none> 7m4s v1.21.1+k3s1
k3s-wk2 Ready <none> 1s v1.21.1+k3s1
5. リソースをデプロイする
ここまで来たらあとはいつものKubernetesと同じように
kubectlコマンドを使ってリソースをデプロイできます。
ただ、今回はk3sの特徴を生かした自動デプロイ機能を使ってみます。
Any file found in /var/lib/rancher/k3s/server/manifests will automatically be deployed to Kubernetes in a manner similar to kubectl apply.
/var/lib/rancher/k3s/server/manifests にファイルを配置することで、自動的にKubernetesにデプロイされます(kubectl applyのように)
5-1. 使用するリソース
今回はK3sを動かすことにフォーカスしているので、そんなに凝ったものはデプロイしません。
nginxが動くpod(deploymentから作成します)、pod接続用のservice、serivceの外部公開ロードバランサのingressで構成しています。
serviceは8088番ポートでトラフィックを受け、podの80番ポートへトラフィックを流します。
Loadbalancerタイプのserviceを作成すればingressは無しでもOKです
今回使用したymlはgithubに公開しておいたので、K3sを試したい方は使ってください。
root@k3s-master:~# git clone https://github.com/otsukousan/sample-k3s-resource.git
5-2. deployment
root@k3s-master:~# cp deployment.yml /var/lib/rancher/k3s/server/manifests/deployment.yml
(十数秒後)
root@k3s-master:~# k3s kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7dc45fbd74-dfjg6 1/1 Running 0 23s
nginx-7dc45fbd74-lc5q7 1/1 Running 0 23s
nginx-7dc45fbd74-bjgxq 1/1 Running 0 23s
root@k3s-master:~# k3s kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7dc45fbd74-dfjg6 1/1 Running 0 31s 10.42.2.9 k3s-wk2 <none> <none>
nginx-7dc45fbd74-lc5q7 1/1 Running 0 31s 10.42.2.8 k3s-wk2 <none> <none>
nginx-7dc45fbd74-bjgxq 1/1 Running 0 31s 10.42.1.11 k3s-wk1 <none> <none>
きちんと各ノードに分散配置されていますね。
試しにpodの中から自身のnginxに向かってcurlを打ってみました。
root@k3s-master:~# k3s kubectl exec -it nginx-7dc45fbd74-dfjg6 -- curl http://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@k3s-master:~#
いつものやつ🤗
5-3. service
serviceもdeploymentと同様に自動デプロイ機能を使ってデプロイします。
root@k3s-master:~# cp service.yml /var/lib/rancher/k3s/server/manifests/service.yml
(数秒後)
root@k3s-master:~# k3s kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 62m
nginx-service ClusterIP 10.43.74.131 <none> 80/TCP 6s
root@k3s-master:~#
5-4. ingress
ingressも同様です。
root@k3s-master:~# cp ingress.yml /var/lib/rancher/k3s/server/manifests/ingress.yml
(数秒後)
root@k3s-master:~# k3s kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress <none> * 192.168.1.150,192.168.1.151,192.168.1.152 80 12s
root@k3s-master:~#
ちなみにK3sはTraefikというingressコントローラが標準で入っているので、コントローラのデプロイなしで使用することができます。
逆にTrarfik以外のingressコントローラを使う場合は、マスターノードでのk3s起動時に指定が必要みたいです。
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -
結果確認
ローカルPCのブラウザからingressで公開したアドレスを入力するとnginxのトップページが表示されました。
また、podのログからもアクセスが来ていることがわかります。
root@k3s-master:~# k3s kubectl logs nginx-7dc45fbd74-dfjg6
(中略)
10.42.0.7 - - [26/Jun/2021:10:30:28 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" "10.42.0.1"
------------------------------------------------------------------------
root@k3s-master:~# k3s kubectl logs nginx-7dc45fbd74-lc5q7
(中略)
10.42.0.7 - - [26/Jun/2021:10:35:18 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" "10.42.0.1"
------------------------------------------------------------------------
root@k3s-master:~# k3s kubectl logs nginx-7dc45fbd74-bjgxq
(中略)
10.42.0.7 - - [26/Jun/2021:10:30:31 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" "10.42.0.1"
お疲れさまでした!!!
感想
マネージドサービスを使わずにKubernetesクラスタを組んだのは初めてでしたが、思ったよりもスムーズに進められました。
せっかく軽量なKubernetesなので、今度はシングルボードコンピュータでk3sクラスタを組んで遊ぼうと思います。
参考
日本語版k3s マニュアルダウンロード - 株式会社スタイルズ
k3s でクラスタ (Master 1台/Worker 2台) を構築してみた - SIOS TECH.LAB