[k8s] kube-vip
์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ๊ณ ๊ฐ์ฉ์ฑ์ผ๋ก ๊ตฌ์ฑํ๋ค๊ณ ํ์๋, ๊ฑธ๋ฆฌ๋ ๊ฒ ์ค ํ๋๊ฐ ์ด๊ฒ์ด๋ค.
"๊ทธ๋ฌ๋ฉด kube API ์๋ํฌ์ธํธ๋ ์ด๋ป๊ฒ HA๋ฅผ ๋ณด์ฅํ๋๊ฐ?"
๊ฒฐ๊ตญ ์ฟ ๋ฒ ๋ด ์ผ๋ถ ๋ฆฌ์์ค๋ค๋ kube API์ ์ด์ ์ด๋ฐ์ ๋ฐ ๋์์ ์ฒ๋ฆฌํ๊ฑฐ๋ ํ๋๋ฐ, ์ฟ ๋ฒ์ ์ผ๋ถ ํ์ ์์คํ ๋ค์ ์ด๊ฑธ HA ๊ธฐ๋ฐ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ต๋ค.
control plane ๋
ธ๋๊ฐ 3๊ฐ ์๋ค๊ณ ํ๋ฉด ์ด๋ ๋
ธ๋์ ์ฐ๋ฌ์ผ ํ ๊น? ๋
ธ๋๊ฐ ํ๋ ์ฃฝ์ผ๋ฉด ๋ค๋ฅธ ๋
ธ๋๋ก ์ด๋ป๊ฒ ์ฎ๊ฒจ์ผํ ๊น?
์ผ๋ฐ์ ์ธ Pod๋ค์ ์์ฒด์ ์ธ kubernetes.default.svc ์๋น์ค ๊ณ์ธต์ ํตํด์ ์ด๊ฑธ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ฃผ๋๋ฐ, ์๋น์ค๋ฅผ ์ธ ์ ์๋ kube-proxy(ํน์ CNI), kubelet, kube agent๋ค์ ๊ทธ ํํ์ ๋๋ฆฌ์ง ๋ชปํด์ ์๋ํฌ์ธํธ ๋
ธ๋๊ฐ ๋ป์ผ๋ฉด ํต์ ์ ํ์ง ๋ชปํ๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋๊ตฌ ์ค ํ๋๊ฐ kube-vip๋ค.
๋ณ๋์ LB๋ฅผ ์ ๋ขฐ์ฑ ๋์ ๊ณ์ธต์ ๊ตฌ์ถํด๋ ๋์ง๋ง, ์ด๊ฑด ํฉ์ ๊ธฐ๋ฐ์ผ๋ก control plane ๋
ธ๋๋ค์ด ์์ฒด์ ์ผ๋ก ๋ฆฌ๋๋ฅผ ๋ฝ๊ณ ์ ํ์ ํ ์ ์๊ฒ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ๋ฆฌ๋ ๋
ธ๋๊ฐ API ์๋ํฌ์ธํธ๊ฐ ๋๋ค.
์ด๋ฌ๋ฉด ๊ฐ์ ๋ด๋ถ IP๋ฅผ ํตํด ํน์ ๋
ธ๋๊ฐ ์ฃฝ๋๋ผ๋, ๊ฐ์ IP๋ฅผ ํตํด์ ๋ค๋ฅธ ๋
ธ๋๊ฐ ์์ฅ์ ์ก๊ณ ํต์ ์ ํ ์ ์๊ฒ ํด์ค๋ค.
๊ธฐ์กด k3s์ ์ค์นํ๊ธฐ
๋จผ์ VIP๋ก ์ฌ์ฉํ IP๋ฅผ ์ ํด์ผํ๋ค.
LAN ๋ด์์ ARP ๊ธฐ๋ฐ์ผ๋ก ์ง์ง ์กด์ฌํ๋ ๊ฒ์ฒ๋ผ ๋์ํ ๊ฒ์ด๋ฏ๋ก, ๋ง ๋ด์์ ๊ณ ์ ํด์ผ ํ๋ค.
๋ 192.168.88.250๋ก ์ ๋นํ ์ก์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ค.
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
kubectl apply -f kube-vip-ds.yaml # ์๋ ํ์ผapiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-vip-ds
namespace: kube-system
labels:
app.kubernetes.io/name: kube-vip-ds
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
labels:
name: kube-vip-ds
spec:
hostNetwork: true
serviceAccountName: kube-vip
nodeSelector:
node-role.kubernetes.io/control-plane: "true"
tolerations:
- operator: Exists
effect: NoSchedule
containers:
- name: kube-vip
image: ghcr.io/kube-vip/kube-vip:v1.2.4
args: [manager]
env:
- { name: vip_arp, value: "true" }
- { name: port, value: "6443" }
- { name: vip_cidr, value: "32" }
- { name: cp_enable, value: "true" }
- { name: cp_namespace, value: kube-system }
- { name: vip_leaderelection, value: "true" }
- { name: vip_leaseduration, value: "15" }
- { name: vip_renewdeadline, value: "10" }
- { name: vip_retryperiod, value: "2" }
- { name: address, value: "๊ฐ์IP" }
securityContext:
capabilities:
add: [NET_ADMIN, NET_RAW]
๋ฐฉ๊ธ VIP๋ก ์ฐ๊ธฐ๋ก ๊ฒฐ์ ํ๊ฑธ ์ ๊ธฐ ์ฃผ์์ ๋ฐ์ผ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ control plane ๋
ธ๋์๋ง ์๋์ผ๋ก ์คํ๋๊ฒ ํ๋ค.
์ ๊ฑธ ๋ค ๋์ฐ๊ณ , control plane ๋ ธ๋์ ์์ด์ ํธ ํ์ผ์ ์ ๋ถ ์ด์ด์, tls-san ๋ชฉ๋ก์ ๋ฐฉ๊ธ VIP๋ฅผ ์ ๋ถ ์ถ๊ฐํ๋ค.

