Docker

쿠버네티스(k8s) 클러스터 만들기

기억보다는 기록을... 2025. 2. 26. 13:58

쿠버네티스 클러스터 만들기

  • 최소 구성은 마스터 1노드, 워커 2노드로 가능하나, 마스터 1노드, 워커 3노드로 구성 진행
  • 최소 사양
    • Minimum 2GB RAM or more.
    • Minimum 2 CPU cores (or 2 vCPUs).
    • 20 GB of free disk space on /var (or more).

 

서버 구성

Master Node Worker Node Worker Node Worker Node
- k8smaster1
- 10.0.0.230
- 4Core, 4GB 메모리
- Ubuntu 24.04.2 LTS
- k8sworker1
- 10.0.0.231
- 4Core, 4GB 메모리
- Ubuntu 24.04.2 LTS
- k8sworker2
- 10.0.0.232
- 4Core, 4GB 메모리
- Ubuntu 24.04.2 LTS
- k8sworker3
- 10.0.0.233
- 4Core, 4GB 메모리
- Ubuntu 24.04.2 LTS

 


 

공통 설정

1. Swap Memory 비활성화

  • Pod가 SWAP 영역으로 빠지게 되면 성능저하가 발생하기 때문에 쿠버네티스에서는 SWAP을 사용하지 않음.
  • 재부팅 후에도 적용 되도록 /etc/fstab 에서 swap 영역 주석 처리
# free -g
               total        used        free      shared  buff/cache   available
Mem:               0           0           0           0           0           0
Swap:             15           0          15

# swapoff -a

# free -g
               total        used        free      shared  buff/cache   available
Mem:               0           0           0           0           0           0
Swap:              0           0           0

 

 

2. IPv4 Forwarding 기능 활성화 

  • 리눅스는 기본적으로 보안상 이슈로 다른 인터페이스로 패킷을 forward 하지 않음
  • 네트워크간 패킷 통신이 가능하도록 forward 설정
# cat /proc/sys/net/ipv4/ip_forward
0

# sed -i 's/^#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf

# sysctl --quiet --system

# cat /proc/sys/net/ipv4/ip_forward
1

 

 

3. 커널 파라미터 설정

  • 쿠버네티스 네트워크와 컨테이너 네트워크 간 통신을 위해 설정
# tee /etc/modules-load.d/containerd.conf <<EOF
> overlay
> br_netfilter
> EOF

# modprobe overlay
# modprobe br_netfilter

# tee /etc/sysctl.d/kubernetes.conf <<EOF
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF

 

더보기

커널 모듈 로드

  • overlay
    • 오버레이 파일시스템을 지원하는 모듈
    • 컨테이너 런타임(예: Docker, containerd)에서 사용하는 스토리지 드라이버로, 컨테이너의 계층화된 파일시스템을 생성하는 데 필요
  •  br_netfilter
    • 리눅스 브리지 네트워크 스택에서 iptables를 사용한 네트워크 필터링을 지원
    • Kubernetes의 네트워킹 플러그인(예: Calico, Flannel)이 정상적으로 작동하기 위해 필요

 

 시스템 설정 (sysctl)

  • net.bridge.bridge-nf-call-ip6tables = 1   /   net.bridge.bridge-nf-call-iptables = 1
    •  이 두 설정은 브리지를 통과하는 패킷이 iptables 규칙을 통과하도록 함.
    • Kubernetes의 서비스 네트워크와 파드 간 통신을 위해 필요.
    • 대부분의 Kubernetes CNI(Container Network Interface) 플러그인이 iptables를 사용하므로 이 설정이 필요.

 

 

4. Containerd 런타임 설치

  • 의존성 패키지 설치
# apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

 

  • 도커 GPG 키 추가 및 레포지토리 설정
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

 

  • Containerd 설치
# apt update
# apt install -y containerd.io

 

  • Containerd 설정 추가
# containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
# sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

 

더보기

기본 설정 파일 생성

  • containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
    • containerd config default 명령어로 기본 설정값을 출력하여 /etc/containerd/config.toml 파일에 저장
    • /dev/null 2>&1는 표준 출력과 오류 출력을 버려서 터미널 화면을 깔끔하게 유지

cgroup 드라이버를 systemd로 변경하는 과정

  • sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
    • 기본적으로 containerd는 SystemdCgroup = false 상태로 설정
    • Kubernetes는 systemd를 기본적으로 사용하여 컨테이너 리소스 관리
    • SystemdCgroup = false 상태에서는 cgroupfs가 사용되며, Kubernetes와 충돌이 발생할 수 있음.

 

  • 서비스 시작 및 활성화
# systemctl restart containerd
# systemctl enable containerd
# systemctl status containerd

 

 

5. 쿠버네티스(k8s) apt 레포지토리 추가

  • Ubuntu 기본 레포지토리에서는 쿠버네티스 패키지를 사용할 수 없음.
# echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

 

 

6. Kubectl, Kubeadm, Kubelet 설치

  • kubectl - Kubernetes 클러스터를 관리하는 CLI
  • kubeadm - 클러스터를 설치 및 초기화하는 도구
  • kubelet - 각 노드에서 컨테이너(Pod)를 실행 및 모니터링하는 에이전트
# apt update
# apt install -y kubelet kubeadm kubectl
# apt-mark hold kubelet kubeadm kubectl

 

더보기

apt-mark hold

  • apt upgrade나 apt dist-upgrade 실행 시 패키지가 최신 버전으로 업데이트 되는것을 방지.
  • 쿠버네티스의 kubelet, kubeadm, kubectl 패키지는 클러스터의 안정성을 위해 특정 버전을 유지해야 하는 경우 많음

 

잠금 해제 방법

  • apt-mark unhold kubelet kubeadm kubectl

 


 

이 후 설정은 쿠버네티스를 운영할 일반 사용자 계정(dockeruser)으로 설치를 진행하였음.

초기 설치 시 사용자 변경을 깜빡하고 진행.;;;

 


 

마스터 노드

1. k8s 초기화 (kubeadm 사용)

  • VM의 메모리 설정을 동적으로 해 놨더니 전체 메모리가 1GB로 잡혀 오류 발생
$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16
I0226 16:20:57.459189    4472 version.go:256] remote version is much newer: v1.32.2; falling back to: stable-1.30
[init] Using Kubernetes version: v1.30.10
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Mem]: the system RAM (970 MB) is less than the minimum 1700 MB
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

$ free -gh
               total        used        free      shared  buff/cache   available
Mem:           966Mi       453Mi       120Mi       3.3Mi       611Mi       513Mi
Swap:             0B          0B          0B

 

  • 동적 메모리 설정 해제 후 초기화 진행
  • CNI 플러그인을 Calico 사용 예정이라 IP 대역을 198.168.0.0/16으로 설정
    • 플러그인별 기본 CIDR - Flannel(10.244.0.0/16), Calico(192.168.0.0/16)
    • 네트워크 플러그인에 맞는 CIDR을 설정하지 않으면 클러스터 내 Pod 간 통신이 되지 않을 수 있음
  • 마지막 kubeadm join 부분은 워커 노드 추가를 위해 복사
$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16
I0226 16:27:38.259697    1179 version.go:256] remote version is much newer: v1.32.2; falling back to: stable-1.30
[init] Using Kubernetes version: v1.30.10
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster

생략...

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

kubeadm join 10.0.0.230:6443 --token llxpmg.wao1c2cj5dwn2l3s \
        --discovery-token-ca-cert-hash sha256:b192d79f1eff212762c8e6a99c7d782c28373641a33c8b12eacb57e74a62663e

 

 

2. 클러스터 운영 계정 설정

  • 일반 사용자 계정(dockeruser)에서 kubectl 명령어를 사용하여 쿠버네티스 클러스터를 관리 할 수 있도록 설정
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

 

3. Calico 플러그인 설치

  • 쿠버네티스 사용자 계정(dockeruser)에서 실행
$ kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

 

  • kubelet(모니터링 에이전트) 재시작
$ sudo systemctl restart kubelet

 

 

4. 상태 확인

  • NotReady -> Ready 로 변경까지 시간이 걸림.
dockeruser@k8smaster1:~$ kubectl get no
NAME         STATUS     ROLES           AGE   VERSION
k8smaster1   NotReady   control-plane   11m   v1.30.10

dockeruser@k8smaster1:~$ kubectl get no
NAME         STATUS   ROLES           AGE   VERSION
k8smaster1   Ready    control-plane   12m   v1.30.10

 


 

워커 노드

1. 워커 노드 추가

  • 각 노드(k8sworker1~3)에서 실행 
$ sudo kubeadm join 10.0.0.230:6443 --token llxpmg.wao1c2cj5dwn2l3s \
        --discovery-token-ca-cert-hash sha256:b192d79f1eff212762c8e6a99c7d782c28373641a33c8b12eacb57e74a62663e

 


 

마스터 노드

1. 클러스터 구성 확인

$ kubectl get no
NAME         STATUS   ROLES           AGE     VERSION
k8smaster1   Ready    control-plane   4m36s   v1.30.10
k8sworker1   Ready    <none>          2m41s   v1.30.10
k8sworker2   Ready    <none>          2m      v1.30.10
k8sworker3   Ready    <none>          110s    v1.30.10

 

 

2. 서비스 IP 범위와 클러스터 Pod IP 범위 확인

  • --service-cluster-ip-range - 클러스터 내에서 서비스에 할당될 IP 주소 범위
  • --cluster-cidr - Pod들에게 할당되는 IP 주소 범위
$ kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"
                            "--service-cluster-ip-range=10.96.0.0/12",
                            "--cluster-cidr=192.168.0.0/16",