minikubeはマルチノードにも対応してるというので試してみたいと思います。
前提
- mac
- minikubeがインストールされている(DriverはDocker)
標準状態(シングルノード)での動作確認
まずはシングルノードでの動作(挙動)を確認してみます。
kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 5m21s v1.25.3
minikubeというノードが1つ動いている。Roleがcontrol-planeになっているがワーカーノードも兼務?してるみたい。
というのは、下記のようにnginxを普通にデプロイしてみて、
kubectl create deployment my-www --image=nginx
kubectl expose deployment my-www --type=NodePort --port=80
minikube service my-www
podの名前を確認し、
kubectl get pods
my-www-567df47dd7-b4jbh 1/1 Running 0 10m
詳細を確認してみると、nodeとしてはcontrol-planeと同じminikubeで動いている(特にnodeとかかが追加されない)。
kubectl describe pod my-www-567df47dd7-b4jbh
ame: my-www-567df47dd7-b4jbh
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Fri, 11 Nov 2022 06:13:47 +0900
Labels: app=my-www
pod-template-hash=567df47dd7
Annotations: <none>
Status: Running
(以下、省略)
そこで、
kubectl describe node minikube
としてみると、下記のような感じでNamespaceで区別され実行されているみたいです。
(抜粋)
Non-terminated Pods: (8 in total)
Namespace Name
--------- ----
default my-www-567df47dd7-b4jbh
kube-system coredns-565d847f94-7rb2x
kube-system etcd-minikube
kube-system kube-apiserver-minikube
kube-system kube-controller-manager-minikube
kube-system kube-proxy-7blwf
kube-system kube-scheduler-minikube
kube-system storage-provisioner
(抜粋)
マルチノード化
標準ではシングルノードで動いているのをマルチノード化するためには以下の2つの方法があるようです。
start時に--nodes 3とかする
start時に以下のようにすることも可能ですが、既にクラスタが生成されている場合はaddしろ!と怒られるようです。
minikube deleteしてから再度minikube startすればOKです。
minikube start --nodes 2
node add --workerとかする
既にクラスタがある場合とかはaddも利用できるようです。
但し、私の環境では追加したnodeでCNIか有効化できず、nodeへの通信ができませんでした(調査中)。
minikube node add --worker
マルチノード化(今回)
今回はminikube start時にnode数を指定する方法でマルチノード化しました。
minikube delete #必要なら
minikube start --nodes 2
動作確認
minikube-m02というのが追加されています。
kubectl get nodes
minikube Ready control-plane 26m v1.25.3
minikube-m02 Ready <none> 21s v1.25.3
ラベルの確認
nodeSelectorやAffinityはラベル情報を利用するので、確認します。
kubectl get nodes --show-labels
ラベルは、以下のようにして追加できるようです。
kubectl label node minikube-m02 disktype=ssd
ラベルの削除はkubectl label node minikube-m02 disktype- とするみたい。
nodeSelector, Affinityの確認(Podを指定のNodeで動かす)
準備(掃除)
kubectl delete service my-www
kubectl delete deployment my-www
nodeSelector
Affinityで代用できるので最近はあまり使わないのかな?
Yamlの記述
以下のようにYamlを記述しました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-www
spec:
replicas: 1
selector:
matchLabels:
app: my-www
template:
metadata:
labels:
app: my-www
spec:
containers:
- name: my-www
image: nginx
ports:
- containerPort: 80
nodeSelector:
kubernetes.io/hostname: minikube-m02
Yamlの適用
kubectl apply -f my-www-deployment.yaml
どこのnodeで動いてるか確認
describeで確認します。minikube-m02で動いているようです。
kubectl describe pod my-www-deployment-68696dc6b7-7g9lr
Name: my-www-deployment-68696dc6b7-7g9lr
Namespace: default
Priority: 0
Service Account: default
Node: minikube-m02/192.168.49.3
Start Time: Fri, 11 Nov 2022 07:00:41 +0900
Labels: app=my-www
pod-template-hash=68696dc6b7
Annotations: <none>
Status: Running
IP: 172.17.0.2
(以下省略)
以下のコマンドでもOK
kubectl get pods -A -o wide
動作確認
Podの配置が目的なので動作確認は不要ですが、一応。
DeploymentをYamlで設定したので、ServiceもYamlで書いてみます。
apiVersion: v1
kind: Service
metadata:
name: my-www
spec:
ports:
- port: 80
selector:
app: my-www
type: NodePort
適用と動作確認。
kubectl apply -f my-www-service.yaml
minikube service my-www
nodeAffinity
Yamlの編集
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-www
spec:
replicas: 1
selector:
matchLabels:
app: my-www
template:
metadata:
labels:
app: my-www
spec:
containers:
- name: my-www
image: nginx
ports:
- containerPort: 80
# nodeSelector:
# kubernetes.io/hostname: minikube-m02
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- "minikube-m02"
Yamlの適用
kubectl apply -f my-www-deployment.yaml
動作確認
nodeSelectorと同じなので割愛。
解説(最低限)
nodeAffinityには以下の2種類がある。
- requiredDuringSchedulingIgnoredDuringExecution
- preferredDuringSchedulingIgnoredDuringExecution
前者は指定したnodeで動かす(nodeSelectorと同じようなもの)。後者は指定したnode優先だが、NGなら他のnodeでもよい。
条件指定には、以下がある。
- matchExpressions
- matchFields
前者はLabelに対する条件指定で、後者はオブジェクトフィールドに対する条件指定らしい。
operatorにはIn Not Inとかもあるし、Anti AffinityとかTaintsとかいろいろあるけど、あまり使わないのでとりあえずこの記事ではここまで。詳細は本家のドキュメントなどを参照。
参考
ありがとうございます。