๊ทธ๋ฆฌ๊ณ tls ๋ชฉ๋ก์ VIP๋ฅผ ์ถ๊ฐํ๊ณ ์ฌ๋ถํ
ํด์ค๋ค.
๋์ค์ control plane์ผ๋ก ๋
ธ๋๋ฅผ ์ถ๊ฐํ ๋๋ ํญ์ VIP๋ฅผ ์ถ๊ฐ๋ก ๋ฃ์ด์ค์ผ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ํต์ ์ด ๋๋ฉด ๋คํธ์ํฌ๋ ์ ์ฎ์ธ ๊ฒ์ด๋ค.
์ด ๋ค์์, cilium์ ์ด๋ค๋ฉด cilium ์ธํ
๋ VIP๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ฉด ๋๋๋ฐ, ๊ทธ๊ฑด ํ๋จ์ ์ ๋ฆฌํด๋จ๋ค.
๊ทธ๋ฆฌ๊ณ control plane์ด ์๋ ์์ปค ๋
ธ๋๋ค๋ VIP๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ๋ฐ๊ฟ์ค๋ค.
๊ทธ๋์ผ ๋
ธ๋ ํ๋ ๋ป์์๋๋ ํต์ ์ด ์ ์ง๋๋ค.
sudo sed -i 's|https://192.168.88.202:6443|https://192.168.88.250:6443|' /etc/systemd/system/k3s-agent.service.env
sudo systemctl daemon-reload
sudo systemctl restart k3s-agent

Cilium์ VIP ์ ์ฉ (with helm)
Cilium์ CNI๋ก ์ธ ๊ฒฝ์ฐ์ ํด๋น๋๋ ๋ถ๋ถ์ด๋ค. ๊ทธ๋ฆฌ๊ณ helm์ผ๋ก ์ค์นํด๋จ๋ค๊ณ ๊ฐ์ ํ๋ค.
serviceHost๋ฅผ VIP๋ก ๋ฐ๊ฟ์ฃผ๊ณ
helm upgrade cilium cilium/cilium -n kube-system \
--version 1.20.2 \
-f cilium/values.yaml
kubectl -n kube-system rollout restart ds/cilium
kubectl -n kube-system rollout status ds/cilium
์ฌ์ค์นํ๋ค.
๊ทธ๋ ๊ฒ ํด์ ์ด ๊ฐ์ด VIP๋ก ๋์ค๋ฉด ์ ๋ ๊ฒ์ด๋ค.
kubectl -n kube-system exec ds/cilium -- sh -c 'echo "KUBERNETES_SERVICE_HOST=$KUBERNETES_SERVICE_HOST"'

์ฐธ์กฐ
https://kube-vip.io/docs/usage/k3s/
https://kube-vip.io/
https://medium.com/@siddharthsid533/how-i-got-kube-vip-working-with-my-k3s-cluster-without-breaking-things-668100703d5c