シン・お家クラウドを構築する【1】- HAなk8sのセットアップ編
寒い冬も明け、心地よい日差しと爽やかな風、静寂を掻き消すサーバの音に新たな芽吹き。
ファンの爆音にツバメも目を覚ます頃でしょうか
エモいですね~
どうもmurasameです
本日は、新しく届いたサーバのセットアップをする過程でk8sの構成の刷新をしたのでそれについての轍を掲載していこうかなぁと思います。
解説ほぼなしで、手順だけ乗っけていきます。
サーバの紹介
今回セットアップするサーバの紹介を少し、
Node | CPU | MEM |
---|---|---|
mackerel | Xeon E5-2667 v4 *2 | 64GB |
puffer | Xeon E5-2667 v4 *2 | 64GB |
yellowtail | Xeon E5-2667 v4 *2 | 64GB |
shark | Xeon E5-2667 v4 *2 | 64GB |
全体に 16c/32tで構成されており、メモリは64GBの構成です。
kubernetesの構築
今回構築していくk8sの構成はこんな感じです。
Node | Hostname | CIDR | type | CPU / MEM / STO |
---|---|---|---|---|
mackerel | k8s2-ha-proxy-1 | 10.0.1.4/8 | LXC | 1vCPU / 1GB / SSD 10GB |
mackerel | k8s2-ha-proxy-2 | 10.0.1.5/8 | LXC | 1vCPU / 1GB / SSD 10GB |
mackerel | k8s2-master-1 | 10.0.1.1/8 | VM | 4vCPU / 16GB / SSD 100GB |
mackerel | k8s2-master-2 | 10.0.1.2/8 | VM | 4vCPU / 16GB / SSD 100GB |
mackerel | k8s2-master-3 | 10.0.1.3/8 | VM | 4vCPU / 16GB / SSD 100GB |
puffer | k8s2-slave-1 | 10.0.2.1/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
puffer | k8s2-slave-2 | 10.0.2.2/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
yellowtail | k8s2-slave-3 | 10.0.3.1/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
yellowtail | k8s2-slave-4 | 10.0.3.2/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
shark | k8s2-slave-5 | 10.0.4.1/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
shark | k8s2-slave-6 | 10.0.4.2/8 | VM | 8vCPU*2 / 32GB / SSD 100GB |
全体的に扱うのはubuntu server 22.04を利用します。
puffer, yellowtail,sharkをVMで2分割してる理由としては、単純にたくさんノードを扱いたかっただけです。
最終的にこんな感じの構成になればいいかなぁと考えてます
LBの構築
masterが冗長化されているk8sではLBを構築する必要があります。nginxなど利用されることもありますが、今回はHA-Proxyを利用します。
k8s2-ha-proxy-1とk8s2-ha-proxy-2をKeepalibedを利用してVRRPを張りたいと思います。
haproxyの設定
今回etcdはmaster内部のものを利用し、APIserverを冗長化しようと思います。
apt update && apt upgrade -y
apt install haproxy keepalived
cat << _EOF_ >> /etc/haproxy/haproxy.cfg
frontend api
bind *:6443
mode tcp
option tcplog
default_backend api
backend api
mode tcp
option tcplog
option tcp-check
balance leastconn
server master1 10.0.1.1:6443 check
server master2 10.0.1.2:6443 check backup
server master3 10.0.1.3:6443 check backup
_EOF_
systemctl restart haproxy.service
systemctl enable haproxy.service
Keepalived
この設定もそれぞれk8s2-ha-proxy-1とk8s2-ha-proxy-2に行ってください
echo "
global_defs {
notification_email {
}
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance haproxy-vip {
state BACKUP
priority 100
interface eth0 # 適切なネットワークカードを選択してください
virtual_router_id 60
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
unicast_src_ip 10.0.1.4 # このマシンのアドレス
unicast_peer {
10.0.1.5 # 相手のマシンのアドレス
}
virtual_ipaddress {
10.0.0.100/8 # VIP
}
track_script {
chk_haproxy
}
}
" > /etc/keepalived/keepalived.conf
systemctl restart keepalived
systemctl enable keepalived
kubernetes の構築
今回は現状最新の1.29の構築をしていきます。
下準備
masterとslave両方やろう!
sudo apt update && sudo apt upgrade -y
# ipv4のフォワーディング有効に…
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# swapの無効化
sudo swapoff -a
sudo vi /etc/fstab
/etc/fstabを
-/swap.img none swap sw 0 0
+# /swap.img none swap sw 0 0
kubelet , kubeadm , kubectl のインストール
これも両方やろう
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/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:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
# バージョン固定しとこうね!
sudo apt-mark hold kubelet kubeadm kubectl
CRI-Oのセットアップ
これも両方やろう!
sudo su
apt install -y jq
curl https://raw.githubusercontent.com/cri-o/packaging/main/get | bash
sudo systemctl daemon-reload
sudo systemctl enable crio
sudo systemctl start crio
masterのセットアップ
ここまで来たらあと少し!
sudo kubeadm init --control-plane-endpoint 10.0.0.100:6443 --pod-network-cidr=10.1.0.0/16 --upload-certs
を実行。ここで注意が、--control-plane-endpoint に設定される値は最初のほうで設定したVIPを指定してください。 --pod-network-cidr=10.1.0.0/16はpod内で扱うネットワークの設定なのでよしなに
#==================================================================================================
# 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 10.0.0.100:6443 --token ********* \
# --discovery-token-ca-cert-hash sha256:********* \
# --control-plane --certificate-key *********
# 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 10.0.0.100:6443 --token ********* \
# --discovery-token-ca-cert-hash sha256:*********
みたいなのが出るとmasterの初期化成功です。
あとは残りのmasterとworkerをjoinさせれば終了
# master-2, master-3でこっちのコマンド
sudo kubeadm join 10.0.0.100:6443 --token ********* \
--discovery-token-ca-cert-hash sha256:********* \
--control-plane --certificate-key *********
すべてのノードでkubectlが使えるようにセットアップ
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
これでmasterはおしまい!
workerのセットアップ
sudo kubeadm join 10.0.0.100:6443 --token ********* \
--discovery-token-ca-cert-hash sha256:*********
すべてのセットアップ済のworkerに対してjoinのコマンドを入力すれば完了!
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s2-master-1 Ready control-plane 56m v1.29.3
k8s2-master-2 Ready control-plane 51m v1.29.3
k8s2-master-3 Ready control-plane 51m v1.29.3
k8s2-slave-1 Ready <none> 16s v1.29.3
k8s2-slave-2 Ready <none> 15s v1.29.3
k8s2-slave-3 Ready <none> 14s v1.29.3
k8s2-slave-4 Ready <none> 14s v1.29.3
k8s2-slave-5 Ready <none> 13s v1.29.3
k8s2-slave-6 Ready <none> 13s v1.29.3
こんな感じになってれば準備完了
CNIの準備
今回はcalicoを利用します。(実は失敗だったがまぁいいや)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml
# カスタムリソースのDL
curl https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/custom-resources.yaml -O
custom-resource.yamlの spec.calicoNetwork.ipPools[0].cidrを init時の--pod-network-cidrに修正してください
# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Configures Calico networking.
calicoNetwork:
# Note: The ipPools section cannot be modified post-install.
ipPools:
- blockSize: 26
cidr: 10.1.0.0/16 # <-ここのアドレスを initした時の--pod-network-cidrに合わせる
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()
---
# This section configures the Calico API server.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.APIServer
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}
カスタムリソースのデプロイ
kubectl apply -f custom-resources.yaml
kubectl get pod -n calico-system
# これですべてのpodがrunningなってたらOK
kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7cdf75fbc7-z7n6g 1/1 Running 0 6d14h
calico-node-2nqr7 1/1 Running 0 6d14h
calico-node-7c4kn 1/1 Running 0 6d14h
calico-node-gj4sq 1/1 Running 1 6d14h
calico-node-gnzsh 1/1 Running 0 6d14h
calico-node-ml5qw 1/1 Running 0 6d14h
calico-node-tmvtf 1/1 Running 0 6d14h
calico-node-wtw29 1/1 Running 3 6d14h
calico-node-wz4bn 1/1 Running 0 6d14h
calico-node-z2cn5 1/1 Running 0 6d14h
calico-typha-7c56499d7c-6jvbb 1/1 Running 0 6d14h
calico-typha-7c56499d7c-mwrgh 1/1 Running 0 6d14h
calico-typha-7c56499d7c-wmwx2 1/1 Running 0 6d14h
csi-node-driver-4hns7 2/2 Running 0 6d14h
csi-node-driver-4tjw9 2/2 Running 0 6d14h
csi-node-driver-6ch9z 2/2 Running 0 6d14h
csi-node-driver-dbcnv 2/2 Running 4 6d14h
csi-node-driver-g8xc9 2/2 Running 2 6d14h
csi-node-driver-nkztd 2/2 Running 0 6d14h
csi-node-driver-sb7wn 2/2 Running 0 6d14h
csi-node-driver-sf5f2 2/2 Running 0 6d14h
csi-node-driver-wjgrn 2/2 Running 0 6d14h
これ、そこそこ時間がかかるのでゆっくりお茶でもしながら待ちましょう!
すべてが終わったそこのあなた!楽しいk8sライフを楽しみましょう!
MetalLBのセットアップ
自宅鯖勢でもLoadBalancerを活用したい!
そんなあなたにMetalLBを。。。(Calicoミスった。でも動いてるからヨシ!)
calicoだと限定的なサポートになっている…
trictARPの許可
# 変更の確認
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
# 変更の適用
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
MetalLBのデプロイ
helm repo add metallb https://metallb.github.io/metallb
kubectl create ns metallb-system
helm install metallb metallb/metallb -n metallb-system
Address Poolの設定
ここで設定した値のレンジがLoadBalancerに割り当てられるIP。
10.0.100.0-10.0.100.100に今回設定したいのでその範囲で設定。
echo "
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default
namespace: metallb-system
spec:
addresses:
- 10.0.100.0-10.0.100.100
autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
spec:
ipAddressPools:
- default
" > tee addresspool.yaml
kubectl apply -f addresspool.yaml
動作確認
apiVersion: v1
kind: Pod
metadata:
name: "nginx"
labels:
app: "nginx"
spec:
containers:
- name: nginx
image: "nginx:latest"
ports:
- containerPort: 80
name: http
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- name: nginx
protocol: TCP
port: 80
targetPort: 80
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 0 12s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d17h
service/nginx LoadBalancer 10.110.115.132 10.0.100.2 80:31099/TCP 12s
service/nginxに10.0.100.2が割り当てられているのでそこにアクセスしてみよう
nginxが正常にデプロイされてそうですね!
最後に
CNIはfannelとかに変えたほうがいいです。
バージョン変わってできねぇよ!ってなったらコメントとかTwitterで教えてもらえると直します。
Discussion