Bare-metal,Cloud,VM 등 쿠버네티스를 구축하는 다양한 방법이 존재합니다. 각 방식마다 장점과 단점이 존재하고 이는 성능,확장성,Integreation에 영향을 주고 각 각의 구축된 방식에서 변경이 힘들기 때문에 적절한 선택이 필요합니다.
설정이나 관리가 빠르고 편함.
클라우드를 통한 확장성이 무한함.
벤더사에 따라 제공하는 설정,제약을 확인해아함.
온프레미스(Bare-metal,VM)에 비해 세부적인 컨트롤이 제한됨.
저는 프로젝트 특성을 고려해 온프레미스로 구축하여야 했고 이를 베어메탈 서버에 Kubespray를 이용해 설치했습니다. 글을 작성하는 시점에서는 GKE,EKS를 통해서도 쿠버네티스를 구축해본 경험이 있습니다. 당연한 이야기지만 GKE나 EKS를 사용하는게 훨씬 수월합니다.
실제 프로젝트에서는 베어메탈 서버에서 설치를 진행하였지만 여기에서는 EC2 인스턴스를 생성해 Kubernetes를 설치하는 과정을 기록합니다. 보통 고가용성의 클러스터를 구성할 때 마스터 3대로 구성하고(1대 리더, 2대 대기) 좀 더 안정적인 운영 할 경우 마스터 서버를 5대로 구성합니다. 저는 테스트 용으로 마스터 노드 한대,워커 노드 3대로 구성하였습니다.
kubespray 설치 시 요구사항에 Master 서버의 메모리는 1500MB, Worker 서버의 메모리는 1024MB기 때문에 각각 t2.large와 t2.medium으로 선택하고(OS: ubuntu 18.04) 설치 후 Nvida-plugin을 테스트하기 위해 GPU가 포함된 P2 인스턴스를 선택했습니다. 인스턴스를 생성 후 설치를 위해 필요한 포트를 보안그룹에서 열어줍니다.
설치 과정은 Kubespray github를 따라하며 설치를 진행하였습니다.
4-1. ssh-key 공유
Master 서버에서 worker 서버에 인증없이 ssh 접속을 위해 key 공유하는 과정입니다. 베어메탈 서버에서는 우분투 ssh-keygen
명령어를 통해 key를 생성하고 ssh-copy-id
명령어를 통해 공유 하면 됩니다.EC2에서는 적용되지 않아서 .authorized_key
파일에 직접 키를 입력합니다.
cat ~/.ssh/id_rsa.pub | ssh -i "k8s.pem" ubuntu@[IP 주소] " cat - >> ~/.ssh/authorized_keys"
마스터 서버에서 다음 명령어를 통해 모든 워커 노드에 SSH 접속이 가능하도록 설정합니다.
4-2. host 설정
마스터 서버에서 /etc/hosts 파일을 수정해 ansible 수행시 워커노드를 호스트명을 통해 인식 할 수 있도록 설정합니다.
4-3. inventory 파일 작성
kubepsray 파일을 clone 후 kubespray/invenvtory/sample 파일을 복사 후의 과정입니다. README에서 inventory 파일 생성까지의 명령어를 통해 자동으로 생성 할 수 있지만 저는 yaml 파일 대신 다음과 같은 ini파일로 설치를 진행했습니다.
#hosts.ini 파일
[k8s-cluster:children]
kube-master
kube-node
[all]
master ansible_host=172.31.16.167 ip=172.31.16.167
node1 ansible_host=172.31.17.34 ip=172.31.17.34
node2 ansible_host=172.31.17.132 ip=172.31.17.132
node3 ansible_host=172.31.14.195 ip=172.31.14.195
[kube-master]
master
[kube-node]
node1
node2
node3
[etcd]
master
[calico-rr]
[vault]
node1
node2
node3
각각의 항목에 서버의 정보를 입력하고 etcd서버로 설정할 노드를 설정합니다. etcd 서버는 홀수 개로 설정하여야됩니다. 그 외에 설정을 확인해야 하는 파일은 all 디렉토리(클라우드 설정 aws,azure 등)과 k8s-cluster 디렉터리의 k8s-cluster.yaml 파일입니다. k8s-cluster 파일에서 쿠버네티스 버전, network 등을 설정 할 수 있습니다. 현재 설정은 kube-version: v1.20.5 , kube-proxy: ipvs, Network-plugin: calico로 진행합니다.
4-4. ansible 실행
ansible-playbook -i inventory/mycluster/hosts.ini -v --become --become-user=root cluster.yml
명령어를 통해 설치를 진행합니다. -v 옵션은 디버깅, --become은 root로 실행하지 않을 경우 적용합니다. 만약 ssh 접속에 오류가 생긴다면 -kK옵션을 통해 password를 직접 입력 할 수 있습니다. 정상적으로 설치 되면 다음과 같은 화면이 나타납니다.
kubectl이 설치가 안되있다면 링크 내용을 따라 설치를 진행합니다. kubectl 명령어 실행시 connection 오류가 나타날 경우 다음을 명령어를 실행합니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
다음과 같이 클러스터가 정상적으로 구성이 완료됬음을 확인 할 수 있습니다.
또한 워커노드에서 도커 확인 시 k8s 관련 컨테이너가 실행 중임을 확인 할 수 있습니다.
설치 완료 후 노드를 추가하거나 삭제하는 것 또한 ansible을 통해 작업을 수행할 수 있습니다. hosts.ini 파일을 수정후 scale.yml 파일이나 remove-node.yml을 실행합니다. 또한 설치중 reset이 필요한 경우 ansible-playbook -i inventory/mycluster/hosts.ini reset.yml –flush-cache
명령어를 실행합니다.
두 세번 설치를 진행하면서 많은 오류가 발생하였습니다. EC2의 경우 아무것도 설치가 되어있지 않은 상태여서 별 다른 오류가 발생하지 않았지만, 베어메탈 서버의 경우 기존에 설치되어있는 데몬과 겹쳐서 발생하는 오류가 대부분이었습니다. 그렇기 때문에 기존 시스템의 환경을 잘 고려해서 설치하면 쉽게 설치 할 수 있을거 같습니다.
멀티 마스터 구조로 클러스터를 구성하기 위해 마스터노드를 추가하는 과정은 간단합니다. 기존 위에서 작성한 host.ini
파일에 마스터 노드를 추가하고 ansible을 실행하면 됩니다. ansible을 실행할 때 사용하는 파일은 cluster.yml
입니다 (worker node를 추가할 때는 scale.yml
을 사용합니다.), 또한 사전준비 과정에서 진행 한 ssh public key 공유와 hosts 파일 수정을 수행해야합니다.
host.ini
파일을 다음과 같이 수정합니다.
#host.ini
[k8s-cluster:children]
kube-master
kube-node
[all]
master ansible_host=172.31.5.173 ip=172.31.5.173
master2 ansible_host=172.31.43.25 ip=172.31.43.25
master3 ansible_host=172.31.37.125 ip=172.31.37.125
worker1 ansible_host=172.31.0.115 ip=172.31.0.115
worker2 ansible_host=172.31.3.174 ip=172.31.3.174
#worker3 ansible_host=172.31.58.96 ip=172.31.58.96
[kube-master]
master
master2
master3
[kube-node]
worker1
worker2
#worker3
[etcd]
master
master2
master3
[calico-rr]
[vault]
worker1
worker2
#worker3
추가로 연결 할 마스터 서버의 정보를 입력하고 Ansible 명령어를 수행하면 다음과 같이 클러스터에 추가 된 것을 확인 할 수 있습니다.
정상적으로 설치 하게 되면 다음과 같이 node가 추가된 것을 확인 할 수 있습니다.