### 환경
- Rocky Linux release 8.10
- kubernetes v1.32.3
- enp0s3 : 호스트 전용 어댑터
- enp0s8 : NAT(10.0.3.15)
### 구성
- kubernetes-master(Control Plane) 192.168.56.140
- kubernetes-worker1 192.168.56.141
- kubernetes-worker2 192.168.56.142
yum -y update
yum install -y yum-utils iproute-tc
cat <<EOF >> /etc/hosts
192.168.56.140 kube-master
192.168.56.141 kube-worker1
192.168.56.142 kube-worker2
EOF
systemctl stop firewalld
systemctl disable firewalld
# 스왑 비활성화
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
# 커널 모듈 설정
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay # 컨테이너 이미지 레이어 마운트
br_netfilter # 브릿지 네트워크 iptables 필터링 기능
EOF
modprobe overlay
modprobe br_netfilter
# 커널 파라미터 적용 (브리지 네트워킹 및 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 저장소 및 설치
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y containerd.io
# containerd, CRI 설정
systemctl daemon-reload
systemctl enable --now containerd
containerd config default | tee /etc/containerd/config.toml
# systemd cgroup driver 활성화
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd
# Kubernetes YUM 저장소 추가
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
# SELinux 설정 (permissive 모드로 전환)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# kubelet, kubeadm, kubectl 설치 및 활성화
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
# Control Plane 초기화 (kubeadm init)
# --pod-network-cidr: Pod 네트워크 대역 (Calico 기본값: 20.96.0.0/12)
kubeadm init \
--pod-network-cidr=20.96.0.0/12 \
--apiserver-advertise-address=192.168.56.140
# kubectl 설정
mkdir -p \$HOME/.kube
cp -i /etc/kubernetes/admin.conf \$HOME/.kube/config
chown \$(id -u):\$(id -g) \$HOME/.kube/config
Control Plane 노드, Worker노드 비슷하게 진행되다가 마지막 초기화부분만 ControlPlane 노드에서 진행하고 Worker노드는 클러스터에 참여만 해주면 된다.
각각의 컴포넌트에 대해서 역할을 확인해본다.
Control Plane
ETCD
- 키-값 형식으로 정보를 저장하는 저장소
- 클러스터에 관한 정보를 저장 - 클러스터의 모든 변경이력 노드 추가, 파드 배포, 복제세트등 ETCD에 업데이트
kube-scheduler
- 노드의 상태와 자원, 레이블, 요구 조건등을 고려해 파드를 어떤 워커 노드에 생성할 것인지 결정하고 할당
kube-controller-manager
- 클러스터의 오브젝트 상태를 관리
- 상태 체크와 복구 - 노드 컨트롤러
- 레플리카셋셋에 요청받은 파드 개수대로 파드 생성 - 레플리카셋 컨트롤러
kube-apiserver
- 서버내에서 모든 작업을 오케스트레이션
- kubelet으로 부터 노드의 상태를 확인
- 유일하게 ETCD 데이터 저장소와 직접 상호 작용
worker-node
kubelet
- 클러스터의 각 노드에서 실행되는 에이전트
- kube-apiserver의 지시를 듣고 필요한 노드에서 컨테이너를 배포하거나 삭제(Control Plane에서 유일한 접촉 지점)
- 컨테이너와 kube proxy를 관리, 파드 상태를 계속 모니터링
kubeproxy
- 클러스터의 각 노드에서 실행되는 네트워크 프록시
- 클러스터 내부 서비스를 pod 네트워크 상에서 동작
Container-Runtime
- Pod안의 컨테이너를 실행, 종료, 모니터
CNI
- 컨테이너 간의 네트워킹 제어 할 수 있는 플러그인이 지켜야 하는 표준
- Pod간의 통신을 위해서 사용
※ 처음 구축을 진행후 확인해봤을때 CNI가 제대로 동작하지 않았다.
calico를 배포하였을때 enp0s8을 감지하여 실행 -> nat으로 외부통신용이기 때문에 내부 통신용으로는 enp0s3 호스트 전용 으로 바꿔서 진행
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
vi calico.yaml
...
...
kind: DaemonSet
apiVersion: apps/v1
...
spec:
...
template:
...
env:
- name: FELIX_WIREGUARDMTU
- name: IP_AUTODETECTION_METHOD
value: "interface=enp0s3"
kubectl apply -f calico-kans.yaml
위 옵션 적용으로 배포 완료
※ 참고
- https://kubernetes.io/docs/setup/production-environment/container-runtimes/
- 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커 책
- Certified Kubernetes Administrator(CKA) with Practice Tests - Udemy 강의