はじめに
microk8sでは物足りなくなってきたので、ProxmoxVE上にKubernetesを構築してみることにしました。
備忘録も兼ねて、手順を残しておきます。
環境
ProxmoxVE 8.1.4
VM作成等の手順は省略するが、以下のような構成で構築します。
hostname | ip | role |
---|---|---|
k8s-proxy-1 | 172.16.11.1 | Proxy 1 |
k8s-proxy-2 | 172.16.11.2 | Proxy 2 |
k8s-control-1 | 172.16.11.10 | Control Plane 1 |
k8s-control-2 | 172.16.11.11 | Control Plane 2 |
k8s-control-3 | 172.16.11.12 | Control Plane 3 |
k8s-worker-1 | 172.16.11.50 | Worker 1 |
k8s-worker-2 | 172.16.11.51 | Worker 2 |
手順
一般ユーザーでは正常に完了できないものが含まれているため、これ以下の手順はすべてrootユーザーで実行してください。
Proxyの設定
k8s-proxy-1, k8s-proxy-2にhaproxyとkeepalivedをインストール・設定します。
apt install haproxy keepalived -y
以下の作業は各のサーバーで行ってください。
k8s-proxy-1
/etc/haproxy/haproxy.cfg
frontend kube-api
bind *:6443
option tcplog
mode tcp
default_backend api-6443
backend api-6443
mode tcp
balance roundrobin
server k8s-control-1 172.16.11.10:6443
server k8s-control-2 172.16.11.11:6443
server k8s-control-3 172.16.11.12:6443
/etc/keepalived/keepalived.conf
# k8s-proxy-1 keepalived config
global_defs {
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance Instance1 {
state MASTER
interface eth0
virtual_router_id 10
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass v4SevXnwLAxJ73qFx
}
unicast_src_ip 172.16.11.1 # k8s-proxy-1 Public IP
unicast_peer {
172.16.11.2 # k8s-proxy-2 Public IP
}
virtual_ipaddress {
172.16.11.0 # VRRP IP
}
track_script {
check_haproxy
}
}
k8s-proxy-2
/etc/haproxy/haproxy.cfg
frontend kube-api
bind *:6443
option tcplog
mode tcp
default_backend api-6443
backend api-6443
mode tcp
balance roundrobin
server k8s-control-1 172.16.11.10:6443
server k8s-control-2 172.16.11.11:6443
server k8s-control-3 172.16.11.12:6443
/etc/keepalived/keepalived.conf
# k8s-proxy-2 keepalived config
global_defs {
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance Instance1 {
state BACKUP
interface eth0
virtual_router_id 10
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass v4SevXnwLAxJ73qFx
}
unicast_src_ip 172.16.11.2 # k8s-proxy-2 Public IP
unicast_peer {
172.16.11.1 # k8s-proxy-1 Public IP
}
virtual_ipaddress {
172.16.11.0 # VRRP IP
}
track_script {
check_haproxy
}
}
k8s-proxy-1, k8s-proxy-2
以下のコマンドを各サーバーで実行してください。
systemctl enable haproxy
systemctl start haproxy
systemctl enable keepalived
systemctl start keepalived
Kubernetesの構築
k8s-control-1, k8s-control-2, k8s-control-3, k8s-worker-1, k8s-worker-2にKubernetesを構築します。
CRI-Oのインストール
export OS=xUbuntu_22.04
export VERSION=1.24
echo "deb [signed-by=/usr/share/keyrings/libcontainers-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb [signed-by=/usr/share/keyrings/libcontainers-crio-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
mkdir -p /usr/share/keyrings
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-archive-keyring.gpg
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-crio-archive-keyring.gpg
apt update -y && apt upgrade -y
apt install cri-o cri-o-runc cri-tools -y
systemctl enable crio.service
systemctl start crio.service
カーネルパラメータを設定する。
cat << _EOF_ > /etc/modules-load.d/crio.conf
overlay
br_netfilter
_EOF_
modprobe overlay
modprobe br_netfilter
cat << _EOF_ > /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
_EOF_
sysctl --system
swap の無効化
swapoff -a
GPG公開鍵の追加、リポジトリの追加、kubeadm / kubelet / kubectl のインストール
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
apt update
apt install -y kubeadm kubelet kubectl
ここからの作業はcontrol nodeとworker nodeで異なるため、それぞれのサーバーで実行してください。
control node
controlとして割り当てたノードのうち、1台のみ(ここではk8s-control-1)で初期化を実行していきます。
k8s-control-1
実行時に、control-plane-endpoint
でProxy Serverのフロントエンドを指定する必要があります。今回の場合、冒頭のProxy設定でfrontend kube-api
として指定されている、VRRPのIP:6443
を指定します。
また、upload-certs
コマンドを指定して、ControlNode用の証明書を暗号化し、kubeadm-certsをSecretsリソースにアップロードします。
kubeadm init --control-plane-endpoint "172.16.11.0:6443" --upload-certs
上記コマンドを実行した際に標準出力されるコマンドは、後述の手順にて必要となるため、どこかに控えておいてください。
I0620 12:25:04.219703 19748 version.go:256] remote version is much newer: v1.30.2; falling back to: stable-1.28
[init] Using Kubernetes version: v1.28.11
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
( -- 中略 -- )
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 172.16.11.0:6443 --token 5ogthw.cgv9o58h9y3yer45 \
--discovery-token-ca-cert-hash sha256:3c42a10bf34c5162e266516d8eb27e32eaf492c9ddf458ccf6664250adb81d6c \ --control-plane --certificate-key 2f09d6a8c0aaebb9ee624c5621114a43e8cef88c999025cf2c11b48a90a8baed
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 172.16.11.0:6443 --token 5ogthw.cgv9o58h9y3yer45 \
--discovery-token-ca-cert-hash sha256:3c42a10bf34c5162e266516d8eb27e32eaf492c9ddf458ccf6664250adb81d6c
k8s-control-2, k8s-control-3
controlとして割り当てたノードのうち、残りの2台(k8s-control-2, k8s-control-3)で初期化を実行します。
ここで実行するコマンドは、k8s-control-1で実行したものと異なることに注意してください。
kubeadm join 172.16.11.0:6443 --token 5ogthw.cgv9o58h9y3yer45 \
--discovery-token-ca-cert-hash sha256:3c42a10bf34c5162e266516d8eb27e32eaf492c9ddf458ccf6664250adb81d6c \ --control-plane --certificate-key 2f09d6a8c0aaebb9ee624c5621114a43e8cef88c999025cf2c11b48a90a8baed
worker node
worker node で初期化を実行します。
kubeadm join 172.16.11.0:6443 --token 5ogthw.cgv9o58h9y3yer45 \
--discovery-token-ca-cert-hash sha256:3c42a10bf34c5162e266516d8eb27e32eaf492c9ddf458ccf6664
接続確認
~/.kube/config に設定ファイルをコピーし、kubectlコマンドを実行できるようにします。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
control node で以下のコマンドを実行し、各ノードの状態を確認します。
kubectl get nodes
以下のような結果が得られたら、Kubernetesの構築は成功しています!
root@k8s-control-1:/home/chan-mai# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-control-1 Ready control-plane 41m v1.28.11
k8s-control-2 Ready control-plane 21m v1.28.11
k8s-control-3 Ready control-plane 20m v1.28.11
k8s-worker-1 Ready <none> 9m11s v1.28.11
k8s-worker-2 Ready <none> 9m8s v1.28.11
まとめ
KeepalivedとHAProxyを組み合わせることで、冗長なKubernetesプロキシを構築し、高可用性なKubernetesクラスタを構築することができました。
Controlノードを別々の場所に分散させると、いい感じの堅牢なクラスタができるかと思います。