RKE2는 Rancher가 만든 엔터프라이즈급 Kubernetes 배포판으로, 보안 강화와 FIPS 컴플라이언스에 초점을 맞추고 있다. 이번 실습에서는 Vagrant + VirtualBox 기반으로 Rocky Linux 9 VM을 구성하고, RKE2 서버 노드를 설치·운영하는 전 과정을 다룬다.

| 항목 | 값 |
|---|---|
| Base Image | bento/rockylinux-9 (202510.26.0) |
| Node 수 | 2 (k8s-node1, k8s-node2) |
| vCPU | 4 |
| Memory | 4096 MB |
| Network (Private) | 192.168.10.11 ~ 192.168.10.12 |
| SSH Port (Host) | 60001, 60002 |
BOX_IMAGE = "bento/rockylinux-9"
BOX_VERSION = "202510.26.0"
N = 2
Vagrant.configure("2") do |config|
(1..N).each do |i|
config.vm.define "k8s-node#{i}" do |subconfig|
subconfig.vm.box = BOX_IMAGE
subconfig.vm.box_version = BOX_VERSION
subconfig.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--groups", "/RKE2-Lab"]
vb.name = "k8s-node#{i}"
vb.cpus = 4
vb.memory = 4096
vb.linked_clone = true
end
subconfig.vm.host_name = "k8s-node#{i}"
subconfig.vm.network "private_network", ip: "192.168.10.1#{i}"
subconfig.vm.network "forwarded_port", guest: 22, host: "6000#{i}", auto_correct: true, id: "ssh"
subconfig.vm.synced_folder "./", "/vagrant", disabled: true
subconfig.vm.provision "shell", path: "init_cfg.sh", args: [ N ]
end
end
end
init_cfg.sh는 VM 초기 세팅을 자동화하는 셸 스크립트다. 핵심 작업은 다음과 같다.
Asia/Seoul 설정 + NTP 활성화firewalld 비활성화, SELinux → permissive/etc/fstab 항목 제거)overlay, br_netfilter) + sysctl 설정/etc/hosts 에 노드 IP 등록v3.20.0 설치conntrack, python3-pip, git 설치⚠️ 주의 : NetworkManager가 Calico/Flannel 가상 인터페이스를 관리하면 CNI 오작동이 발생한다. 반드시 아래 설정으로 제외시켜야 한다.
# /etc/NetworkManager/conf.d/k8s.conf
[keyfile]
unmanaged-devices=interface-name:flannel*;interface-name:cali*;interface-name:tunl*;...
RKE2는 systemd 서비스 기반 설치를 공식 지원한다. RPM 기반 OS(Rocky Linux)는 자동으로 yum/rpm 설치 방식을 선택한다.
curl -sfL https://get.rke2.io --output install.sh
chmod +x install.sh
INSTALL_RKE2_CHANNEL=v1.33 ./install.sh
설치 완료 후 버전 확인:
rke2 --version
# rke2 version v1.33.7+rke2r3
주요 환경변수 옵션:
| 변수 | 설명 | 기본값 |
|---|---|---|
INSTALL_RKE2_VERSION | 설치할 RKE2 버전 | stable 채널 최신 |
INSTALL_RKE2_TYPE | 서비스 타입 | server |
INSTALL_RKE2_CHANNEL | 채널 | stable |
INSTALL_RKE2_METHOD | 설치 방법 | rpm (RPM OS) / tar |
💡 설치 시
/etc/yum.repos.d/rancher-rke2.repo가 자동 추가된다.common과 버전별 repo 두 개가 등록된다.
[rancher-rke2-common-stable]
baseurl=https://rpm.rancher.io/rke2/stable/common/centos/9/noarch
[rancher-rke2-1.33-stable]
baseurl=https://rpm.rancher.io/rke2/stable/1.33/centos/9/aarch64
# /etc/rancher/rke2/config.yaml
write-kubeconfig-mode: "0644"
debug: true
cni: canal
bind-address: 192.168.10.11
advertise-address: 192.168.10.11
node-ip: 192.168.10.11
disable-cloud-controller: true
disable:
- servicelb
- rke2-coredns-autoscaler
- rke2-ingress-nginx
- rke2-snapshot-controller
- rke2-snapshot-controller-crd
- rke2-snapshot-validation-webhook
CNI로 canal (Calico 정책 + Flannel 네트워크) 을 사용하고, 실습 환경에 불필요한 컴포넌트는 비활성화했다.
Canal CNI가 올바른 네트워크 인터페이스를 사용하도록 flannel iface 를 지정한다.
# /var/lib/rancher/rke2/server/manifests/rke2-canal-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-canal
namespace: kube-system
spec:
valuesContent: |-
flannel:
iface: "enp0s9"
CoreDNS autoscaler는 실습 환경에서 불필요하므로 비활성화한다.
# /var/lib/rancher/rke2/server/manifests/rke2-coredns-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-coredns
namespace: kube-system
spec:
valuesContent: |-
autoscaler:
enabled: false
# 모니터링 (별도 터미널)
journalctl -u rke2-server -f
# 서비스 시작 (약 2~4분 소요)
systemctl enable --now rke2-server.service
# kubeconfig 복사
mkdir ~/.kube
cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
# 심볼릭 링크로 바이너리 노출
ln -s /var/lib/rancher/rke2/bin/kubectl /usr/local/bin/kubectl
ln -s /var/lib/rancher/rke2/bin/crictl /usr/local/bin/crictl
ln -s /var/lib/rancher/rke2/agent/etc/crictl.yaml /etc/crictl.yaml
# 자동완성 + alias
source <(kubectl completion bash)
alias k=kubectl
complete -F __start_kubectl k
kubectl get node -owide
# NAME STATUS ROLES VERSION CONTAINER-RUNTIME
# k8s-node1 Ready control-plane,etcd v1.34.3+rke2r3 containerd://2.1.5-k3s1
kubectl get pod -A
# kube-system etcd-k8s-node1 1/1 Running 0
# kube-system kube-apiserver-k8s-node1 1/1 Running 0
# kube-system kube-controller-manager-k8s-node1 1/1 Running 0
# kube-system kube-proxy-k8s-node1 1/1 Running 0
# kube-system kube-scheduler-k8s-node1 1/1 Running 0
# kube-system rke2-canal-dkw2n 2/2 Running 0
# kube-system rke2-coredns-... 1/1 Running 0
# kube-system rke2-metrics-server-... 1/1 Running 0
helm list -A
# rke2-canal kube-system deployed
# rke2-coredns kube-system deployed
# rke2-metrics-server kube-system deployed
# rke2-runtimeclasses kube-system deployed
/var/lib/rancher/rke2 전체 구조/var/lib/rancher/rke2/
├── bin -> data/v1.34.3-rke2r3-.../bin # 핵심 바이너리 (symlink)
├── data/
│ └── v1.34.3-rke2r3-.../
│ ├── bin/ # containerd, kubectl, kubelet, runc 등
│ └── charts/ # 내장 Helm chart (rke2-coredns.yaml 등)
├── server/
│ ├── cred/ # kubeconfig 정보
│ ├── db/ # etcd snapshot / WAL
│ ├── manifests/ # Helm controller가 관리하는 manifest
│ ├── tls/ # CA 인증서, API Server 인증서
│ └── token # 노드 등록 토큰
└── agent/
├── containerd/ # containerd root 디렉터리
├── etc/
│ ├── containerd/config.toml
│ ├── crictl.yaml
│ └── kubelet.conf.d/00-rke2-defaults.conf
├── images/ # 컴포넌트 이미지 이름 텍스트 파일
├── logs/ # kubelet.log
└── pod-manifests/ # Static Pod YAML (etcd, apiserver 등)
/var/lib/rancher/rke2/bin/)containerd
containerd-shim-runc-v2
crictl
ctr
kubectl
kubelet
runc
❌ 절대 주의 :
config.toml은 RKE2가 자동 생성하므로 직접 수정 금지. 수정이 필요하면 반드시config.toml.tmpl을 사용한다. rke2/k3s 재시작 시 덮어써진다.
cat /var/lib/rancher/rke2/agent/etc/containerd/config.toml
# File generated by rke2. DO NOT EDIT. Use config.toml.tmpl instead.
💡 RKE2는 containerd 소켓을
/run/k3s/containerd/containerd.sock에 노출한다. k3s 경로를 그대로 사용한다는 점이 특징이다.
runtime-endpoint: unix:///run/k3s/containerd/containerd.sock
00-rke2-defaults.conf)| 설정 | 값 | 의미 |
|---|---|---|
cgroupDriver | systemd | systemd cgroup 사용 |
failSwapOn | false | Swap 있어도 기동 허용 (일반 k8s와 다름) |
serializeImagePulls | false | 이미지 병렬 pull |
nodeStatusUpdateFrequency | 10s | 10초마다 헬스 보고 |
staticPodPath | /var/lib/rancher/rke2/agent/pod-manifests | Static Pod 경로 |
RKE2는 내장 Helm Controller로 CNI, CoreDNS 등의 시스템 컴포넌트를 Helm Chart로 관리한다.
# CRD 확인
kubectl get crd | grep -E 'helm|addon'
# helmcharts.helm.cattle.io
# helmchartconfigs.helm.cattle.io
# addons.k3s.cattle.io
# HelmChart 리소스 확인
kubectl get helmcharts -n kube-system
# 설치 Job 확인
kubectl get job -n kube-system
# helm-install-rke2-canal Complete
# helm-install-rke2-coredns Complete
📌 동작 순서 :
HelmChart리소스 생성 → Helm Controller 감지 →Job생성 →helm install실행 → Completed
# Kubernetes CA 인증서
cat /var/lib/rancher/rke2/server/tls/server-ca.crt | openssl x509 -text -noout
# API Server 인증서 (SAN 포함)
cat /var/lib/rancher/rke2/server/tls/serving-kube-apiserver.crt | openssl x509 -text -noout
# Issuer: CN=rke2-server-ca@...
# Subject: CN=kube-apiserver
# SAN: DNS:kubernetes, IP:192.168.10.11, IP:10.43.0.1 ...
# 유효기간: 1년
💡 API Server 인증서의 SAN(Subject Alternative Name) 에
DNS:kubernetes, 노드 IP, ClusterIP(10.43.0.1) 등이 포함된다. 유효기간은 1년이므로 갱신 주기 관리가 필요하다.
RKE2는 hardened 이미지를 사용한다. 각 컴포넌트의 이미지명은 텍스트 파일로 관리된다.
| 파일 | 이미지 |
|---|---|
etcd-image.txt | rancher/hardened-etcd:v3.6.7-k3s1-... |
kube-apiserver-image.txt | rancher/hardened-kubernetes:v1.34.3-rke2r3-... |
runtime-image.txt | rancher/rke2-runtime:v1.34.3-rke2r3 |
💡 hardened 이미지는 CIS 벤치마크 기준으로 보안 강화된 이미지다. 일반 upstream 이미지와 다르다.
Agent 노드 등록 시 사용하는 토큰은 아래 경로에 있다.
cat /var/lib/rancher/rke2/server/token
# K1087d08f6b3f21e75c6835e1b959d634d...::server:466038852cf7cdcd389872ba4ab64c04
⚠️ 이 토큰은 클러스터 접근 권한과 직결된다. 외부 노출 금지.