[k8s] HA Cluster 구축하기

minujana
8 min readDec 18, 2020

--

Kubernetes Cluster 구성 중 HA Cluster를 구축하는 방법을 정리해보려 한다.

그림1. HA Cluster 구성도 [출처: google kubernetes 공식 docs]

마스터 노드를 3개로 두어 클러스터 구성하는 것은 그냥 kubeadm init 에 옵션만 추가하면 될 정도로 어려운 과정은 아니지만, load balancer를 추가해서 위 그림 처럼 구축을 진행할 것이다.

마스터를 HA 구성하기 위해서는 1대 이상의 마스터가 필요하다. 그러나 2대로는 구성을 할 수 없다. 왜냐하면 etcd의 leader election 알고리즘 때문이다. 찾아본 바로는 해당 옵션을 False로 하고 구성을 어떻게 진행할 수 있는것 같지만, 네트워크가 이상이 생길 경우 클러스터가 손상될 수도 있다고 한다. 그래서 더 이상 알아보지 않았고, 나도 마스터 노드 3대로 진행을 하기로 했다.

2대가 아니라 4대로 진행을 해도 leader election 과정에서 2:2의 형태가 생길 경우 클러스터의 손상을 초래할 수 있으니까 홀수의 노드로 HA 클러스터를 구성하길 권장한다.

Load Balancer 는 물리 스위치가 있다면 좋겠지만, 나의 경우에는 그렇지 않기 때문에 keepalive 와 haproxy를 이용해서 진행을 할 것이다.

HA 클러스터를 구성할 Master Node 3대에 대한 정보는 아래와 같다. 3대 모두 CentOS 7.8을 설치하여 진행하였다.

kube-master01 [10.1.10.21]
kube-master02 [10.1.10.22]
kube-master03 [10.1.10.23]

그리고 LoadBalancer에 사용할 VIP는 10.1.10.20 이다.

keepalive set-up

모든 노드에 keepalived 패키지를 설치해주자. 모든 노드에서 진행해야하는 커맨드는 이탤릭체로 작성을 하겠다.

#yum install keepalived

설치하게 되면 /etc/keepalived/ 디렉토리 아래에 keepalived.conf 파일이 존재하는데 기본 파일을 다른이름으로 백업해두고 config 파일을 아래와 같이 작성하자.

#vi /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface
eth0 (사용할 NiC의 이름)
virtual_router_id 51 (모두 동일한 id 로 설정 255까지 가능)
priority
100 (255까지 입력가능하며 높을수록 우선순위를 가짐)
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.1.10.20/24 (사용할 VIP 입력 뒤에 마스크값 안넣으면 기본 32)
}
}

3대의 노드에 위와 같이 설정해준다. NiC 이름이 노드마다 다르다면 그에 맞춰 설정해주면 되고, route_id 는 모두 동일하게 설정해야한다. 그리고 priority의 경우 나는 1번 노드를 100, 2번은 99, 3번은 98로 설정했다.

위처럼 환경파일 작성하고 난 후,

#systemctl enable --now keepalived.service

서비스가 시작되었는지 확인하고, ip a 커맨드로 확인하여 보면 아래와 같이 VIP가 등록된 것을 확인 할 수 있다.

우선 순위가 높은 노드에만 생기고, 다른 노드에는 확인 되지 않는 것이 정상이다. 제대로 작동하는지 확인하려면 현재 VIP가 떠있는 노드의 NiC를 다운시키고 그 다음 우선순위인 노드에서 확인해보면 된다.

haproxy set-up

우선 모든 노드에 해당 패키지를 설치한다.

#yum install haproxy

이번에도 haproxy의 기본 설정인 /etc/haproxy/haproxy.cfg 를 다른 이름으로 바꿔주고, 아래와 같이 파일을 작성한다.

#vi /etc/haproxy/haproxy.cfg
frontend kube-cluster
bind 10.1.10.20:16443
option tcplog
mode tcp
default_backend kube-cluster-be
backend kube-cluster-be
mode tcp
balance roundrobin
option tcp-check
option tcplog
server node1 10.1.10.21:6443 check
server node2 10.1.10.22:6443 check
server node3 10.1.10.23:6443 check

