Kubernetes Cluster 설치 및 구축 (Ubuntu 18.04)

Gunyoung Yoon·2021년 2월 17일
4

컨테이너 스터디

목록 보기
2/3
post-thumbnail

최근 진행하고 있는 Container Study에서 나온 실습 과제인 Kubernetes Cluster 구축하기를 진행하면서 한 내용을 기록하기 위한 글이다. 대부분 쿠버네티스가 제공하는 공식 문서를 참고해서 진행했다. 이번에 설치하면서 확실히 느낀건데, 단기간에 여러곳에서 사용되기 시작하며 소위 "핫한" 오픈소스 프로젝트들은 문서화가 굉장히 잘 되어있다고 생각한다. Ubuntu가 기반한 Debian 프로젝트에 비해서 상대적으로 문서화가 잘 되어있고, 레퍼런스나 포럼이 잘 운영되고 있듯이, 쿠버네티스도 문서화와 커뮤니티가 프로젝트가 널리쓰이는데 큰 기여를 했다고 생각한다.

참고로 아래의 1번부터 N번까지는 Control-Plane(Master) / Worker 모두에게 공통적으로 적용되는 부분이고, N번만 Control-Plane / Worker 역할에 따라서 설정해주면 된다.

1. OS 설치

쿠버네티스를 설치하기 위해서 OS 제약은 없는 것으로 알고있지만, 이 글에서는 Ubuntu 18.04 LTS 버전을 기준으로 설명 할 예정이다. 설치 과정에서 docker 등의 설치가 가능하지만, 실습을 위해서 구축하는 만큼 openssh-server 외에는 별도로 설치하지 않았다.

OS Version: Ubuntu 18.04.05 LTS (Server)

OS가 설치된 후, hostname과 network(IP) 설정 등 기본적인 설정을 하고, 패키지를 최신으로 업데이트 하였다.

1.1 Hostname 변경

주의: Hostname에는 영문 소문자(a-z), 숫자(0-9), 그리고 하이폰(-)만 사용해야 한다. Ref.

sudo hostnamectl set-hostname (NEW_HOSTNAME)
Ex1. sudo hostnamectl set-hostname devops-master
Ex2. sudo hostnamectl set-hostname devops-worker-1

hostnamectl로 변경한 후, /etc/hosts 파일을 확인하여 127.0.0.1에 변경된 hostname이 매핑되어있는지 확인한다. (DNS lookup 실패로 Warning이 날 수 있다.)

1.2 Network 설정

Ubuntu 18.04 부터는 Netplan이 기본 네트워크 설정 도구로 사용되고 있어, /etc/netplan/ 안의 설정을 변경하면 된다. Netplan을 사용하여 Ubunut의 네트워크 설정을 변경하는 부분에 대해서는 추후 별도 글로 다룰 예정이다.

1.3 패키지 업그레이드

기본으로 설치되어있는 패키지들을 최신으로 업그레이드 한다.

sudo apt update
sudo apt upgrade

2. Swap OFF 진행

쿠버네티스를 실행하기 위해서는 OS의 SWAP을 꺼줘야한다.

sudo swapoff -a
vi /etc/fstab  # SWAP이 정의된 줄을 '#'으로 주석처리해준다.

3. NTP(Network Time Protocol) 설정

클러스터는 보통 여러개의 VM이나 서버로 구성되기 때문에, 클러스터 내의 모든 노드들은 NTP를 통해서 시간 동기화가 되어야 한다. 공식 문서에 따르면 노드간에 시간차가 클 경우, 문제가 될 수 있다고 한다.

sudo apt install ntp
sudo service ntp restart
sudo ntpq -p

4. k8s 런타임 준비

쿠버네티스를 구동하기위한 런타임을 구성해야 한다. containerd, docker, CRI-O 세가지 런타임에 대한 방법이 공식 문서에 있지만, 이번에 실습에서는 도커를 사용했기 때문에 도커 기준으로 작성한다.

# apt가 HTTPS로 리포지터리를 사용하는 것을 허용하기 위한 패키지 설치
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common gnupg2

# 도커 공식 GPG 키 추가:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -

# 도커 apt 리포지터리 추가:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# 도커 CE 설치
sudo apt-get update && sudo apt-get install -y containerd.io=1.2.13-2 docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs)

## /etc/docker 생성
sudo mkdir /etc/docker

# 도커 데몬 설정
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# /etc/systemd/system/docker.service.d 생성
sudo mkdir -p /etc/systemd/system/docker.service.d

# 도커 재시작 & 부팅시 실행 설정 (systemd)
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker

5. Kubeadm 및 그 외 util 설치

