본문 바로가기
K8s/Practices

[K8s] K8s 클러스터를 직접 구성해보자

by okms1017 2023. 8. 22.
728x90

✍ Posted by Immersive Builder  Seong

 

오늘은 간단하게 쿠버네티스를 설치하고 클러스터를 구성해보겠습니다. 

 

클라우드 서비스로 제공하는 쿠버네티스 도구(GKE, EKS, AKS, NKS 등)를 이용하기엔 비용이 많이 발생하므로

하이퍼바이저 위에 쿠버네티스를 직접 설치하여 실습 환경을 만들어볼 예정입니다. 

 

 


1. 준비물 

 

- Oracle VirtualBox 또는 VMWare 등 하이퍼바이저 

- 느긋하고 여유로운 마음 

 

 

2. 사전 작업 

 

K8s 클러스터는 Master Node 한 대, Worker Node 두 대로 최소 구성하고 

추후에 필요하면 추가 생성하는 방식으로 진행하겠습니다. 

 

Oracle VirtualBox 무료버전을 설치하고 실행합니다. 

 

 

각 노드의 사양을 CPU 2Core / MEM 2GB / DISK 10GB 로 생성합니다. 

그리고 모든 노드에 Ubuntu 20.04 LTS OS를 설치합니다. 

 

 

노드에 접속하여 sshd, net-tools 등 네트워크 관련 설치를 진행합니다. 

 

$ sudo apt install net-tools (ifconfig)
$ sudo apt install openssh-server (sshd)

 

작업의 편의성을 위해 쉘프로그램(MobaXterm)을 이용하여 노드에 접속합니다. 

이 때 네트워크 방식은 NAT Network로 구성하고 노드별로 포트를 구분하여 포트포워딩 설정을 합니다. 

이것저것 설치를 위해 외부에서 다운로드해야하므로  호스트 전용 네트워크로 설정하지 않았습니다. 

(접속용 호스트 전용 네트워크와 인터넷 연결용 NAT를 조합하여 어댑터 2개로 구성하는 방식도 생각해볼 수 있겠습니다) 

 

※ NAT vs NAT Network

NAT 방식은 내부에서 외부로 송신하는 기능을 하며, 내부 VM들끼리 통신할 수 없고 외부에서 내부로 접근이 불가합니다. 

외부 호스트에서 내부 VM으로 접근하려면 포트포워딩을 설정해야 합니다. 

 

NAT Network 방식은 NAT와 동일한 기능을 하나, 내부 VM들이 동일한 브로드캐스트 도메인 내에 존재하여 서로 다른 사설 IP를 가지고 서로 통신이 가능한 장점이 있습니다. 마치 도커 컨테이너 네트워크와 유사한 모습입니다. 

 

VirtualBox Interface GW

 

NAT Network

 

Geust OS IP

 

포트는 8022~8024 포트를 사용하겠습니다. 

 

포트포워딩(SSH)

 

노드 접속이 잘 됩니다. 

 

 

 

 

컨테이너를 실행할 수 있는 환경을 구성하기 위해 도커를 설치해줍시다. 

 

$ sudo apt-get update
$ sudo apt-get install -y ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
$ sudo apt-get update
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo systemctl enable docker
$ sudo systemctl start docker
$ sudo docker run hello-world

 

도커가 정상적으로 설치되었습니다. 

 

도커 설치 완료

이제 사전 작업은 다 끝났습니다. 

 

 

3. K8s 설치 

 

시작하기 전에 스왑(Swap) 메모리를 비활성화해야 합니다. 

스왑이란 하드디스크 일부를 메모리처럼 사용하는 기능으로 메모리가 부족할 때 당장 사용하지 않는 프로세스를 디스크로 옮겨서 특정 프로세스를 실행시키는 것을 말합니다.  

 

쿠버네티스의 Kubelet은 노드 에이전트로서 각 노드에 파드(Pod)를 생성하고 정상적으로 동작하는지 관리하는 역할을 수행하는데요. 

파드 생성 시, Kubelet이 스왑 메모리까지 고려하여 리소스를 할당하지는 않는다고 합니다. 

 

## 스왑 임시 비활성화 
$ sudo swapoff -a
## 스왑 영구 비활성화 
$ sudo sed -i '/swap/s/^/#/' /etc/fstab

 

클러스터 간에 네트워크 통신이 가능하도록 브릿지 설정을 활성화합니다.  

 

$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sudo sysctl --system

 

아.. 노드 디스크 용량을 너무 적게 할당한 거 같네요. (겨우 10GB 주고 뭐하냐 나란놈 !)

 

 

쓸모없는 캐시를 비워줍니다. 

 

 

디스크 용량을 20GB 로 증설해봅시다. 

 

 

$ sudo apt install -y gparted
$ sudo gparted

 

/dev/sda3 파티션 증설
/dev/sda5 파티션 증설

 

디스크 용량이 증설되었습니다. 

 

디스크 용량 증설 확인

 

다시 본론으로 돌아가서.

 

 

OS 방화벽은 동작하지 않으므로 손대지 않습니다. 

Selinux 설정을 비활성화 합니다. 

 

