이번에는 클라우드가 아닌 로컬 온프레미스 환경에서 직접 Kubernetes 클러스터를 구성해보겠습니다.
MacOS 환경을 기반으로, 가상 머신 설정부터 Kubernetes 설치 및 네트워크 구성까지 총 9단계에 걸쳐 단계별로 설정을 진행하겠습니다.
1. Rock Linux 이미지 다운로드
실습은 Rocky Linux 기반으로 진행되므로, 아래의 리눅스 이미지를 미리 다운로드합니다.
2. VM 설정
MacOS는 VirtualBox를 공식적으로 지원하지 않으므로, UTM이라는 가상화 도구를 사용해야 합니다.
- UTM 다운로드: https://mac.getutm.app
다운로드 받은 UTM을 실행시키면 다음과 같은 화면이 나옵니다. 여기서, 새로운 가상머신 생성을 눌러줍니다.

가상화를 클릭해주고 다운로드 받은 ISO 디스크 이미지를 선택해줍니다.

RAM, CPU, Strorage의 경우, 다음과 같이 설정합니다.

네트워크의 경우 192.168.56.0/24 대역으로 지정합니다.
이 설정은 VM과 호스트 간 통신이 가능한 내부 네트워크를 구성하기 위함이며, 이후 고정 IP 설정이나 노드 간 통신에 사용됩니다.
UTM에서 Shared Network 모드를 사용하면 NAT 기반으로 인터넷 연결도 가능하면서, 같은 네트워크 대역 안에서 가상 머신들끼리도 직접 통신할 수 있는 구조가 됩니다. 따라서 Kubernetes 클러스터를 구성할 때 노드 간 통신과 Pod 네트워크 구성을 위해 고정된 프라이빗 네트워크 대역을 지정하는 것이 중요합니다.

