目的
Kubernetes の Master Node に冗長性を担保させるため、マルチクラスタ構成で Kubernetes Cluster を作成する。
今回は複数台の Master Node にアクセスする際にプロキシサーバを用いる。
プロキシサーバをインストールし、別マシンから Kubernetes Cluster に接続するまでをまとめる。
構成
Master Node 3 台、Worker Node 2 台利用する。
- Proxy Server: 192.168.90.1, 192.168.122.1
- master01: 192.168.122.232
- master02: 192.168.122.116
- master03: 192.168.122.18
- worker01: 192.168.122.114
- worker02: 192.168.122.79
各マシンのスペックは下記の通りとする。
- Disk: 32GB
- Cores: 8 core
- Memory: 16GB
- OS: Ubuntu 22.04
手順
HAProxy
Proxy Server で実行する。
- 実行対象
- Proxy Server
HAProxy をインストールする。
HAProxy は多機能なプロキシサーバであり、ソフトウェアロードバランサの 1 つである。
apt update
apt -y upgrade
apt -y install haproxy
デフォルト設定ファイルのバックアップを取得する。
cp -ai /etc/haproxy/haproxy.cfg{,.default}
設定ファイルを作成する。
今回は Master Node に対して接続する際、Proxy Server でアクセスを待ち受ける。
そして、受け取ったアクセスをバックエンドの Master Node に振り分ける。
cat << _EOF_ >> /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 master1 192.168.122.232:6443
server master2 192.168.122.116:6443
server master3 192.168.122.18:6443
_EOF_
設定した内容を確認する。
$ diff /etc/haproxy/haproxy.cfg{.default,}
34a35,47
>
> frontend kube-api
> bind *:6443
> option tcplog
> mode tcp
> default_backend api-6443
>
> backend api-6443
> mode tcp
> balance roundrobin
> server master1 192.168.122.232:6443
> server master2 192.168.122.116:6443
> server master3 192.168.122.18:6443
HAProxy を再起動する。
systemctl restart haproxy.service
systemctl enable haproxy.service
Kubernetes
以下の手順は Kubernetes Cluster を構成するマシン上で実行する。
- 実行対象
- master01, master02, master03, worker01, worker02
インストールを開始する前に 1 度環境をアップデートする。
apt update
apt upgrade
CRI-O
CRI-O をインストールする。
CRI-O とは Kubernetes とコンテナランタイムが通信するために規定されている CRI (Container Runtime Interface) である。
export する変数は自身の環境に沿うものに変更する。
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-get update
apt-get install cri-o cri-o-runc cri-tools
CRI-O を起動する。
systemctl enable crio.service
systemctl start crio.service
Kernel Parameter
カーネルパラメータを設定する。
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
kubeadm / kubelet / kubectl のインストール
Kubernetes をインストール・操作するために必要なソフトウェアをインストールする。
GPGキーの追加する。
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
リポジトリの追加する。
apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
kubeadm / kubelet / kubectl をインストールする。
apt update
apt install -y kubeadm kubelet kubectl
swap の無効化
swap が有効である場合は無効にする。
既に無効化されている場合は必要のない手順である。
# 一時的な swap の無効化 (再起動で有効化)
swapoff -a
# 永続的な swap の無効化
cp -p /etc/fstab{,.default}
vim /etc/fstab
## swap の設定をコメントアウトする
Kubernetes Cluster の構築
ここからの作業は Master Node と Worker Node で実行内容が異なる。
Master Node
Master Node を初期化する。
この初期化は Master Node のうちの 1 台で実行する。
- 実行対象
- master01
実行時、control-plane-endpoint
で Proxy Server のフロントエンドを指定する。
今回の場合は [HAProxy] の frontend kube-api
で指定した通り、Proxy Server の IP アドレス:6443 を指定する。
また、upload-certs
により Master Node 用の証明書を暗号化し、kubeadm-certs を Secrets リソースにアップロードする。
出力結果は後述する残りの Master Node 追加時と Worker Node 追加時に利用する。
$ kubeadm init --control-plane-endpoint "192.168.90.1:6443" --upload-certs
... (省略) ...
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 192.168.90.1:6443 --token d9tr90.jpif6a1hboo2gxk2 \
--discovery-token-ca-cert-hash sha256:c0afb2695d3b18590e9acefa7e28a9163f25b7532bf38dbd8e5c4494ad56f1d7 \
--control-plane --certificate-key 5bf2e194f4a4b49ad1457e28aa338a6cf67554eb59ccb39bdb26a4a458516b51
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 192.168.90.1:6443 --token d9tr90.jpif6a1hboo2gxk2 \
--discovery-token-ca-cert-hash sha256:c0afb2695d3b18590e9acefa7e28a9163f25b7532bf38dbd8e5c4494ad56f1d7
構築した 1 台目の Master Node に残りのマシンも追加する。
- 実行対象
- master02, master03
実行する下記のコマンドは 1 台目の Master Node 構築時に出力されたものと同等である。
kubeadm join 192.168.90.1:6443 --token d9tr90.jpif6a1hboo2gxk2 \
--discovery-token-ca-cert-hash sha256:c0afb2695d3b18590e9acefa7e28a9163f25b7532bf38dbd8e5c4494ad56f1d7 \
--control-plane --certificate-key 5bf2e194f4a4b49ad1457e28aa338a6cf67554eb59ccb39bdb26a4a458516b51
Worker Node
Worker Node を初期化する。
- 実行対象
- worker01, worker02
実行する下記のコマンドは 1 台目の Master Node 構築時に出力されたものと同等である。
Master Node 追加時とコマンドが異なることに注意する。
kubeadm join 192.168.90.1:6443 --token d9tr90.jpif6a1hboo2gxk2 \
--discovery-token-ca-cert-hash sha256:c0afb2695d3b18590e9acefa7e28a9163f25b7532bf38dbd8e5c4494ad56f1d7
接続確認
Kubernetes Cluster の kubeconfig を確認すると、下記のように server
が control-plane-endpoint として指定したものとなっている。
$ cat .kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx
server: https://192.168.90.1:6443
name: kubernetes
...
上記の config ファイルを手元に移動させ、接続確認をする。
接続確認時、Proxy Server でログファイルを tail すると、接続先の Master Node が振り分けられていることを確認できる。
# ローカル環境で実行
$ kubectl --kubeconfig config get node
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane 20m v1.27.2
master02 Ready control-plane 9m36s v1.27.2
master03 Ready control-plane 7m11s v1.27.2
worker01 Ready <none> 6m44s v1.27.2
worker02 Ready <none> 6m31s v1.27.2
# Proxy Server で実行
ubuntu@wg-r640-01:~$ tail -f /var/log/haproxy.log
... (省略) ...
xxx kube-api api-6443/master02 1/0/47 31650 -- 11/11/10/3/0 0/0
xxx kube-api api-6443/master03 1/0/23 16348 -- 11/11/10/3/0 0/0
xxx kube-api api-6443/master01 1/0/21 4934 -- 11/11/10/4/0 0/0
xxx kube-api api-6443/master02 1/0/18 4933 -- 11/11/10/3/0 0/0
まとめ
今回はプロキシサーバである HAProxy を用いることで Kubernetes のマルチ Master Node の Kubernetes Cluster を構築した。
マルチ Master Node 構成とすることで、冗長性担保以外にも Master Node を複数拠点に配置するような地理的な分散も考慮できるようになる。
次は異なるネットワークに Master Node が存在するような Kubernetes Cluster の構築をしてみたいと考えている。
今回、HAProxy を用いることで容易に Master Node を拡張し冗長性が確保できたが、HAProxy 自体に冗長性はない状態である。
この状態の場合、HAProxy 自体が障害点となりえるため、HAProxy 自体を冗長化させることが推奨される。
当該冗長化には Keepalived を用いることができる。
Keepalived はサービスの稼働状態を監視し冗長化機能を提供するオープンソースソフトウェアであるため、ロードバランサ自体の監視に基づき、障害時に自動的にバックアップに切り替えることができる。
このように、Keepalived を導入しHAProxy 自体が障害点とならないようにするのが望ましい。