Kubernetesらしくクラスタ環境を作りますよ!
「MicroK8sでKubernetesのお勉強」にて、シングル構成(1台だけ)の Kubernetes環境を作りましたが、Kubernetesの真髄はやはり分散環境によるロードの分散と冗長化ですので、ここでは 3台のクラスタ環境を作ります。
MicroK8sのクラスタ環境の作り方はこちら。
Create a MicroK8s cluster
1.環境
3つのサーバーは Ubuntu Server 24.04で作ります。
役割 | マシン名 | IPアドレス | CPU数 | メモリ量 |
---|---|---|---|---|
マスターノード | microk8s-master | 192.168.1.120 | 2 | 4GB |
ワーカーノード1 | microk8s-worker1 | 192.168.1.121 | 2 | 4GB |
ワーカーノード2 | microk8s-worker2 | 192.168.1.122 | 2 | 4GB |
Ubuntu Server 24.04のインストールについては「Ubuntu 24.04 Server インストール」に書いていて、その手順で作りました。
MicroK8sのバージョンは 2024年7月29日時点で 1.30.1になっています。
2.事前準備
マスターノードの [microk8s-master] でワーカーノードの [microk8s-worker1][microk8s-worker2] のマシン名を解決できるよう、マスターノードの [/etc/hosts]ファイルに以下の行を追加しておきます。
192.168.1.121 microk8s-worker1
192.168.1.122 microk8s-worker2
それから3台全てで「MicroK8sでKubernetesのお勉強」でやっている通り、MicroK8sのインストールまでやっておきます。
3.クラスタ構築
では手順に従って進めていきます。
まずマスターノードで以下の作業を行います。
これによりワーカーノードで実行するべきコマンド行が生成されます。
コマンド行が 3種類ありますが、ピンク色の行が今回の対象です。
暗号のような箇所は add-nodeを実行する度に変わります。
subro@microk8s-master:~$ sudo microk8s add-node
From the node you wish to join to this cluster, run the following:
microk8s join 192.168.1.120:25000/c855d3b0126b0fdd22a462b8cddafba2/1a7d04600797
Use the '--worker' flag to join a node as a worker not running the control plane, eg:
microk8s join 192.168.1.120:25000/c855d3b0126b0fdd22a462b8cddafba2/1a7d04600797 --worker
If the node you are adding is not reachable through the default interface you can use one of the following:
microk8s join 192.168.1.120:25000/c855d3b0126b0fdd22a462b8cddafba2/1a7d04600797
microk8s join 2408:82:a8:0:20c:29ff:fef0:c166:25000/c855d3b0126b0fdd22a462b8cddafba2/1a7d04600797
ではピンク行を [microk8s-worker1]サーバーで実行します。
subro@microk8s-worker1:~$ sudo microk8s join 192.168.1.120:25000/c855d3b0126b0fdd22a462b8cddafba2/1a7d04600797
Contacting cluster at 192.168.1.120
Waiting for this node to finish joining the cluster. .. .. .. ..
Successfully joined the cluster.
うまくいったようです。
続けて [microk8s-worker2]サーバーでもやるんですが、[microk8s-master]サーバーで microk8s add-nodeコマンドの実行からやって下さい。
どうやらこれはクラスタに新規追加する度にやるようです。
終わったら、参加しているノードを確認してみます。
(この環境では状態確認のコマンドはどのノードで実行しても取れます。)
subro@microk8s-master:~$ sudo microk8s kubectl get no
NAME STATUS ROLES AGE VERSION
microk8s-master Ready <none> 10m v1.30.1
microk8s-worker1 Ready <none> 5m9s v1.30.1
microk8s-worker2 Ready <none> 34s v1.30.1
クラスタにワーカーノードとなれるマシンが 3つになりました。
しかし実験用の PCにメモリの余裕がないので、ここではマスターノードもワーカーノードを兼ねてもらうことにしています。
クラスタの状態を見てみると、HA(high-availability)が有効になっていることが分かります。
subro@microk8s-master:~$ sudo microk8s status --wait-ready
microk8s is running
high-availability: yes
datastore master nodes: 192.168.1.120:19001 192.168.1.121:19001 192.168.1.122:19001
datastore standby nodes: none
addons:
enabled:
dns # (core) CoreDNS
ha-cluster # (core) Configure high availability on the current node
helm # (core) Helm - the package manager for Kubernetes
helm3 # (core) Helm 3 - the package manager for Kubernetes
disabled:
cert-manager # (core) Cloud native certificate management
cis-hardening # (core) Apply CIS K8s hardening
community # (core) The community addons repository
dashboard # (core) The Kubernetes dashboard
gpu # (core) Alias to nvidia add-on
host-access # (core) Allow Pods connecting to Host services smoothly
hostpath-storage # (core) Storage class; allocates storage from host directory
ingress # (core) Ingress controller for external access
kube-ovn # (core) An advanced network fabric for Kubernetes
mayastor # (core) OpenEBS MayaStor
metallb # (core) Loadbalancer for your Kubernetes cluster
metrics-server # (core) K8s Metrics Server for API access to service metrics
minio # (core) MinIO object storage
nvidia # (core) NVIDIA hardware (GPU and network) support
observability # (core) A lightweight observability stack for logs, traces and metrics
prometheus # (core) Prometheus operator for monitoring and logging
rbac # (core) Role-Based Access Control for authorisation
registry # (core) Private image registry exposed on localhost:32000
rook-ceph # (core) Distributed Ceph storage using Rook
storage # (core) Alias to hostpath-storage add-on, deprecated
とりあえずこれで kubernetesのクラスタ環境として負荷分散と冗長化をしているはずです。
4.クラスタへの Pod配備
NGiNXの Podを 9個ばかり動かしてみましょうか。
予想では 1台あたり Podが 3個ずつ動くような気がします。
Podのデプロイ用に [nginx.yaml]ファイルを以下の内容で作成しました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 9
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
デプロイします。
subro@microk8s-master:~$ sudo microk8s kubectl apply -f nginx.yaml
deployment.apps/nginx-deployment created
Podがどうなったか見てみます。
subro@microk8s-master:~$ sudo microk8s kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default pod/nginx-deployment-6cfb64b7c5-6pcdd 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-7hvtz 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-7pxst 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-9hwcn 0/1 ContainerCreating 0 20s
default pod/nginx-deployment-6cfb64b7c5-9jdqs 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-9ztcd 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-kkgcs 0/1 ContainerCreating 0 20s
default pod/nginx-deployment-6cfb64b7c5-t7rkm 0/1 ContainerCreating 0 19s
default pod/nginx-deployment-6cfb64b7c5-tpmp5 0/1 ContainerCreating 0 20s
kube-system pod/calico-kube-controllers-796fb75cc-9bmbf 1/1 Running 0 23m
kube-system pod/calico-node-9648k 1/1 Running 0 18m
kube-system pod/calico-node-mppgq 1/1 Running 0 18m
kube-system pod/calico-node-rkd96 1/1 Running 0 13m
kube-system pod/coredns-5986966c54-4lbp5 1/1 Running 0 23m
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 24m
kube-system service/kube-dns ClusterIP 10.152.183.10 <none> 53/UDP,53/TCP,9153/TCP 23m
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/calico-node 3 3 3 3 3 kubernetes.io/os=linux 23m
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
default deployment.apps/nginx-deployment 0/9 9 0 20s
kube-system deployment.apps/calico-kube-controllers 1/1 1 1 23m
kube-system deployment.apps/coredns 1/1 1 1 23m
NAMESPACE NAME DESIRED CURRENT READY AGE
default replicaset.apps/nginx-deployment-6cfb64b7c5 9 9 0 20s
kube-system replicaset.apps/calico-kube-controllers-796fb75cc 1 1 1 23m
kube-system replicaset.apps/coredns-5986966c54 1 1 1 23m
[pod/nginx-deployment-」で始まるのが 9行あり、Podは予定の数立ち上がっていることが分かります。
ワーカーノードへの分散っぷりを見てみます。
subro@microk8s-master:~$ sudo microk8s kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6cfb64b7c5-6pcdd 1/1 Running 0 7m29s 10.1.195.66 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-7hvtz 1/1 Running 0 7m29s 10.1.195.65 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-7pxst 1/1 Running 0 7m29s 10.1.166.132 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9hwcn 1/1 Running 0 7m30s 10.1.195.67 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-9jdqs 1/1 Running 0 7m29s 10.1.166.133 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9ztcd 1/1 Running 0 7m29s 10.1.170.66 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-kkgcs 1/1 Running 0 7m30s 10.1.166.131 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-t7rkm 1/1 Running 0 7m29s 10.1.170.65 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-tpmp5 1/1 Running 0 7m30s 10.1.170.67 microk8s-worker2 <none> <none>
見事に 3個ずつ別れています。\(^o^)/
5.冗長化のテスト
折角ですから、冗長化の方もやってみます。
[microk8s-worker2]サーバーをシャットダウンしてみます。
3つの Podが落ちて他のノードで立ち上がれば OK。
subro@microk8s-worker2:~$ sudo poweroff
ノードの状態を見ると [microk8s-worker2]サーバーの状態が [NotReady]になりました。
subro@microk8s-master:~$ sudo microk8s kubectl get no
NAME STATUS ROLES AGE VERSION
microk8s-master Ready <none> 36m v1.30.1
microk8s-worker1 Ready <none> 30m v1.30.1
microk8s-worker2 NotReady <none> 25m v1.30.1
5分くらい経ったでしょうか、自動的に他ノードへの切り替えが発生しました。
[microk8s-worker2]にあった Podが [Terminating]になり、他のノードで [ContainerCreating]になっているのが分かります。
subro@microk8s-master:~$ sudo microk8s kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6cfb64b7c5-6pcdd 1/1 Running 0 17m 10.1.195.66 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-6xzzd 0/1 ContainerCreating 0 1s <none> microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-7hvtz 1/1 Running 0 17m 10.1.195.65 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-7pxst 1/1 Running 0 17m 10.1.166.132 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9hwcn 1/1 Running 0 17m 10.1.195.67 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-9jdqs 1/1 Running 0 17m 10.1.166.133 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9ztcd 1/1 Terminating 0 17m 10.1.170.66 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-kkgcs 1/1 Running 0 17m 10.1.166.131 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-rk9g2 0/1 ContainerCreating 0 1s <none> microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-t7rkm 1/1 Terminating 0 17m 10.1.170.65 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-tpmp5 1/1 Terminating 0 17m 10.1.170.67 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-zn7p5 0/1 ContainerCreating 0 1s <none> microk8s-worker1 <none> <none>
その結果、[ microk8s-master]サーバーと [microk8s-worker1]サーバーに振り分けられたようです。
subro@microk8s-master:~$ sudo microk8s kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6cfb64b7c5-6pcdd 1/1 Running 0 26m 10.1.195.66 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-6xzzd 1/1 Running 0 8m57s 10.1.166.134 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-7hvtz 1/1 Running 0 26m 10.1.195.65 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-7pxst 1/1 Running 0 26m 10.1.166.132 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9hwcn 1/1 Running 0 26m 10.1.195.67 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-9jdqs 1/1 Running 0 26m 10.1.166.133 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9ztcd 1/1 Terminating 0 26m 10.1.170.66 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-kkgcs 1/1 Running 0 26m 10.1.166.131 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-rk9g2 1/1 Running 0 8m57s 10.1.195.69 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-t7rkm 1/1 Terminating 0 26m 10.1.170.65 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-tpmp5 1/1 Terminating 0 26m 10.1.170.67 microk8s-worker2 <none> <none>
nginx-deployment-6cfb64b7c5-zn7p5 1/1 Running 0 8m57s 10.1.195.68 microk8s-worker1 <none> <none>
ちゃんと HAになっていますね。
[microk8s-worker2]サーバーを起動します。
[microk8s-worker2]サーバーがクラスタに戻ってきました。
subro@microk8s-master:~$ sudo microk8s kubectl get no
NAME STATUS ROLES AGE VERSION
microk8s-master Ready <none> 58m v1.30.1
microk8s-worker1 Ready <none> 52m v1.30.1
microk8s-worker2 Ready <none> 47m v1.30.1
また [microk8s-worker2]サーバーに元通り Podが分散されているような気がするので、再度分散っぷりを見てみます。
subro@microk8s-master:~$ sudo microk8s kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6cfb64b7c5-6pcdd 1/1 Running 0 36m 10.1.195.66 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-6xzzd 1/1 Running 0 19m 10.1.166.134 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-7hvtz 1/1 Running 0 36m 10.1.195.65 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-7pxst 1/1 Running 0 36m 10.1.166.132 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-9hwcn 1/1 Running 0 36m 10.1.195.67 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-9jdqs 1/1 Running 0 36m 10.1.166.133 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-kkgcs 1/1 Running 0 36m 10.1.166.131 microk8s-master <none> <none>
nginx-deployment-6cfb64b7c5-rk9g2 1/1 Running 0 19m 10.1.195.69 microk8s-worker1 <none> <none>
nginx-deployment-6cfb64b7c5-zn7p5 1/1 Running 0 19m 10.1.195.68 microk8s-worker1 <none> <none>
しかし、待てど暮せど一向に変化がありません。
実は Kubernetesは Podの再配置はしてくれないんですね〜。
これを実現するには Deschedulerという機能を使わないといけないようです。
しかし、このネタはここまでで終わりなのでした。
Deschedulerについてはいずれ別なところで書こうと思います。
更にここでもまだ NGINXの Podにクラスタ外の PCからアクセス出来ないのでした…。
この環境でクラスタ外部からアクセスできるようにする話を「オンプレ Kubernetes環境に LoadBalancerサービスを」に書いています。
==========
というわけでオンプレで Kubernetesクラスタを作りました。
非常に簡単にできましたね。
これならマスターノードの冗長化とワーカーノードの役割の分離までやればよかったかな?
これだけでもかなりそれっぽい環境になってきましたが、まだ外部からの通信ができないので、使い物になりません。
上記の次のネタでやっとそれを実現しますので、ご期待下さい。