Rocky Linux 설치를 완료한 후, 가상 머신이 네트워크에 정상적으로 연결될 수 있도록 고정 IP 설정을 해줘야 합니다.
IPv4 설정 탭에서 수동(Manual) 방식을 선택하고, 다음과 같이 설정합니다:
- 주소: 192.168.56.30
- 넷마스크: 255.255.255.0
- 게이트웨이: 192.168.56.1
이렇게 설정하는 이유는 다음과 같습니다.
- 고정 IP 필요
- Kubernetes 클러스터에서는 마스터 노드와 워커 노드가 서로 통신하기 위해 고정된 IP 주소를 사용하는 것이 필수입니다. DHCP로 할당된 IP는 재부팅 시 변경될 수 있기 때문에 클러스터가 정상적으로 동작하지 않을 수 있습니다.
- 게스트 네트워크 대역과 일치
- 앞서 UTM에서 설정한 네트워크 대역(192.168.56.0/24)과 일치하는 IP를 지정함으로써, 호스트와 VM 간 또는 VM 간 통신이 가능해집니다.
- 게이트웨이 설정
- 192.168.56.1은 UTM의 NAT 라우터 역할을 하는 주소입니다. 이를 게이트웨이로 설정하면 Rocky Linux에서 외부 인터넷으로도 연결이 가능합니다.
3. 터미널로 원격 접속
완료된 Linux 서버를 실행해, 로컬 터미널에서 SSH 접속이 원활한지 확인합니다.
ssh root@192.168.56.30
4. Rocky Linux 기본 설정
Kubernetes 설치 및 실행에 앞서 시스템 환경을 일관되게 맞추고, 충돌 요소를 제거해야 합니다.
타임존 설정
클러스터 전체 노드의 시간이 다르면 인증서 만료나 로그 분석이 꼬일 수 있습니다. Asia/Seoul로 통일하고 NTP로 시간 동기화합니다.
timedatectl set-timezone Asia/Seoul && timedatectl set-ntp true
chronyc makestep
패키지 설치
Kubernetes 설치 과정 중 발생할 수 있는 필수 도구 누락 경고를 방지하기 위해 필요한 패키지를 설치합니다.
iproute-tc는 네트워크 트래픽 제어 도구인 tc 명령어를 제공합니다.
- kubeadm init 실행 시 tc not found in system path라는 경고가 발생할 수 있는데, 이 패키지를 설치하면 해당 경고를 제거할 수 있습니다.
yum-utils는 yum-config-manager 등 YUM 리포지터리 설정에 필요한 유틸리티를 포함하고 있어, 이후 Docker나 Kubernetes 저장소 추가 시 사용됩니다.
yum install -y yum-utils iproute-tc
OpenSSL 및 OpenSSH 업데이트
설치 안정성 확보와 보안 강화를 위해 필수적인 과정입니다.
- openssl은 Kubernetes 설치 및 TLS 인증서 생성 과정에서 사용되며, 버전이 너무 낮으면 OpenSSL version mismatch와 같은 경고가 발생할 수 있습니다.
- openssh-server는 원격 SSH 접속을 담당하는 데몬이며, 보안 취약점을 방지하기 위해 항상 최신 상태로 유지하는 것이 좋습니다.
yum update openssl openssh-server -y
Host 파일 설정
k8s-master라는 호스트 이름과 해당 IP 주소(192.168.56.30)를 매핑해야 합니다.
- Kubernetes 클러스터를 구성할 때, 각 노드를 IP가 아닌 호스트 이름으로 식별할 수 있도록 하는 것이 일반적입니다.
- 특히 외부 DNS가 없는 온프레미스 환경에서는 이처럼 hosts 파일에 수동으로 등록해주는 방식이 많이 사용됩니다.
cat << EOF >> /etc/hosts
192.168.56.30 k8s-master
EOF
5. kubeadm 설치 전 사전작업
Kubernetes의 정상적인 작동을 막는 요소 제거 및 리눅스 시스템을 클러스터 운영에 맞게 준비해야 합니다.
방화벽 비활성화
Kubernetes는 여러 포트를 동적으로 사용하므로, firewalld가 열려 있지 않으면 노드/Pod 간 통신에 실패합니다. 실습 환경에서는 간단하게 전면 비활성화합니다.
systemctl stop firewalld && systemctl disable firewalld
Swap 비활성화
Kubernetes는 노드의 리소스(CPU/Memory)를 정확하게 파악하고 스케줄링해야 합니다. Swap이 켜져 있으면 메모리 사용량을 정확히 추정할 수 없어 kubelet이 거부합니다.
swapoff -a && sed -i '/ swap / s/^/#/' /etc/fstab
6. 컨테이너 런타임 설치
컨테이너 런타임 설치 전 사전작업
Pod 간 통신, 클러스터 외부와의 트래픽 처리에 반드시 필요합니다.
- overlay: 여러 파일 시스템을 중첩시켜 컨테이너 이미지 계층을 표현하는 데 필요합니다.
- br_netfilter: 브리지 네트워크 인터페이스를 통해 전달되는 트래픽도 iptables에서 필터링할 수 있도록 해줍니다.
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
네트워크 파라미터 설정을 해줘야 합니다. 이 설정이 없으면 Pod가 생성되더라도 외부 또는 다른 노드와 통신하지 못하는 문제가 발생할 수 있습니다.
- bridge-nf-call-iptables: 브릿지 네트워크를 통해 들어오는 트래픽도 iptables 규칙을 적용할 수 있게 합니다.
- ip_forward: Kubernetes Pod가 외부로 패킷을 전달할 수 있도록 IP 포워딩을 허용합니다.
cat <<EOF | 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
sysctl --system
containerd 설치
# containerd는 Docker에서 분리된 프로젝트이므로, Docker 저장소에서 containerd 패키지를 설치합니다.
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# containerd 패키지 설치 및 실행
yum install -y containerd.io-1.6.21-3.1.el9.aarch64
systemctl daemon-reload
systemctl enable --now containerd
컨테이너 런타임 CRI 활성화 및 Cgroup 설정
# containerd 설정 파일 생성 및 수정
containerd config default > /etc/containerd/config.toml
sed -i 's/ SystemdCgroup = false/ SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd
- containerd는 처음 설치하면 기본 설정 파일이 없기 때문에 config default 명령어로 생성합니다.
- SystemdCgroup = true로 변경해야 Kubernetes가 사용하는 systemd 기반 Cgroup 관리 방식과 containerd가 일치하게 됩니다.
- 기본값이 false이면 kubelet이 containerd와 제대로 통신하지 못해 오류가 발생할 수 있습니다.
7. Kubeadm 설치
Kubernetes 클러스터를 구성하고 관리하는 데 필요한 3대 핵심 도구를 설치합니다.
Repository 등록
- Kubernetes는 기본 CentOS/Rocky 저장소에는 존재하지 않기 때문에, 공식 패키지 저장소를 별도로 등록해야 합니다.
- exclude 옵션은 의도하지 않은 yum 업데이트로 Kubernetes 패키지가 자동 변경되는 것을 방지합니다.
- 이 저장소를 통해 버전 고정이 가능하고, gpgcheck로 패키지 무결성도 검증합니다.
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
SELinux 설정 완화
- SELinux가 enforcing 모드로 동작하면 kubelet이 Pod 생성 시 필요한 시스템 자원 접근을 차단할 수 있습니다.
- 초기 설정에서는 불필요한 충돌을 방지하기 위해 permissive 모드로 완화합니다.
- setenforce는 일시적 설정, sed는 재부팅 후에도 적용되도록 영구 변경입니다.
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
필수 도구 설치 및 kubelet 서비스 등록
- kubeadm: 클러스터를 생성하고 초기화하는 도구 (Control Plane 설정, 인증서 생성, 토큰 발급 등)
- kubelet: 각 노드에서 컨테이너를 실행하고, 상태를 감시하며, Control Plane과 통신
- kubectl: 사용자나 관리자가 클러스터를 제어할 수 있도록 해주는 명령줄 클라이언트
yum install -y kubelet-1.27.2-150500.1.1.aarch64 kubeadm-1.27.2-150500.1.1.aarch64 kubectl-1.27.2-150500.1.1.aarch64 --disableexcludes=kubernetes
systemctl enable --now kubelet
8. 클러스터 생성
Kubernetes 클러스터의 Control Plane을 초기화하고, Pod 네트워크를 설정하여 전체 클러스터가 정상 작동할 수 있는 기반을 구성합니다.
클러스터 초기화
- kubeadm init: Kubernetes 마스터 노드를 초기화합니다.
- TLS 인증서 생성
- etcd 초기화
- kube-apiserver, kube-controller-manager, kube-scheduler 배포
- admin.conf 생성
- 클러스터 토큰 발급 (워커 노드 조인용)
- --pod-network-cidr: 클러스터 내 Pod들이 사용할 가상 IP 대역을 지정합니다.
-
- 사용하려는 CNI 플러그인(Calico 등)과 일치해야 합니다.
- 예: Calico는 /16 대역을, Flannel은 보통 /12 대역을 사용합니다.
- --apiserver-advertise-address: 클러스터 외부에서 API 서버에 접근할 수 있는 마스터 노드의 고정 IP 주소를 명시합니다.
kubeadm init --pod-network-cidr=20.96.0.0/16 --apiserver-advertise-address=192.168.56.30
kubectl 설정
kubectl은 /etc/kubernetes/admin.conf 파일을 사용해 클러스터와 통신합니다. 하지만 이 파일은 root 소유이므로, 일반 사용자도 kubectl을 사용할 수 있게 복사 및 권한 변경을 해주는 작업입니다.
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
Pod 네트워크(CNI) 설치 – Calico
Kubernetes는 자체적으로 네트워크 기능이 없기 때문에, Pod 간 통신을 위해 CNI(Container Network Interface) 플러그인이 반드시 필요합니다. 기본 설정(calico.yaml)과 사용자 정의 설정(calico-custom.yaml)을 함께 적용하여 네트워크 안정성과 유연성을 확보합니다. 참고로, Calico가 설치되어야 Pod들이 서로 통신할 수 있고, DNS 및 서비스 기능도 정상 작동합니다.
kubectl create -f calico.yaml
kubectl create -f calico-custom.yaml
마스터 노드 taint 제거
Kubernetes는 기본적으로 마스터 노드에 워크로드(Pod)를 배포하지 않도록 taint를 적용합니다. 실습 환경처럼 노드가 1개뿐인 경우, taint를 제거해 마스터에도 Pod를 배포할 수 있도록 해야 합니다. 참고로, 이 명령은 개발/테스트 환경에서만 사용하는 것이 일반적이며, 실무 운영 환경에서는 마스터 노드에 워크로드를 배포하지 않는 것이 원칙입니다.
kubectl taint nodes k8s-master node-role.kubernetes.io/control-plane-
9. 쿠버네티스 편의 기능 설치
클러스터를 보다 편리하게 운영·관리할 수 있도록 도와주는 기능들을 설치합니다. 자동완성, 웹 UI 대시보드, 리소스 모니터링 도구 등은 실습과 운영에서 생산성과 가시성을 높이는 데 중요합니다.
kubectl 자동완성 기능 설정
bash-completion 설치 후 kubectl 명령어 자동완성을 활성화합니다. 긴 명령어를 빠르게 입력할 수 있고, 리소스 이름도 탭(Tab) 키로 자동 제안되므로 명령 실수를 줄이고 작업 속도 향상에 효과적입니다. alias k=kubectl을 통해 더 짧은 명령어로 kubectl을 사용할 수 있게 합니다.
yum -y install bash-completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
source ~/.bashrc
Dashboard 설치 (웹 UI)
Kubernetes Dashboard는 웹 기반 GUI 도구로, 클러스터 상태, 리소스 배포 현황, 이벤트 등을 시각적으로 확인할 수 있습니다.
CLI(kubectl)에 익숙하지 않은 사용자나, 클러스터 리소스를 한눈에 확인하고자 하는 관리자에게 유용합니다. 이후 서비스 계정 생성, 토큰 인증 설정, 포트 포워딩 등을 통해 웹 UI에 접근할 수 있습니다.
kubectl create -f https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/dashboard-2.7.0/dashboard.yaml
Metrics Server 설치
- Metrics Server는 Pod, Node의 CPU/Memory 사용량을 수집하는 구성요소입니다.
- Horizontal Pod Autoscaler(HPA) 같은 리소스 기반 자동 스케일링 기능을 사용하기 위해 반드시 설치해야 합니다.
- kubectl top pod, kubectl top node 같은 실시간 모니터링 명령도 이 Metrics Server가 있어야 작동합니다.
kubectl create -f https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/metrics-server-0.6.3/metrics-server.yaml
위처럼 1~9 단계를 정상적으로 완료하면 다음 명령어를 통해 현재 클러스터에서 생성된 Pod 목록을 확인할 수 있습니다.
k get pods -A
또, https://192.168.56.30:30000 로 접속했을 때, 대시보드가 보인다면 성공적으로 설치한 것 입니다.

'Infra' 카테고리의 다른 글
| [K8S] 오브젝트 (0) | 2025.05.19 |
|---|---|
| [K8S] 왜 실무에서는 쿠버네티스를 많이 쓸까? (0) | 2025.05.19 |
| [K8S] Linux, Container, Orchestration (0) | 2025.05.06 |
| Docker 이미지: 가상화의 핵심 요소 (0) | 2025.04.28 |
| Docker의 내부 구조와 작동 방식: 클라이언트-서버 모델 (2) | 2025.04.24 |
댓글