KubesprayによるKubernetesのインストール
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}"