About this page
自宅でKubernetesクラスタを作りたかったが、
物理マシンは配線がめんどくさいのでVMでクラスタを作ることにした。
KVMのインストール〜Kubernetesのインストールまでのただの作業記録。
Host setup
install KVM
sudo apt-get install kvm
install GUI tools
GUI使わない場合は、不要。
sudo apt-get install virt-manager virt-viewer
hostからguestの名前解決ができるようにする
ssh <vm_name>
でsshが通るようにしたい。
sudo apt-get install libnss-libvirt
/etc/nsswitch.conf
を開き、hosts
行にlibvirt
とlibvirt_guest
を追記する。
- libvirt: Guest OSに設定したHostnameで名前解決できるようになる
- libvirt_guest: libvirtで作成したVM名で名前解決できるようになる
# /etc/nsswitch.conf
hosts: files libvirt libvirt_guest dns
create pool
VMのディスク領域を格納するためのリソース。targetのディレクトリは予め作り、libvirt-qemuがアクセスできるようにパーミッションを与えておく。
virsh pool-define-as default dir --target /media/data/libvirt/images/
Guest OS setup
download linux iso
適当にlinuxのisoイメージをダウンロードしてくる。ここではubuntu22.04を選択した。
create vm
vmを作成する。
virt-install --name myvm1 \
--memory 2048 --vcpus 2 --disk size=8 \
--cdrom /media/data/libvirt/isos/ubuntu-22.04.4-desktop-amd64.iso
VMにlogin
GUI
virt-manager
立ち上げるVMをダブルクリックすると、GUIが立ち上がる。
もしくは、virt-viewerで直接VMを指定してもOK。
virt-viewer myvm1
CUI
virsh consoleでコンソールに接続できる。
$ virsh console myvm1
Connected to domain 'myvm1'
Escape character is ^] (Ctrl + ])
me@node01:~$
Guest OS設定
いつものように、普通にUbuntuをインストールする…。
sshdの設定
sshdを有効にして外部からsshでログインできるようにする。
sudo apt-get update
sudo apt-get install ssh vim -y
sudo vim /etc/sshd_config
以下を追加する。
Port 22
PermitRootLogin no
PasswordAuthentication yes
設定を変更したのでsshdサービスを再起動する。
sudo service sshd restart
ホストからsshでログインできるようになる。
$ ssh myvm1
上記の手順を2回行い、Ubuntu VMを2つ準備した。
Kubernetesをインストールする
swapをoff
kubeletが正常に動作するためにはswapは必ずオフでなければなりません。
# swapの確認
sudo swapon --show
# swapの無効化
sudo swapoff -a
/etc/fstab
をエディタで開いてswapの行をコメントアウト
# /etc/fstab: static file system information.
#/swapfile none swap sw 0 0
cri-o, kubelet, kubeadmのinstall
コンテナランタイムは、適当にcri-oを選ぶ。
上記はcri-oのインストール手順のページだが、kubeletやkubeadmのインストール手順まで、丁寧にほぼすべて書いてある
依存パッケージのインストール
sudo apt-get update
sudo apt-get install -y software-properties-common curl
バージョンの指定
KUBERNETES_VERSION=v1.30
PROJECT_PATH=prerelease:/main
Kubernetesのリポジトリを追加する
curl -fsSL https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/Release.key |
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/ /" |
sudo tee /etc/apt/sources.list.d/kubernetes.list
CRI-Oのリポジトリを追加する
curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/Release.key |
gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/ /" |
tee /etc/apt/sources.list.d/cri-o.list
cri-o, kubelet, kubeadm, kubectlのインストール
apt-get update
apt-get install -y cri-o kubelet kubeadm kubectl
cri-oの起動
systemctl start crio.service
bootstrapの設定
modprobe br_netfilter
sysctl -w net.ipv4.ip_forward=1
ここまでは共通
Controle Plane Nodeの設定
後でCalicoを入れたいので、pod-network-cidrを以下のように指定する。
kubeadm init --pod-network-cidr=192.168.0.0/16
しばらく待っていると、次のようなスニペットがターミナルに表示される。
kubeadm join 192.168.122.XXX:6443 --token <<token>> \
--discovery-token-ca-cert-hash <<hash>>
Worker Nodeの設定
上記のコマンドをコピペして、実行するだけ。
kubeconfigの設定
/etc/kubernetes以下に生成されているので、ローカルにコピーする。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectlを叩くと、node一覧を取得できた。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
node01 Ready control-plane 45m v1.30.0
node02 Ready <none> 43m v1.30.0
CNIのインストール
前述の通り、Calicoをインストールする。
公式の手順そのまま。
operatorとcrdをインストールする。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml
calicoをインストールするために必要なCustom Resourceを作成する。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/custom-resources.yaml
1分ちょっと待つと、calicoのpodが起動する。
$ kubectl get po -n calico-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-58dc9899f-9v5zr 1/1 Running 0 93s
calico-node-57xs2 1/1 Running 0 94s
calico-node-fv5zs 1/1 Running 0 94s
calico-typha-65b5b98d54-k9jzv 1/1 Running 0 94s
csi-node-driver-8r5cg 2/2 Running 0 93s
csi-node-driver-b92xh 2/2 Running 0 93s
通信テスト
node01と02にそれぞれpodを立てて、通信できることを確認してみる。
まずはサーバ用のPodを作成する。特に何も指定しないので、worker nodeであるnode02の方にPodが作成されるはず。
kubectl run nginx --image nginx
kubectl expose nginx --port 80
クライアント用のPodをたてる。こちらはnode01に作成したい。node01はcontrol-planeのためtaintがついており、そのままではPodが作成できないのでtolerationを設定した上でnodeNameを指定する。
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
labels:
run: client
name: client
spec:
containers:
- image: ubuntu
name: client
command:
- sleep
- "3600"
nodeName: node01
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
EOF
作成したPodの確認。想定通り別々のnodeに立っている。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 19m 192.168.140.67 node02 <none> <none>
client 1/1 Running 0 10m 192.168.196.131 node01 <none> <none>
clientに入る。
kubectl exec -it client -- bash
serverへのアクセスを確認。
$ apt-get update && apt-get install -y curl
$ curl nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
ちゃんと通信できた。