메뉴 닫기

[ Kubernetes #03 ] Kubernetes HA 구성 배포 (#kubeadm #cri-o)

안녕하세요. 스마일서브 KoreaV 공공클라우드 사업부 김병학 입니다.

지난글에 이어서 이후 실습환경 구축을 위해서 Kubernetes 를 배포해보는 실습을 진행하려 합니다.

혹시 아직 Kubernetes 와 Container 의 개념이 조금 부족하다면 지난글을 확인해 주세요.

지난글

 

목차


  1. 개요
  2. 배포 환경
  3. Kubernetes 클러스터 구조
  4. 모듈 로드 및 ipv4 사용 지정
    1. br_netfilter 모듈 로드 확인
    2. br_netfilter 모듈 로드
    3. 필요한 모듈을 자동으로 로드하도록 설정
    4. 설정적용을 위해 모듈 로드
    5. sysctl 파라미터 설정
    6. 설정 적용
  5. repository 추가 및 kubectl, kubelet, kubeadm 설치
    1. pkgs.k8s.io apt repository 등록
  6. kubernetes 배포
    1. kubelet enable
    2. contole-plane 추가
    3. worker node 추가
  7. 배포 확인

 

1. 개요


얼마전에 Ubuntu 24.04 LTS 가 나왔고, Kubernetes 도 1.31 버전까지 Stable 버전으로 출시 되었습니다. 모두 최신버전으로 설치해보려고 이미 설치해보신 분들이 있을까 해서, 구글에서 찾아보니 별로 없더군요. 이전보다 많이 간단해져서, 설치를 진행해보고 싶으신분들은 참고하시면 좋을듯 합니다. 현 문서는 컨테이너 엔진은 cri-o 를 사용하며, kubeadm 을 사용하여 배포하는 기준으로 설명드립니다.

 

2. 배포 환경


Node OS / OS version K8s / cri-o Internal IP
master01 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.10
master02 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.19
master03 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.11
worker01 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.4
worker02 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.7
worker03 Uubntu 24.04 LTS 1.30.1 / cri-o 10.101.0.16
lb01     10.101.0.18

master 노드를 3개로 구성하기 위해서는 kubeapi 의 통신을 위해서 Proxy 서버나 lb가 필요로 합니다. 저는 저희 회사의 iwinv 서비스의 lb를 사용할 예정이고, 혹여나 다른 CSP 사 또는 온프레미스에서 구성하신다면 Proxy 서버등을 사용하시면 좋을듯 합니다.

 

3. Kubernetes 클러스터 구조


 

중첩된 etcd 토플로지
출처 : https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/ha-topology/

해당 그림은 Kubernetes Document 에 올라와 있는 사진입니다. 저희가 배포하려는 환경은 위 사진과 worker node 의 갯수만 다를뿐 동일합니다.
가장 주목해야 할 점은, etcd 의 가용성을 1개 또는 3개 이상을 보장해야한다는점과 각 노드는 kubeapi(6443 port) 를 통해서 통신한다는 점입니다.
etcd는 아래 참고로 적어두겠습니다. etcd와 그 외 컴포넌트에 대해서는 추후 따로 정리하도록 하겠습니다.

etcd 란?
etcd는 분산 시스템에서 사용하는 key=value 저장소로, Raft 합의 알고리즘을 통해 일관성을 보장합니다. 고가용성을 위해 etcd는 최소 3개 이상의 노드가 필요합니다. 이는 합의 알고리즘의 특성상 2개의 클러스터링으로는 안정적인 합의와 데이터 일관성을 유지하기 어렵기 때문입니다. 

 

4. 모듈 로드 및 ipv4 사용 지정


참고 : 해당 게시글은 kubernetes Document 를 활용하여 작성하였습니다.

아래 작업은 모든 노드에서 진행합니다.

1. br_netfilter 모듈 로드 확인

먼저, br_netfilter 모듈이 로드되었는지 확인해야 합니다. 아래 명령어를 실행하여 모듈이 로드되어있는지 확인합니다.

lsmod | grep br_netfilter

아무것도 출력되지 않는다면, br_netfilter 모듈이 로드되지 않은것이므로 br_netfilter 모듈을 로드합니다.

2. br_netfilter 모듈 로드

아래 명령어를 통하여 br_netfilter 모듈을 로드합니다.

sudo modprobe br_netfilter

3. 필요한 모듈을 자동으로 로드하도록 설정

Kubernetes에서 필요한 모듈을 시스템 부팅 시 자동으로 로드되도록 설정합니다.
아래 명령어를 실행하여 /etc/modules-load.d/k8s.conf 파일에 필요한 모듈을 추가합니다

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

4. 설정적용을 위해 모듈 로드

위 설정이 적용되도록 모듈을 로드합니다.

sudo modprobe overlay
sudo modprobe br_netfilter

5. sysctl 파라미터 설정

Kubernetes 노드의 iptables가 브리지된 트래픽을 올바르게 처리하도록 sysctl 파라미터를 설정합니다.
아래 명령어를 실행하여 /etc/sysctl.d/k8s.conf 파일에 필요한 설정을 추가합니다.

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
  • net.bridge.bridge-nf-call-iptables = 1: 네트워크 인터페이스에서 iptables를 통해 트래픽을 필터링할 수 있도록 합니다.  Kubernetes 에서 네트워크 정책을 제어하기위해 필요합니다.
  • net.bridge.bridge-nf-call-ip6tables = 1: IPv6 트래픽에 대해서도 iptables 필터링을 적용합니다.
  • net.ipv4.ip_forward = 1: IP 포워딩을 활성화하여 패킷이 네트워크 인터페이스 간에 라우팅될 수 있게 합니다.  각 노드 및 외부 네트워크 접근에 필요합니다.

6. 설정 적용

재부팅하지 않고 sysctl 파라미터를 적용하기위해서 아래와 같이 명령어를 입력합니다.

sudo sysctl --system

이로서 배포 이전에 필요한 설정은 완료 되었습니다.

 

5. repository 추가 및 kubectl, kubelet, kubeadm 설치


Kubernetes 1.29 부터 crio 가 https://pkgs.k8s.io 레포지토리로 통합되었다고 합니다. 따라서 이전에 설치하셨던 분들은 crio 레포지토리를 따로 추가하여야 했지만, 최신 버전부터는 https://pkgs.k8s.io 만 사용합니다. 관련 링크를 아래 참고로 남깁니다.

참고 자료
https://github.com/cri-o/packaging?tab=readme-ov-file
https://kubernetes.io/blog/2023/10/10/cri-o-community-package-infrastructure/

1. pkgs.k8s.io apt repository 등록

아래 코드블럭과 같이 레포지토리를 추가하고 설치를 진행합니다. 해당 작업은 모든 노드에서 진행합니다.

KUBERNETES_VERSION=v1.30
PROJECT_PATH=prerelease:/v.1.30

sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/Release.key |
    sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/$KUBERNETES_VERSION/deb/ /" |
    sudo tee /etc/apt/sources.list.d/kubernetes.list
apt update
sudo apt install -y cri-tools kubelet kubeadm kubectl cri-o

## 혹여나 cri-o 정상 설치가 안될경우 아래처럼 레포지토리 추가
PROJECT_PATH=prerelease:/v.1.30
sudo curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/Release.key |
    sudo gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg

sudo echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/ /" |
    sudo tee /etc/apt/sources.list.d/cri-o.list
sudo apt install cri-o

 

6. kubernetes 배포


1. kubelet enable

아래 명령어를 통해서 모든 노드에서 kubelet 을 시작하고 enable 상태로 변경합니다.

sudo systemctl enable --now kubelet

NOTE!

혹시 진행하다가 문제가 생겨서 다시 설치해야하는 경우 아래 순서대로 초기화하면 됩니다.

sudo kubeadm reset 
sudo rm -rf /var/lib/etcd 
sudo rm -rf /etc/kubernetes/manifests 
sudo rm -rf /etc/kubernetes/pki
sudo rm -rf ~/.kube

kubelet 이 정상적으로 작동하는것을 확인했다면 kubeadm 을 통하여 master1 node 부터 kubeadm inint 명령어를 통해 배포를 시작합니다.

sudo kubeadm init --control-plane-endpoint=lb01:6443 --pod-network-cidr=192.168.1.0/24 --upload-certs
~
~
~
Your Kubernetes control-plane has initialized successfully!

To start using your 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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join lb01:6443 --token imbp6w.mj1er4ccpxsb8t7y \
        --discovery-token-ca-cert-hash sha256:4ff4ed67e0f0986a4fdee6d06ff753daef21da611b5d33cde5d1df209acf3c33 \
        --control-plane --certificate-key f0d1142b7eab1d2e03e45d607e6ad3294d4060458453a1017d7cc8a5032d1baf

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

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

kubeadm join lb01:6443 --token imbp6w.mj1er4ccpxsb8t7y \
        --discovery-token-ca-cert-hash sha256:4ff4ed67e0f0986a4fdee6d06ff753daef21da611b5d33cde5d1df209acf3c33

명령어 설명

kubeadm init –control-plane-endpoint=lb01:6443 –pod-network-cidr=192.168.1.0/24 –upload-certs

  • --control-plane-endpoint=lb01:6443

    • 로드 밸런서의 DNS 이름 또는 IP 주소와 포트를 지정합니다. 다른 노드가 control plane 에 접근할 때 이 Endpoint를 사용합니다.

  • --pod-network-cidr=192.168.1.0/24

    • 클러스터 내에서 사용할 Pod 네트워크의 CIDR(클래스리스 도메인 라우팅) 블록을 지정합니다.
    • 추후에 네트워크 플러그인(CNI)이 지정한 CIDR 을 사용하여 네트워크를 구성하게됩니다.
  • --upload-certs

    • 이 옵션은 클러스터 초기화 중에 생성된 제어 control plane 을 공유 스토리지(ex: Kubernetes Secrets)에 업로드합니다.
    • 다른 control plane 노드를 클러스터에 추가할 때 인증서를 쉽게 가져올 수 있습니다. 고가용성 클러스터를 구성할 때 해당 옵션이 필요합니다.

정상적으로 설치가 완료되었다면 친절하게 출력메시지를 통하여 control-plane (master node) 와 worker node 를 추가하는 방법을 출력해줍니다.
출력된 명령어의 해쉬값은 2시간동안 유효합니다. 해당 명령어를 통하여 타 master node 부터 클러스터에 추가합니다.

2. contole-plane 추가

추가 하고자 하는 마스터 노드는 아래 명령어를 실행합니다.

kubeadm join lb01:6443 --token imbp6w.mj1er4ccpxsb8t7y \
      --discovery-token-ca-cert-hash sha256:4ff4ed67e0f0986a4fdee6d06ff753daef21da611b5d33cde5d1df209acf3c33 \
      --control-plane --certificate-key f0d1142b7eab1d2e03e45d607e6ad3294d4060458453a1017d7cc8a5032d1baf
유저 계정에서 kubeclt 명령어를 사용하기 위해 kube 디렉토리 및 하위 파일을 생성합니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

3. worker node 추가

추가 하고자 하는 워커 노드는 아래 명령어를 실행하여 노드에 추가합니다.

kubeadm join lb01:6443 --token imbp6w.mj1er4ccpxsb8t7y \
      --discovery-token-ca-cert-hash sha256:4ff4ed67e0f0986a4fdee6d06ff753daef21da611b5d33cde5d1df209acf3c33

 

7. 배포 확인


모든 배포가 완료되었다면, kubectl get nodes 명령어를 통해서 node 가 정상적으로 추가되었는지 확인할 수 있습니다.

~$ kubectl get nodes
NAME       STATUS   ROLES    AGE    VERSION
master01   Ready    master   5d1h   v1.30.1
master02   Ready    master   5d1h   v1.30.1
master03   Ready    master   5d1h   v1.30.1
worker01   Ready    <none>   5d1h   v1.30.1
worker02   Ready    <none>   5d1h   v1.30.1
worker03   Ready    <none>   5d1h   v1.30.1

 

이곳까지 모두 따라오셨다면, 이제 기본적인 kubernetes 클러스터 의 배포는 완료되었습니다. 축하드립니다.

하지만 아쉽게도 현재 배포한 k8s 클러스터는 완벽하게 활용가능한 클러스터가 아닙니다. kubernetes 를 조금더 아름답게 만들기 위해서는 몇가지 플러그인의 사용이 필요합니다. 그래도 오늘은 설치를 마무리한것에 자축하고 이후에 각종 리소스및 기능과 플러그인의 추가방법에 대해서 설명하겠습니다.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x