Skip to content

Commit 43dbb6b

Browse files
authored
#497 K3s 멀티 노드 확장을 위한 kube-vip 및 HA 구성 (#498)
1 parent 5d51403 commit 43dbb6b

3 files changed

Lines changed: 220 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# K3s와 Kube-vip을 이용한 고가용성(HA) 클러스터 구성 가이드
2+
3+
이 문서는 K3s와 Kube-vip을 함께 사용하여 여러 컨트롤 플레인 노드에 걸쳐 안정적인 가상 IP(VIP)를 갖는 고가용성 Kubernetes 클러스터를 구축하는 방법을 안내합니다.
4+
5+
### 핵심 파일
6+
7+
- `kube-vip-rbac.yaml`: Kube-vip이 클러스터 리소스에 접근하는 데 필요한 권한(RBAC)을 정의합니다.
8+
- `kube-vip.yaml.tpl`: Kube-vip DaemonSet을 위한 템플릿입니다. 실제 배포 시 가상 IP 주소(`##VIP_ADDRESS##`)를 채워 넣어야 합니다.
9+
10+
---
11+
12+
### 1. 첫 번째 컨트롤 플레인 노드 설정
13+
14+
가장 먼저 클러스터를 초기화할 첫 번째 노드를 설정합니다.
15+
16+
#### 1-1. 환경 변수 설정
17+
18+
사용할 가상 IP(VIP)와 노드의 네트워크 인터페이스를 환경 변수로 지정합니다. 이 값은 **환경에 맞게 반드시 변경**해야 합니다.
19+
20+
```sh
21+
export VIP="192.168.0.100" # 클러스터에 할당할 가상 IP 주소
22+
export INTERFACE="eno3" # 노드의 네트워크 인터페이스 이름 (e.g., eth0, eno1)
23+
```
24+
25+
#### 1-2. Kube-vip 매니페스트 준비
26+
27+
K3s가 자동으로 로드할 매니페스트 디렉토리를 만들고, 저장소에 미리 준비된 Kube-vip 설정 파일들을 복사합니다.
28+
29+
```sh
30+
# 매니페스트 디렉토리 생성
31+
sudo mkdir -p /var/lib/rancher/k3s/server/manifests/
32+
33+
# 1. RBAC 설정 파일을 복사합니다.
34+
sudo cp ./kube-vip-rbac.yaml /var/lib/rancher/k3s/server/manifests/kube-vip-rbac.yaml
35+
36+
# 2. DaemonSet 템플릿을 복사하고, 위에서 설정한 VIP 주소로 내용을 교체합니다.
37+
sudo cp ./kube-vip.yaml.tpl /var/lib/rancher/k3s/server/manifests/kube-vip.yaml
38+
sudo sed -i "s/##VIP_ADDRESS##/$VIP/g" /var/lib/rancher/k3s/server/manifests/kube-vip.yaml
39+
```
40+
41+
> **참고:** `sed -i` 명령어는 macOS와 GNU/Linux에서 다르게 동작할 수 있습니다. macOS에서는 `sed -i '' "s/..."` 와 같이 사용해야 할 수 있습니다.
42+
43+
#### 1-3. K3s 설치 및 클러스터 초기화
44+
45+
준비된 매니페스트와 함께 K3s 서버를 설치하여 클러스터를 시작합니다.
46+
47+
```sh
48+
curl -sfL https://get.k3s.io | sh -s - server \
49+
--cluster-init \
50+
--tls-san $VIP \
51+
--disable servicelb \
52+
--disable-cloud-controller
53+
```
54+
55+
- `--tls-san $VIP`: K3s API 서버의 TLS 인증서에 가상 IP를 추가하여, VIP를 통해 API 서버에 안전하게 접근할 수 있도록 합니다.
56+
- `--disable servicelb`: K3s의 기본 서비스 로드밸런서인 "ServiceLB"를 비활성화합니다. Kube-vip이 이 역할을 대신합니다.
57+
58+
---
59+
60+
### 2. 추가 컨트롤 플레인 노드 합류
61+
62+
첫 번째 노드 설정이 완료되면, 다른 컨트롤 플레인 노드를 클러스터에 추가하여 고가용성 환경을 완성합니다.
63+
64+
#### 2-1. 클러스터 조인 토큰 확인
65+
66+
**첫 번째 노드**에서 다음 명령을 실행하여 클러스터에 합류하는 데 필요한 토큰을 확인하고 변수에 저장합니다.
67+
68+
```sh
69+
export TOKEN=$(sudo cat /var/lib/rancher/k3s/server/node-token)
70+
echo "클러스터 조인 토큰: $TOKEN"
71+
```
72+
73+
#### 2-2. 추가 노드에서 K3s 설치
74+
75+
**추가할 노드**에서 다음 명령어를 실행하여 클러스터에 컨트롤 플레인 노드로 합류합니다.
76+
77+
```sh
78+
# 아래 변수들은 사용자 환경에 맞게 설정해야 합니다.
79+
export VIP="192.168.0.100" # 첫 번째 노드에서 설정한 것과 동일한 가상 IP
80+
export TOKEN="<your-cluster-token>" # 2-1 단계에서 확인한 클러스터 조인 토큰
81+
82+
curl -sfL https://get.k3s.io | sh -s - server \
83+
--server https://$VIP:6443 \
84+
--token ${TOKEN} \
85+
--tls-san $VIP \
86+
--disable servicelb \
87+
--disable-cloud-controller
88+
```
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
apiVersion: v1
2+
kind: ServiceAccount
3+
metadata:
4+
name: kube-vip
5+
namespace: kube-system
6+
---
7+
apiVersion: rbac.authorization.k8s.io/v1
8+
kind: ClusterRole
9+
metadata:
10+
annotations:
11+
rbac.authorization.kubernetes.io/autoupdate: "true"
12+
name: system:kube-vip-role
13+
rules:
14+
- apiGroups: [""]
15+
resources: ["services/status"]
16+
verbs: ["update"]
17+
- apiGroups: [""]
18+
resources: ["services", "endpoints"]
19+
verbs: ["list", "get", "watch", "update"]
20+
- apiGroups: [""]
21+
resources: ["nodes"]
22+
verbs: ["list", "get", "watch", "update", "patch"]
23+
- apiGroups: ["coordination.k8s.io"]
24+
resources: ["leases"]
25+
verbs: ["list", "get", "watch", "update", "create"]
26+
- apiGroups: ["discovery.k8s.io"]
27+
resources: ["endpointslices"]
28+
verbs: ["list", "get", "watch", "update"]
29+
- apiGroups: [""]
30+
resources: ["pods"]
31+
verbs: ["list"]
32+
33+
---
34+
kind: ClusterRoleBinding
35+
apiVersion: rbac.authorization.k8s.io/v1
36+
metadata:
37+
name: system:kube-vip-binding
38+
roleRef:
39+
apiGroup: rbac.authorization.k8s.io
40+
kind: ClusterRole
41+
name: system:kube-vip-role
42+
subjects:
43+
- kind: ServiceAccount
44+
name: kube-vip
45+
namespace: kube-system
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
apiVersion: apps/v1
2+
kind: DaemonSet
3+
metadata:
4+
labels:
5+
app.kubernetes.io/name: kube-vip-ds
6+
app.kubernetes.io/version: v1.0.2
7+
name: kube-vip-ds
8+
namespace: kube-system
9+
spec:
10+
selector:
11+
matchLabels:
12+
app.kubernetes.io/name: kube-vip-ds
13+
template:
14+
metadata:
15+
labels:
16+
app.kubernetes.io/name: kube-vip-ds
17+
app.kubernetes.io/version: v1.0.2
18+
spec:
19+
affinity:
20+
nodeAffinity:
21+
requiredDuringSchedulingIgnoredDuringExecution:
22+
nodeSelectorTerms:
23+
- matchExpressions:
24+
- key: node-role.kubernetes.io/master
25+
operator: Exists
26+
- matchExpressions:
27+
- key: node-role.kubernetes.io/control-plane
28+
operator: Exists
29+
containers:
30+
- args:
31+
- manager
32+
env:
33+
- name: vip_arp
34+
value: "true"
35+
- name: port
36+
value: "6443"
37+
- name: vip_nodename
38+
valueFrom:
39+
fieldRef:
40+
fieldPath: spec.nodeName
41+
- name: vip_interface
42+
value: eno3
43+
- name: vip_subnet
44+
value: "32"
45+
- name: dns_mode
46+
value: first
47+
- name: cp_enable
48+
value: "true"
49+
- name: cp_namespace
50+
value: kube-system
51+
- name: svc_enable
52+
value: "true"
53+
- name: svc_leasename
54+
value: plndr-svcs-lock
55+
- name: vip_leaderelection
56+
value: "true"
57+
- name: vip_leasename
58+
value: plndr-cp-lock
59+
- name: vip_leaseduration
60+
value: "5"
61+
- name: vip_renewdeadline
62+
value: "3"
63+
- name: vip_retryperiod
64+
value: "1"
65+
- name: address
66+
value: ##VIP_ADDRESS##
67+
- name: prometheus_server
68+
value: :2112
69+
image: ghcr.io/kube-vip/kube-vip:v1.0.2
70+
imagePullPolicy: IfNotPresent
71+
name: kube-vip
72+
resources: {}
73+
securityContext:
74+
capabilities:
75+
add:
76+
- NET_ADMIN
77+
- NET_RAW
78+
drop:
79+
- ALL
80+
hostNetwork: true
81+
serviceAccountName: kube-vip
82+
tolerations:
83+
- effect: NoSchedule
84+
operator: Exists
85+
- effect: NoExecute
86+
operator: Exists
87+
updateStrategy: {}

0 commit comments

Comments
 (0)