frontend의 bind 부분은 실제로 쿠버네티스 서비스는 마스터의 6443 포트를 사용한다. 로드밸런서의 포트가 로컬의 6443포트와 겹치지 않도록 16443으로 지정을 해주었다.

backend의 server는 3대의 마스터 서버의 api를 등록해준다.

위처럼 환경파일 작성하고 난 후,

#systemctl enable --now haproxy.service

서비스가 정상적으로 시작되었는지 확인해본다. 서비스가 동작하지 않는 에러가 몇몇 원인이 있을 수 있는데 우선 아래와 같이 커널값이 설정이 되어있는지 확인하고 되어있지 않다면, 적용해주자

#vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
net.ipv4.ip_forward=1
파일 수정 후, 적용
#sysctl -p

모든 설정을 마친 후에 Fail-over 테스트를 진행해보았는데, ifdown eth0 과 같은 커맨드로 진행하면 VIP가 넘어가지 않는 것을 발견했다.(설정을 잘못한 줄 알고 반나절을 소모했다.) 나와 비슷한 현상이 이미 커뮤니티에 제보되었고, 커뮤니티의 해당 게시글의 최신 버전에서도 그렇다는 것 같다. 따라서 테스트는 실제로 노드를 종료시키거나, ip link set eth0 down 커맨드를 이용해서 테스트를 해보면 Fail-over가 되는 것을 확인 할 수 있다.

Docker-Kubernetes Install

도커와 쿠버네티스 패키지 설치 과정은 생략해도 될 것같다.

모든 노드에 도커, 쿠버네티스 패키지 설치해주자!

#yum install docker-ce docker-ce-cli cotainerd.io
#yum install kubeadm
#systemctl enable --now docker
#systemctl enable --now kubelet

HA k8s cluster set-up

이 역시 kubeadm 을 이용하기 때문에 기존에 클러스터 구축하는 것과 크게 다른 것 없는 과정이다. 이미 앞에서 준비를 다했기 때문에 클러스터 구축은 손쉽게 할 수 있다.

#kubeadm init --control-plane-endpoint "로드밸런서IP:로드밸런서PORT" \
--upload-certs \
--pod-network-cidr "10.244.0.0/16"

가장 높은 우선순위로 설정한 노드에 위와 같이 클러스터를 생성해 준다.

그러면 결과로 2가지 커맨드가 출력되는데 각각 Control-plane 으로 조인 시킬 경우와 Worker로 조인 시킬 경우에 대한 커맨드가 출력된다. 클러스터를 생성하면서 만들어진 admin.conf를 .kube/config로 옮겨주고, 나머지 노드들을 조인시켜주자

나머지 노드를 우리는 Control-plane 으로 조인을 시킬 것이므로 2가지 커맨드 중 Control-plane에 해당하는 커맨드를 입력한다.

#kubeadm join 10.1.10.20:16443 --token 36oc5w.35a8ajb7g4zb16ci \
--discovery-token-ca-cert-hash sha256:aaac49a2b751a1d3288fcaa45d9bb538fa145c6c24e0639817aac918f2f9643f \
--control-plane --certificate-key 7d3144c2b91c1208833c98306e492dba698c72d6307bee9547b131ee7ad1af6e

모든 노드를 조인 시킨 후에 각 노드에도 admin.conf를 .kube/config로 옮겨주어야 한다.

다음으로 CNI를 배포하고 노드 상태를 확인해본다.

#kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

모든 노드가 Ready 상태인 것을 확인 할 수 있을 것이고, 만약 Worker 노드를 조인시킬 계획이 없고, 3중화된 마스터 노드를 워커노드 처럼 같이 사용할 계획이라면 마스터 노드에는 기본적으로 파드가 뜰 수 없게 설정이 되어있기 때문에 아래와 같이 테인트를 제거해준다.

#kubectl taint node --all node-role.kubernetes.io/master-

여기 까지 설정하면 맨위에 그림1 처럼 Control-plane이 구성이 되었다. 실제로 etcd 도 3개가 존재하는 것을 확인할 수 있다. 다음으로는 마스터가 3중화된 HA Cluster에 Ceph를 구성하여 보도록 하겠다.

--

--

minujana
minujana

Responses (1)