Kubernetesの環境を触ってみなくなり、Kubernetesのインストール方法でKubesprayが便利そうだったので、KubesprayによるKubernetesのインストールを試してみました。
構成
- vCenter 7.0 U3
- ESXi 7.0 Update 3
- Ubuntu 22.04 (テンプレートVM)
- open-vm-tools 11.3.5
- cloud-init 22.2
- Kubespray
- kubernetes v1.25.5
Kubesprayのダウンロード
Kubesprayをダウンロードします。
git clone https://github.com/kubernetes-sigs/kubespray
Ansibleのインストール
こちらの手順を確認しながら、venvの環境をインストールし、Ansibleをインストールしていきます。
kubespray/ansible.md at master · kubernetes-sigs/kubespray · GitHub
$ VENVDIR=kubespray-venv $ KUBESPRAYDIR=kubespray $ ANSIBLE_VERSION=2.12 $ python3 -m venv $VENVDIR $ source $VENVDIR/bin/activate $ cd $KUBESPRAYDIR $ pip install -U -r requirements-$ANSIBLE_VERSION.txt $ test -f requirements-$ANSIBLE_VERSION.yml && \ ansible-galaxy role install -r requirements-$ANSIBLE_VERSION.yml && \ ansible-galaxy collection -r requirements-$ANSIBLE_VERSION.yml
インベントリの作成
インベントリを作成していきます。リポジトリの中のsampleディレクトリをコピーし、自身の環境向けのhostファイルやgroup_varsを用意できます。
cp -r inventory/sample inventory/mycluster declare -a IPS=(10.0.50.30 10.0.50.31 10.0.50.32 10.0.50.33 10.0.50.34) CONFIG_FILE=inventory/mycluster/hosts.yml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
hosts.ymlファイルが生成されますが、構成を変えたいので、以下のように変更します。
今回はmasterノード3台とworkerノード2台にしています。
$ vi hosts.yml all: hosts: kube-master01: ansible_host: 10.0.50.30 ip: 10.0.50.30 access_ip: 10.0.50.30 kube-master02: ansible_host: 10.0.50.31 ip: 10.0.50.31 access_ip: 10.0.50.31 kube-master03: ansible_host: 10.0.50.32 ip: 10.0.50.32 access_ip: 10.0.50.32 kube-worker01: ansible_host: 10.0.50.33 ip: 10.0.50.33 access_ip: 10.0.50.33 kube-worker02: ansible_host: 10.0.50.34 ip: 10.0.50.34 access_ip: 10.0.50.34 children: kube_control_plane: hosts: kube-master01: kube-master02: kube-master03: kube_node: hosts: kube-worker01: kube-worker02: etcd: hosts: kube-master01: kube-master02: kube-master03: k8s_cluster: children: kube_control_plane: kube_node: calico_rr: hosts: {}
masterノードとworkerノードのデプロイ
以前、cloud-initを利用した仮想マシンのカスタマイズを書きましたが、Kubernetesの再作成が簡単になるため利用します。
Ubuntu 22.04のテンプレートを作成し、以下のスペックでテンプレートを用意しておきます。
- CPU: 1vCPU
- Memory: 4GB
- Disk: 100GB
masterノードとworkerノードのスペックはそれぞれの以下の通りになります。
node | vCPU | Memory | Disk |
---|---|---|---|
master | 1 | 4GB | 100GB |
worker | 1 | 4GB | 100GB |
cloud-initでmasterノードとworkerノードのIPアドレスと公開鍵を設定を行っていきます。
IPアドレスを設定するために、以下のようにmetadataを作成します。こちらは仮想マシンごとにファイルを作成しておきます。
$ vi metadata-kube-master01.yaml instance-id: kube-master01 local-hostname: kube-master01 hostname: kube-master01 network: version: 2 ethernets: ens192: dhcp4: false addresses: - 10.0.50.30/24 gateway4: 10.0.50.1 nameservers: addresses: - 10.0.50.1
公開鍵を設定するために、以下のようにuserdataを作成します。こちらは全体で共通のファイルを作成しておきます。
$ vi userdata-kube.yaml #cloud-config users: - default - name: username ssh_authorized_keys: - 公開鍵をペースト sudo: ALL=(ALL) NOPASSWD:ALL groups: sudo, wheel lock_passwd: true shell: /bin/bash
firewallは閉じられているため変更はしていません。
$ sudo ufw status Status: inactive
govcによるメタデータの追加
govcを利用するための環境変数を設定します。
$ export GOVC_URL=https://<vcenter fqdn>/sdk $ export GOVC_USERNAME="username" $ export GOVC_PASSWORD="password" $ export GOVC_INSECURE="1"
masterノードとworkerノードごとに以下のコマンドを実行し、masterノードとworkerノードの仮想マシンをデプロイします。
$ export VMNAME="kube-master01" $ export VM="/Datacenter/vm/path/to/$VMNAME" $ govc vm.info "${VM}" $ export METADATA=$(gzip -c9 <metadata-${VMNAME}.yaml | { base64 -w0 2>/dev/null || base64; }) USERDATA=$(gzip -c9 <userdata-kube.yaml | { base64 -w0 2>/dev/null || base64; }) $ govc vm.change -vm "${VM}" -e guestinfo.metadata="${METADATA}" -e guestinfo.metadata.encoding="gzip+base64" -e guestinfo.userdata="${USERDATA}" -e guestinfo.userdata.encoding="gzip+base64" $ govc vm.power -on "${VM}"
以下のようにコマンドを実行すれば、まとめて仮想マシンをデプロイできます。
$ for VMNAME in kube-master0{1..3}; do echo ${VMNAME} export VM="/Datacenter/vm/path/to/$VMNAME" govc vm.clone -vm template-vm -on=false -folder="/Datacenter/vm/k8s" $VMNAME export METADATA=$(gzip -c9 <metadata-${VMNAME}.yaml | { base64 -w0 2>/dev/null || base64; }) USERDATA=$(gzip -c9 <userdata-kube.yaml | { base64 -w0 2>/dev/null || base64; }) govc vm.change -vm "${VM}" -e guestinfo.metadata="${METADATA}" -e guestinfo.metadata.encoding="gzip+base64" -e guestinfo.userdata="${USERDATA}" -e guestinfo.userdata.encoding="gzip+base64" govc vm.power -on "${VM}" done
$ for VMNAME in kube-worker0{1..2}; do echo ${VMNAME} export VM="/Datacenter/vm/path/to/$VMNAME" govc vm.clone -vm template-vm -on=false -folder="/Datacenter/vm/k8s" $VMNAME export METADATA=$(gzip -c9 <metadata-${VMNAME}.yaml | { base64 -w0 2>/dev/null || base64; }) USERDATA=$(gzip -c9 <userdata-kube.yaml | { base64 -w0 2>/dev/null || base64; }) govc vm.change -vm "${VM}" -e guestinfo.metadata="${METADATA}" -e guestinfo.metadata.encoding="gzip+base64" -e guestinfo.userdata="${USERDATA}" -e guestinfo.userdata.encoding="gzip+base64" govc vm.power -on "${VM}" done
Kubesprayによるクラスタ構築
以下のコマンドでKubernetesクラスタを構築することができます。
$ ansible-playbook -i inventory/mycluster/hosts.yml --become --become-user=root cluster.yml
以下のようにログが出力され無事構築が完了します。30分程度で構築が完了します。
TASK [network_plugin/calico : Check if inventory match current cluster configuration] ************************************** ok: [kube-master01] => { "changed": false, "msg": "All assertions passed" } Thursday 22 December 2022 07:56:58 +0900 (0:00:00.101) 0:33:20.265 ***** Thursday 22 December 2022 07:56:58 +0900 (0:00:00.060) 0:33:20.325 ***** Thursday 22 December 2022 07:56:58 +0900 (0:00:00.060) 0:33:20.386 ***** PLAY RECAP ***************************************************************************************************************** kube-master01 : ok=744 changed=146 unreachable=0 failed=0 skipped=1270 rescued=0 ignored=9 kube-master02 : ok=652 changed=135 unreachable=0 failed=0 skipped=1110 rescued=0 ignored=4 kube-master03 : ok=654 changed=136 unreachable=0 failed=0 skipped=1108 rescued=0 ignored=4 kube-worker01 : ok=507 changed=93 unreachable=0 failed=0 skipped=775 rescued=0 ignored=2 kube-worker02 : ok=507 changed=93 unreachable=0 failed=0 skipped=775 rescued=0 ignored=2 localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 Thursday 22 December 2022 07:56:58 +0900 (0:00:00.189) 0:33:20.576 ***** =============================================================================== download : download_container | Download image if required --------------------------------------------------------- 55.77s download : download_file | Download item --------------------------------------------------------------------------- 51.95s download : download_container | Download image if required --------------------------------------------------------- 51.70s network_plugin/calico : Wait for calico kubeconfig to be created --------------------------------------------------- 47.02s kubernetes/control-plane : Joining control plane node to the cluster. ---------------------------------------------- 46.59s container-engine/containerd : download_file | Download item -------------------------------------------------------- 28.89s download : download_file | Validate mirrors ------------------------------------------------------------------------ 28.20s download : download_file | Download item --------------------------------------------------------------------------- 27.57s download : download_container | Download image if required --------------------------------------------------------- 26.08s kubernetes/control-plane : kubeadm | Initialize first master ------------------------------------------------------- 25.96s kubernetes/preinstall : Preinstall | wait for the apiserver to be running ------------------------------------------ 24.94s kubernetes/preinstall : Install packages requirements -------------------------------------------------------------- 24.79s kubernetes/preinstall : Update package management cache (APT) ------------------------------------------------------ 24.47s etcd : reload etcd ------------------------------------------------------------------------------------------------- 23.30s download : download_file | Download item --------------------------------------------------------------------------- 23.14s kubernetes/kubeadm : Join to cluster ------------------------------------------------------------------------------- 21.30s download : download_container | Download image if required --------------------------------------------------------- 20.24s container-engine/crictl : download_file | Download item ------------------------------------------------------------ 20.20s download : download_container | Download image if required --------------------------------------------------------- 20.11s download : download_container | Download image if required --------------------------------------------------------- 17.82s
kubectlのインストール
Ansibleの実行ノードにkubectlをインストールしていきます。
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add OK $ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" $ sudo apt update $ sudo apt install kubectl
masterノードから /etc/kubernetes/admin.conf
を取得します。
admin.confを取得するために、masterノードにログインし、ファイルの権限を変更しておきます。
$ ssh $USERNAME@$IP_CONTROLLER_0 $ USERNAME=$(whoami) $ sudo chown -R $USERNAME:$USERNAME /etc/kubernetes/admin.conf $ exit
masterノードから /etc/kubernetes/admin.conf
を取得します。
scp -v $USERNAME@$IP_CONTROLLER_0:/etc/kubernetes/admin.conf kubespray-do.conf
serverのIPアドレスをmasterノードのIPアドレスに書き換えを行います。
$ vi kubespray-do.conf apiVersion: v1 clusters: - cluster: certificate-authority-data: XXX server: https://10.0.50.30:6443 # 書き換え name: cluster.local ...
設定をロードして、接続ができることを確認します。
$ export KUBECONFIG=$PWD/kubespray-do.conf $ kubectl get nodes NAME STATUS ROLES AGE VERSION kube-master01 Ready control-plane 23h v1.25.5 kube-master02 Ready control-plane 23h v1.25.5 kube-master03 Ready control-plane 23h v1.25.5 kube-worker01 Ready <none> 23h v1.25.5 kube-worker02 Ready <none> 23h v1.25.5
スモークテスト
動作確認を行います。
テスト用のpodを2台作成し、pod間で疎通が取れるか確認します。
$ kubectl run myshell1 -it --rm --image busybox -- sh / # hostname -i 10.233.68.2 / # ping 10.233.92.3 PING 10.233.92.3 (10.233.92.3): 56 data bytes 64 bytes from 10.233.92.3: seq=0 ttl=62 time=0.659 ms 64 bytes from 10.233.92.3: seq=1 ttl=62 time=0.419 ms ^C --- 10.233.92.3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.419/0.539/0.659 ms
kubectl run myshell2 -it --rm --image busybox -- sh / # hostname -i 10.233.92.3 / # ping 10.233.68.2 PING 10.233.68.2 (10.233.68.2): 56 data bytes 64 bytes from 10.233.68.2: seq=0 ttl=62 time=1.144 ms 64 bytes from 10.233.68.2: seq=1 ttl=62 time=0.489 ms 64 bytes from 10.233.68.2: seq=2 ttl=62 time=0.402 ms ^C --- 10.233.68.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.402/0.678/1.144 ms
podの状態は以下の通りです。
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myshell1 1/1 Running 0 4m34s 10.233.68.2 kube-worker01 <none> <none> myshell2 1/1 Running 0 7s 10.233.92.3 kube-worker02 <none> <none>
デプロイメント
nginxのdeploymentを作成します。
port-forwardを行い、nginxへcurlでアクセスができることを確認します。
$ kubectl create deployment nginx --image=nginx $ kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE nginx-76d6c9b8c-kt6td 1/1 Running 0 13m $ POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}") $ kubectl port-forward $POD_NAME 8080:80 $ curl --head http://127.0.0.1:8080
動作確認ができため、deploymentを削除しておきます。
$ kubectl delete deployment nginx
リセット
以下のコマンドでKubernetesクラスタをリセットすることができます。
$ ansible-playbook -i inventory/mycluster/hosts.yml --become --become-user=root reset.yml
リセット後にKubesprayで再構築を行いましたが、再構築に失敗したため、仮想マシンごと削除して、govcで仮想マシンの再作成を行う行うことで、Kubernetesクラスタを何度も構築することができます。
$ govc vm.destroy "${VM}"