$ sudo apt install -y selinux-utils
$ sudo apt install -y policycoreutils
$ sudo setenforce 0
$ sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

 

모든 노드에 kubeadm, kubelet, kubectl을 설치해줍니다. 

 

$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl

$ sudo systemctl enable kubelet
$ sudo systemctl restart kubelet

 

 

kubelet.service 가 동작중인지 확인해봅시다. 

프로세스와 PID 상태가 FAILURE 로 뜨고 있네요. 

 

 

무엇이 문제인지 좀 더 자세히 로그를 들여다봅시다. 

 

 

kubelet 설정 파일을 불러올 수 없다고 합니다. 

실제로 해당 경로(/var/lib/kubelet/)에 설정 파일(config.yaml)이 존재하지 않는 것을 확인할 수 있었습니다. 

 

그리고 주기적으로 kubelet 서비스가 정지 / 시작을 반복하고 있는 모양새입니다. 

왜그런고 하니 kubeadm 서비스가 실행되지 않으면 loaded 상태에 머무른다고 하네요. 

 

다음 Step 에서 control-plane 을 구성하면 자연스럽게 해결될 것으로 보입니다. 

 

 

4. 클러스터 구성 

 

Master Node 에 Etcd, API Server 등을 포함한 쿠버네티스 컴포넌트들을 생성합니다. 

 

$ sudo kubeadm init

 

이건 또 무슨 에러일까.. 해결해보자 (CRI ERROR 어쩌궁) 

' container runtime is not running' 도커 환경에 문제가 있는 듯합니다.

 

 

구글링하여 깔끔한 해결방법 발견 ! 

원인은 containerd 데몬에서 CRI 옵션이 이슈인 것으로 추정.

 

# config.toml : containerd 구성 파일
$ sudo rm /etc/containerd/config.toml
$ sudo systemctl restart containerd
$ sudo kubeadm init

 

이제 잘 된다..!

 

 

화면에 출력된 내용을 토대로 후속작업을 해주자. 

 

$ sudo mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

kubectl 명령어가 잘 동작하는 것을 확인할 수 있습니다. 

지금 Master Node 만 출력되므로 나머지 Worker Node 들도 파드 네트워크로 연결하여 출력되도록 해보자. 

 

 

파드 네트워크의 종류가 아주 다양합니다. 

저는 Flannel 으로 구성해보겠습니다. 

(* 파드 네트워크 종류별 특징을 시간나면 정리해 볼 예정입니다.) 

 

$ wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
$ vi kube-flannel.yml
  "10.244.0.0/16" -> "10.0.2.0/24"
$ kubectl apply -f kube-flannel.yml

 

 

각 Worker Node 에서 토큰을 이용하여 Master Node 에 조인합니다. 

 

$ sudo kubeadm join 10.0.2.15:6443 --token doz0ku.n5j8nqyzod6gkwxq \
        --discovery-token-ca-cert-hash sha256:0868f160bea3299a2211c61bb6e229bca6737efd8804765398b47d2d19d6bf5c

 

Worker Node 01 Join
Worker Node 02 Join
Master Node - kubectl get nodes
kubelet 서비스 상태 확인

 

 


마지막으로 K8s 명령어 자동완성 기능을 추가합니다. 

 

$ source <(kubectl completion bash)
$ echo "source <(kubectl completion bash)" >> ~/.bashrc

$ source <(kubeadm completion bash)
$ echo "source <(kubeadm completion bash)" >> ~/.bashrc

 


자 이렇게 쿠버네티스 공식 가이드를 참고하여 K8s 실습 환경을 구성해보았습니다. 

시행착오를 포함하여 이틀 정도 소요되었습니다. 

 

다음에는 여러가지 실습한 내용을 가지고 찾아오겠습니다. 

 

긴 글 읽어주셔서 감사합니다.

 

 

 

 


[출처] 

1) https://docs.docker.com/engine/install/ubuntu/

 

Install Docker Engine on Ubuntu

 

docs.docker.com

 

2) https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

 

Installing kubeadm

This page shows how to install the kubeadm toolbox. For information on how to create a cluster with kubeadm once you have performed this installation process, see the Creating a cluster with kubeadm page. Before you begin A compatible Linux host. The Kuber

kubernetes.io

 

3) https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/

 

Creating a cluster with kubeadm

Using kubeadm, you can create a minimum viable Kubernetes cluster that conforms to best practices. In fact, you can use kubeadm to set up a cluster that will pass the Kubernetes Conformance tests. kubeadm also supports other cluster lifecycle functions, su

kubernetes.io

 

4) https://kubernetes.io/docs/concepts/cluster-administration/addons/#networking-and-network-policy

 

Installing Addons

Note: This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the content guide

kubernetes.io

 

5) https://kubernetes.io/pt-br/docs/reference/kubectl/cheatsheet/

 

kubectl Cheat Sheet

Esta página contém uma lista de comandos kubectl e flags frequentemente usados. Kubectl Autocomplete BASH source <(kubectl completion bash) # configuração de autocomplete no bash do shell atual, o pacote bash-completion precisa ter sido instalado prime

kubernetes.io

728x90