はじめに
Non-graceful node shutdown や kube-fencing を試してみたくなり、Kubespray+Vagrant で Kubernetes のテスト環境を作る事にしました。
Non-graceful node shutdown の詳細については毛利さんの記事を参照して下さい。
なお、この記事は3部作の1番目です。続編は以下の2つです。
- K8s v1.24 の non-graceful node shutdown を試す
- K8s v1.24 の non-graceful node shutdown を kube-fencing で自動化する
用意するもの
Vagrant がインストールされた Linux マシン
- CPU:Intel または AMD の 64bit (x86-64/amd64)
- メモリ:最低 8GB は必要です。16GB あると安心。
- ネットワーク:インターネットに接続可能なネットワークが必要です。HTTP プロキシなしを前提に説明します。
- ディストリビューション:Ubuntu でも CentOS でも構いません。私の手元では Ubuntu Linux 20.04.5 を使用しました。
- その他:Python 3, Git, VirtualBox, Vagrant をインストールしておいて下さい。
Kubespray 実行手順
Linux マシンにログインします。
後で kube-fencing を試したい場合は、kube-fencing からリモートログインする為に kubespray を実行したアカウント名やパスワードを登録しないといけなせん。そのため、kubespray 専用のアカウントを作って作業した方が良いでしょう。
GitHub から Kubespray を取ってきます。
yosshy@nuc2:~$ cd
yosshy@nuc2:~$ git clone https://github.com/kubernetes-sigs/kubespray.git
yosshy@nuc2:~$ cd kubespray
yosshy@nuc2:~/kubespray$
Ansible 用の virtualenv を作って有効にしましょう。
yosshy@nuc2:~/kubespray$ virtualenv --python=/usr/bin/python3 venv
yosshy@nuc2:~/kubespray$ source venv/bin/activate
(venv) yosshy@nuc2:~/kubespray$ pip install -r requirements.txt
Vagrantfile 中の設定を変更します。
今回は non-graceful node shutdown テストのため、1マスター+2ワーカーの3ノード構成を作ります。
あと、最近の Ansible を使うためのオマジナイも追加。
diff --git a/Vagrantfile b/Vagrantfile
index 63292bd1..123e0fa4 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -60,9 +60,9 @@ $multi_networking ||= "False"
$download_run_once ||= "True"
$download_force_cache ||= "False"
# The first three nodes are etcd servers
-$etcd_instances ||= $num_instances
+$etcd_instances ||= 1
# The first two nodes are kube masters
-$kube_master_instances ||= $num_instances == 1 ? $num_instances : ($num_instances - 1)
+$kube_master_instances ||= 1
# All nodes are kube nodes
$kube_node_instances ||= $num_instances
# The following only works when using the libvirt provider
@@ -247,6 +247,7 @@ Vagrant.configure("2") do |config|
# And limit the action to gathering facts, the full playbook is going to be ran by testcases_run.sh
if i == $num_instances
node.vm.provision "ansible" do |ansible|
+ ansible.compatibility_mode = "2.0"
ansible.playbook = $playbook
ansible.verbose = $ansible_verbosity
$ansible_inventory_path = File.join( $inventory, "hosts.ini")
inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml 中の設定を変更します。
Feature Gate をいじって、non-graceful node shutdown を有効にします。
執筆時点の Kubespray では、kube_version: に v1.24.6 が指定されています。必要であれば変更して下さい。
diff --git a/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml b/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
index af17a2cc..2dded166 100644
--- a/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
+++ b/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
@@ -155,6 +155,9 @@ kube_encrypt_secret_data: false
# kubelet_shutdown_grace_period: 60s
# kubelet_shutdown_grace_period_critical_pods: 20s
+kube_feature_gates:
+ - NodeOutOfServiceVolumeDetach=true
+
# DNS configuration.
# Kubernetes cluster name, also will be used as DNS domain
cluster_name: cluster.local
いよいよ k8s のデプロイに入ります。
特に問題なければ 3個の VM が作成され、その上に K8s クラスターがデプロイされます。
(venv) yosshy@nuc2:~/kubespray$ vagrant up
(中略)
PLAY RECAP *********************************************************************
k8s-1 : ok=813 changed=214 unreachable=0 failed=0 skipped=1068 rescued=0 ignored=4
k8s-2 : ok=497 changed=127 unreachable=0 failed=0 skipped=629 rescued=0 ignored=0
k8s-3 : ok=497 changed=127 unreachable=0 failed=0 skipped=629 rescued=0 ignored=0
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
土曜日 15 10月 2022 12:49:55 +0900 (0:00:00.200) 0:22:16.166 ***************
===============================================================================
download : download_container | Load image into the local container registry -- 43.01s
kubernetes/preinstall : Update package management cache (APT) ---------- 42.92s
kubernetes/preinstall : Install packages requirements ------------------ 37.48s
kubernetes/control-plane : kubeadm | Initialize first master ----------- 34.43s
kubernetes/kubeadm : Join to cluster ----------------------------------- 33.99s
download : download_container | Load image into the local container registry -- 33.72s
kubernetes-apps/network_plugin/flannel : Flannel | Wait for flannel subnet.env file presence -- 31.90s
download : download_container | Load image into the local container registry -- 25.73s
download : download_container | Load image into the local container registry -- 24.48s
download : download_container | Load image into the local container registry -- 21.55s
download : download_container | Load image into the local container registry -- 21.36s
container-engine/containerd : containerd | Unpack containerd archive --- 20.15s
kubernetes-apps/ansible : Kubernetes Apps | Start Resources ------------ 17.48s
download : download_container | Load image into the local container registry -- 14.53s
kubernetes/node : install | Copy kubelet binary from download dir ------ 13.67s
container-engine/validate-container-engine : Populate service facts ---- 13.46s
download : download_container | Download image if required ------------- 13.38s
download : download_file | Copy file from cache to nodes, if it is available -- 12.57s
kubernetes/preinstall : Preinstall | wait for the apiserver to be running -- 10.85s
download : download_container | Download image if required ------------- 10.76s
ノードを確認してみましょう。
(venv) yosshy@nuc2:~/kubespray$ ./inventory/sample/artifacts/kubectl.sh get nodes
NAME STATUS ROLES AGE VERSION
k8s-1 Ready control-plane 12m v1.24.6
k8s-2 Ready <none> 10m v1.24.6
k8s-3 Ready <none> 10m v1.24.6
無事に3ノード動いていますね。Pod も確認してみましょう。
(venv) yosshy@nuc2:~/kubespray$ ./inventory/sample/artifacts/kubectl.sh get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-74d6c5659f-2zftd 1/1 Running 0 170m
kube-system coredns-74d6c5659f-82ncg 1/1 Running 0 169m
kube-system dns-autoscaler-59b8867c86-sl9b7 1/1 Running 0 169m
kube-system kube-apiserver-k8s-1 1/1 Running 2 173m
kube-system kube-controller-manager-k8s-1 1/1 Running 2 (168m ago) 173m
kube-system kube-flannel-rsnf8 1/1 Running 0 171m
kube-system kube-flannel-xx5wl 1/1 Running 0 171m
kube-system kube-flannel-z5s8p 1/1 Running 0 171m
kube-system kube-proxy-grz5k 1/1 Running 1 171m
kube-system kube-proxy-vnnfq 1/1 Running 0 171m
kube-system kube-proxy-xnj64 1/1 Running 0 171m
kube-system kube-scheduler-k8s-1 1/1 Running 3 (168m ago) 173m
kube-system nginx-proxy-k8s-2 1/1 Running 0 171m
kube-system nginx-proxy-k8s-3 1/1 Running 0 171m
kube-system nodelocaldns-2xvwp 1/1 Running 0 169m
kube-system nodelocaldns-h449k 1/1 Running 0 169m
kube-system nodelocaldns-v8jhc 1/1 Running 0 169m
kubectl をそのまま実行できるようにします。
(venv) yosshy@nuc2:~/kubespray$ mkdir ~/.kube
(venv) yosshy@nuc2:~/kubespray$ cp inventory/sample/artifacts/admin.conf ~/.kube/config
(venv) yosshy@nuc2:~/kubespray$ sudo cp inventory/sample/artifacts/kubectl /usr/local/bin/
(venv) yosshy@nuc2:~/kubespray$ cd
(venv) yosshy@nuc2:~$
PVの準備
NFSサーバのセットアップ
今回は VM ホストに NFS サーバをインストールして PV のバックエンドにします。
ディストリビューションによって必要なパッケージ名は異なりますので、各ディストリビューションの NFS 関連情報に従って NFS サーバをインストールして下さい。
(venv) yosshy@nuc2:~$ sudo apt install -y nfs-kernel-server
パッケージのインストールが終わったら、/etc/exports を編集します。
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/srv/nfs4 172.18.8.0/24(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs4/pvs 172.18.8.0/24(rw,sync,no_subtree_check)
NFS でエクスポートするディレクトリを作成します。
(venv) yosshy@nuc2:~$ sudo mkdir -p /srv/nfs4/pvs
(venv) yosshy@nuc2:~$ sudo chmod 1777 /srv/nfs4/pvs
エクスポートします。
(venv) yosshy@nuc2:~$ sudo exportfs -a
(venv) yosshy@nuc2:~$ sudo exportfs
/srv/nfs4 172.18.8.0/24
/srv/nfs4/pvs 172.18.8.0/24
NFS CSI ドライバのセットアップ
GitHub から NFS CSI driver for Kubernetes のリポジトリを取ってきます。
(venv) yosshy@nuc2:~$ git clone https://github.com/kubernetes-csi/csi-driver-nfs.git
(venv) yosshy@nuc2:~$ cd csi-driver-nfs/
(venv) yosshy@nuc2:~/csi-driver-nfs$ git checkout release-4.0
次にドライバのマニフェストを適用します。
(venv) yosshy@nuc2:~/csi-driver-nfs$ ./deploy/install-driver.sh v4.0.0 local
use local deploy
Installing NFS CSI driver, version: v4.0.0 ...
serviceaccount/csi-nfs-controller-sa created
clusterrole.rbac.authorization.k8s.io/nfs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/nfs-csi-provisioner-binding created
csidriver.storage.k8s.io/nfs.csi.k8s.io created
deployment.apps/csi-nfs-controller created
daemonset.apps/csi-nfs-node created
NFS CSI driver installed successfully.
しばらくしたら CSI-NFS 関連のコンテナが動いているかどうか確認します。
(venv) yosshy@nuc2:~/csi-driver-nfs$ kubectl get pods -A | grep csi
kube-system csi-nfs-controller-84bff54b84-rk5kv 3/3 Running 0 70s
kube-system csi-nfs-node-8x9qg 3/3 Running 0 69s
kube-system csi-nfs-node-j78l5 3/3 Running 0 69s
kube-system csi-nfs-node-wjbws 3/3 Running 0 69s
(venv) yosshy@nuc2:~/csi-driver-nfs$
次に、deploy/example/storageclass-nfs.yaml を変更します。
172.18.8.1 はホストの IP アドレスです。違う場合は適宜変更して下さい。
diff --git a/deploy/example/storageclass-nfs.yaml b/deploy/example/storageclass-nfs.yaml
index 2fd2cdae..7c9e85a7 100644
--- a/deploy/example/storageclass-nfs.yaml
+++ b/deploy/example/storageclass-nfs.yaml
@@ -5,14 +5,11 @@ metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
- server: nfs-server.default.svc.cluster.local
- share: /
- # csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
- # csi.storage.k8s.io/provisioner-secret-name: "mount-options"
- # csi.storage.k8s.io/provisioner-secret-namespace: "default"
+ server: 172.18.8.1
+ share: /pvs
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
- - nconnect=8 # only supported on linux kernel version >= 5.3
+ # - nconnect=8 # only supported on linux kernel version >= 5.3
- hard
- nfsvers=4.1
上記の YAML を使って CSI-NFS の StorageClass を登録します。
(venv) yosshy@nuc2:~/csi-driver-nfs$ kubectl apply -f deploy/example/storageclass-nfs.yaml
storageclass.storage.k8s.io/nfs-csi created
(venv) yosshy@nuc2:~/csi-driver-nfs$
PVC 作成で自動的に PV が作成されるかテストします。
後でテスト用リソースを処分しやすいよう、テスト専用のネームスペース csitest を作って作業します。
(venv) yosshy@nuc2:~/csi-driver-nfs$ kubectl create ns csitest
namespace/csitest created
(venv) yosshy@nuc2:~/csi-driver-nfs$ kubectl -n csitest apply -f deploy/example/pvc-nfs-csi-dynamic.yaml
persistentvolumeclaim/pvc-nfs-dynamic created
(venv) yosshy@nuc2:~/csi-driver-nfs$ kubectl -n csitest get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-f26e733c-20f5-4108-848b-a8849c7980f8 10Gi RWX Delete Bound csitest/pvc-nfs-dynamic nfs-csi 58s
yosshy@nuc2:~/csi-driver-nfs$ kubectl delete ns csitest
namespace "csitest" deleted
(venv) yosshy@nuc2:~/csi-driver-nfs$
PVC 作成をトリガーに PV が自動作成されました。
まとめ
Kubespray と Vagrant を使って、1台の VirtualBox ホスト上に自動的に VM を作成して Kubernetes クラスタを構成できる事を確認しました。手っ取り早く複数台構成の Kubernetes 開発環境や評価環境を用意したい方には便利なソリューションの1つと言えるでしょう。