Vitality 팀에 있을때 EKS 로 구축된 시스템을 운영했었습니다. 지금은 해당 팀이 해체 되면서 운영하고 있지는 않지만 그때 내부적으로 진행했던 프로젝트들의 기억을 되살리고자 포스트로 남기려고 합니다.
🤔 쿠버네티스 운영환경 선택
지속적으로 쿠버네티스 환경을 운영도 하면서 공부도 하고 싶어 여러가지 환경을 검토해봤는데, EKS 는 일단 컨트롤 플레인 자체만으로도 한달에 7만원 정도가 나와 Pass (너무 비싸 😭), 로컬 PC 에 Minikube 를 이용하는 방법은 노트북을 너무 핫하게 만드는 방법이라 Pass
요즘 알리에서 미니 PC 가 싸게 풀리고 있고 시스템 초기 구입 비용 빼면 운용하는데는 매월 전기세만 내면 돼 크게 부담이 안될 것 같아 미니 PC 를 이용한 서버를 구축하기로 했습니다.
✅ 1. 쿠버테니스 설치전 사전 세팅
1.1 swap 비활성화
쿠버네티스를 설치하기 전에 리눅스 메모리 swap 을 비활성화 해줘야 합니다.
sudo swapoff -a # 부팅 시에도 swap이 활성화되지 않도록 /etc/fstab 파일에서 swap 관련 항목 주석 처리 sudo sed -i '/swap/d' /etc/fstab
1.2 iptables 설정
# 네트워크 모듈 로드 cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF
sudo modprobe overlay sudo modprobe br_netfilter
# sysctl 파라미터 설정 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
쿠버네티스 설치에 필요한 패키지를 다운 받을 수 있도록 아래 명령어를 이용해 apt 저장소에 GPG 키와 Kubernetes 저장소를 추가해줍니다.
# GPG 키 다운로드 및 저장 curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo tee /etc/apt/keyrings/kubernetes-apt-keyring.asc > /dev/null # apt 저장소에 쿠버네티스 저장소 추가 echo"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null # 위 내용이 반영될 수 있도록 apt 저장소를 업데이트합니다. sudo apt update
쿠버네티스 저장소가 추가 됐으면 apt 명령어를 이용해 kubelet, kubeadm, kubectl 을 설치해줍니다.
# 설치 가능한 버전 확인 sudo apt-cache madison kubeadm # 버전을 명시해서 설치가능 sudo apt-get install -y kubelet=1.27.16-1.1 kubeadm=1.27.16-1.1 kubectl=1.27.16-1.1 sudo apt-mark hold kubelet kubeadm kubectl
✅ 3. Kubernetes 클러스터 초기화
kubelet, kubeadm, kubectl 가 완료되면 kubeadm init 명령어를 이용해 쿠버네티스 컨트롤 플레인 노드를 초기화 시켜줍니다.
kubeadm init 추가적인 파라미터를 확인하고 싶을 경우 쿠버네티스 공식 문서 에서 확인할 수 있습니다.
sudo kubeadm init --pod-network-cidr=10.0.0.0/16 --v=5 # 외부 Listening 할 수 있는 IP 가 있는 경우 sudo kubeadm init --control-plane-endpoint=<접속_IP> --pod-network-cidr=<Pod_네트워크_범위>
Config 파일을 이용한 클러스터 초기화
config 파일을 별도로 생성해 쿠버네티스 클러스터를 생성하는 방법도 있습니다.
apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: "v1.29.3"#설치할 쿠버네티스 버전 controlPlaneEndpoint: "<접속_IP>:<접속_PORT>"#외부 IP 주소와 포트 지정 networking: podSubnet: "10.244.0.0/16"#Pod 네트워크 범위 설정
hi kubeadm 1.29.13-1.1 amd64 Command-line utility for administering a Kubernetes cluster hi kubectl 1.29.13-1.1 amd64 Command-line utility for interacting with a Kubernetes cluster hi kubelet 1.29.13-1.1 amd64 Node agent for Kubernetes clusters ii kubernetes-cni 1.3.0-1.1 amd64 Binaries required to provision kubernetes container networking
✅ 5. Control Plain Taint 삭제
쿠버네티스를 초기화하게되면 Control Plane 노드에 Pod 설치를 못하도록 (Schedule 이 불가능) Taint 설정이 들어가 있습니다.
Control Plane 에도 Pod 설치가 가능하게 (Schedule 이 가능하게) 하려면 해당 노드에 걸려있는 Taint 설정을 해지해줘야 합니다.
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.
I0202 21:12:59.135308 6955 version.go:256] remote version is much newer: v1.32.1; falling back to: stable-1.29 [init] Using Kubernetes version: v1.29.13 [preflight] Running pre-flight checks [WARNING Swap]: swap is supported for cgroup v2 only; the NodeSwap feature gate of the kubelet is beta but disabled by default error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR CRI]: container runtime is not running: output: time="2025-02-02T21:12:59+09:00" level=fatal msg="validate service connection: validate CRI v1 runtime API for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService" , error: exit status 1 [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables does not exist [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
⚠️ [kubelet-check] It seems like the kubelet isn’t running or healthy.
kubelet 상태가 현재 정상적이지 않다는 오류가 발생하고 있어, 아래 명령어들을 이용해 kubelet 상태를 확인해봅니다.
## 서비스 상태 확인 sudo systemctl status kubelet ## 로그 확인 sudo journalctl -xeu kubelet | tail -n 50
🔎 failed to run Kubelet: running with swap on is not supported
로그를 확인해보면 현재 메모리 스왑으로 인해 kubelet 이 정상적으로 실행되지 않음을 확인할 수 있습니다.
Kubernetes는 swap 을 사용하면 정상적으로 동작하지 않으므로 반드시 비활성화 해주어야 합니다.
Feb 02 23:16:56 ddanzit-ubuntu-desktop kubelet[20910]: E0202 23:16:56.465663 20910 run.go:74] "command failed" err="failed to run Kubelet: running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false. /proc/swaps contained: [Filename\t\t\t\tType\t\tSize\t\tUsed\t\tPriority /swap.img file\t\t8388604\t\t0\t\t-2]" Feb 02 23:16:56 ddanzit-ubuntu-desktop systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE ░░ Subject: Unit process exited ░░ Defined-By: systemd ░░ Support: http://www.ubuntu.com/support ░░ ░░ An ExecStart= process belonging to unit kubelet.service has exited. ░░ ░░ The process' exit code is 'exited' and its exit status is 1. Feb 02 23:16:56 ddanzit-ubuntu-desktop systemd[1]: kubelet.service: Failed with result 'exit-code'. ░░ Subject: Unit failed ░░ Defined-By: systemd ░░ Support: http://www.ubuntu.com/support ░░ ░░ The unit kubelet.service has entered the 'failed' state with result 'exit-code'.