쿠버네티스 관련 유틸리티인 kubeadm, kubelet, 그리고 kubectl를 설치한다. 이 과정 역시 공식 문서에 가이드가 잘 나와있다. 간단하게 찾아본 각 유틸리티들의 용도와 설명은 아래와 같다.

  • Kubeadm: 클러스터 부트스트랩(bootstrapping)을 위한 도구이다. (쿠버네티스에서의 부트스트랩이란 클러스터를 구축하고 실행하는 과정을 말하는 것이다.)
  • kubelet: 클러스터의 모든 노드에서 실행되는 컴포넌트로, 파드나 컨테이더를 실행하는 등의 동작을 수행한다.
  • kubectl: 쿠버네티스의 클러스터를 제어하기 위한 CLI 도구이다.
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

6. 클러스터 구성

5번까지 완료를 하였다면, 기본적인 환경구축은 완료를 한 것이다. 이제 각 머신(혹은 VM)의 역할에 따라 Control-Plane으로, 혹은 Worker로 구성을 해주면 된다.
Control-Plane과 노드들의 역할과 전체적인 클러스터 아키텍처는 공식 문서에서 확인 할 수 있다.

  • Control-Plane: 클러스터의 전체적인 관리를 맡아서 진행하고, 컨테이너나 파드를 새로 띄우거나 삭제하는 명령을 내릴뿐 실제 구동이 되는 머신은 아니다.
  • Worker (Nodes): 컨테이너 런타임을 사용하여 실제 컨테이너가 실행되는 머신이다.

일반적인 경우 Control-Plane과 Worker 노드는 모두 각각 다른 공간에서 수행 되게끔 구성해준다. 물론 한 머신에 두 역할 모두 수행 할 수 있게 해주어도 상관은 없지만, 권장되는 방법은 아니다. 주변의 실제 운영환경 사례를 보아도 장애에 대비하여 Control-Plane과 Worker 노드는 분리를 해주고, 각각 여러개를 구성하는 것으로 알고있다.

클러스터 구성방법은 공식 문서에서 자세히 다뤄주고 있다.

6.1 Control-Plane

sudo kubeadm init --apiserver-advertise-address (마스터 노드 접속 가능한 IP) --pod-network-cidr=(클러스터 내부적으로 사용할 네트워크 대역)
sudo kubeadm init --apiserver-advertise-address 192.168.42.3 --pod-network-cidr=192.168.100.0/24

정상적으로 Control-Place 초기화가 된 경우, 하단에 아래와 같은 문구가 뜬다.

Your Kubernetes control-plane has initialized successfully!
To start using yout 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

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.31.0.100:6443 --token (TOKEN) --discovery-token-ca-cert-hash (DISCOVERY_HASH)

가운데 위치한 명령어 세줄은 Control-Plane에서 실행해준다. 마지막 줄의 kubeadm join 명령어를 모두 복사하여, Worker 노드에서 실행해주면 된다.

6.2 Worker 노드

Control-Plane initialize 과정에서 복사한 kubeadm join 명령어를 sudo 권한으로 실행해준다.

sudo kubeadm join (마스터 노드 접속 가능한 IP):6443 --token (TOKEN) --discovery-token-ca-cert-hash (DISCOVERY_HASH)

7. 오버레이 네트워크 설치

Control-Plane에서 kubeadm을 통해 init을 할 때, --pod-network-cidr 옵션을 준 경우, 오버레이 네트워크를 별도로 설치해주어야 한다. 일반적으로 사용되는 오버레이 네트워크는 Flannel, WeaveNet, Calico 등이 있는데, 각 오버레이 네트워크별 특징 및 설명은 별도 글에서 다룰 예정이다. 이 가이드에서는 Calico를 사용한다.

wget https://docs.projectcalico.org/manifests/calico.yaml
sed -i -e 's?192.168.0.0/16?(클러스터 내부적으로 사용할 네트워크 대역)?g' calico.yaml
kubectl apply -f calico.yaml

8. 최종 확인

Control-Plane 노드에서 아래 명령어를 수행하여 Worker 노드가 정상적으로 클러스터에 등록되었는지 확인한다.

kubectl get nodes

정상적으로 등록이 되었다면, 아래와 같이 나와야 한다. 아래 결과는 Control-Plane 1개, Worker 노드 2개로 클러스터를 구축 한 결과이다.

➜  ~ kubectl get nodes
NAME       STATUS   ROLES                  AGE   VERSION
devops-1   Ready    control-plane,master   40h   v1.20.2
devops-2   Ready    <none>                 39h   v1.20.2
devops-3   Ready    <none>                 39h   v1.20.2

번외

쿠버네티스 치트시트를 모든 kube 명령어들의 자동완성을 위한 쉘 설정을 해줄 수 있다고 한다. 특히 Control-Plane에서는 kube 명령어를 자주 쓰기때문에 해주면 매우 편리하다.

profile
이유있는 코드를 짜려고 노력하는 개발자

0개의 댓글