Rancher Labs(현재 SUSE)에서 만든 보안 강화형 Kubernetes 배포판

출처 : https://docs.rke2.io/architecture
| 구분 | RKE2 | K3s | kubeadm |
|---|---|---|---|
| 목적 | Enterprise | Lightweight | Vanilla Kubernetes |
| 보안 | 매우 강함 | 기본 | 직접 설정 |
| 설치 난이도 | 쉬움 | 매우 쉬움 | 어려움 |
| Production | 매우 적합 | Edge/IoT | 가능 |
| 기본 구성 | 많음 | 최소화 | 없음 |
# Base Image https://portal.cloud.hashicorp.com/vagrant/discover/bento/rockylinux-9
BOX_IMAGE = "bento/rockylinux-9" # "bento/rockylinux-10.0"
BOX_VERSION = "202510.26.0"
N = 2 # max number of Node
Vagrant.configure("2") do |config|
# Nodes
(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.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
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#!/usr/bin/env bash
echo ">>>> Initial Config Start <<<<"
echo "[TASK 1] Change Timezone and Enable NTP"
timedatectl set-local-rtc 0
timedatectl set-timezone Asia/Seoul
echo "[TASK 2] Disable firewalld and selinux"
systemctl disable --now firewalld >/dev/null 2>&1
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
echo "[TASK 3] Disable and turn off SWAP & Delete swap partitions"
swapoff -a
sed -i '/swap/d' /etc/fstab
sfdisk --delete /dev/sda 2 >/dev/null 2>&1
partprobe /dev/sda >/dev/null 2>&1
echo "[TASK 4] Config kernel & module"
cat << EOF > /etc/modules-load.d/k8s.conf
overlay
br_netfilter
#vxlan
EOF
modprobe overlay >/dev/null 2>&1
modprobe br_netfilter >/dev/null 2>&1
#modprobe vxlan >/dev/null 2>&1
cat << EOF >/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 >/dev/null 2>&1
echo "[TASK 5] Setting Local DNS Using Hosts file"
sed -i '/^127\.0\.\(1\|2\)\.1/d' /etc/hosts
for (( i=1; i<=$1; i++ )); do echo "192.168.10.1$i k8s-node$i" >> /etc/hosts; done
echo "[TASK 6] Install Helm"
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | DESIRED_VERSION=v3.20.0 bash >/dev/null 2>&1
echo "[TASK 7] Setting SSHD"
cat << EOF >> /etc/ssh/sshd_config
PermitRootLogin yes
PasswordAuthentication yes
EOF
systemctl restart sshd >/dev/null 2>&1
echo "[TASK 8] Install packages"
dnf install -y conntrack python3-pip git >/dev/null 2>&1
echo "[TASK 9] NetworkManager to ignore calico/flannel related network interfaces"
# https://docs.rke2.io/known_issues#networkmanager
cat << EOF > /etc/NetworkManager/conf.d/k8s.conf
[keyfile]
unmanaged-devices=interface-name:flannel*;interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
EOF
systemctl reload NetworkManager
echo "[TASK 11] Install K9s"
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
wget -P /tmp https://github.com/derailed/k9s/releases/latest/download/k9s_linux_${CLI_ARCH}.tar.gz >/dev/null 2>&1
tar -xzf /tmp/k9s_linux_${CLI_ARCH}.tar.gz -C /tmp
chown root:root /tmp/k9s
mv /tmp/k9s /usr/local/bin/
chmod +x /usr/local/bin/k9s
echo "[TASK 12] ETC"
echo "sudo su -" >> /home/vagrant/.bashrc
echo ">>>> Initial Config End <<<<"
mkdir k8s-rke2
cd k8s-rke2
curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/k8s-rke2/Vagrantfile
curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/k8s-rke2/init_cfg.sh
vagrant up
vagrant status
curl -sfL https://get.rke2.io --output install.sh
chmod +x install.sh
INSTALL_RKE2_CHANNEL=v1.33 ./install.sh
| 변수 | 설명 |
|---|---|
| INSTALL_RKE2_VERSION | 특정 버전 지정 |
| INSTALL_RKE2_TYPE | server / agent |
| INSTALL_RKE2_CHANNEL | stable / latest / v1.xx |
| INSTALL_RKE2_METHOD | rpm / tar |
rke2 --version
dnf repolist
/etc/rancher/rke2/config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-canal
namespace: kube-system
spec:
valuesContent: |-
flannel:
iface: "enp0s9"
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-coredns
namespace: kube-system
spec:
valuesContent: |-
autoscaler:
enabled: false
systemctl enable --now rke2-server
journalctl -u rke2-server -f
mkdir ~/.kube
cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
agent
server
data
bin -> versioned bin
| 경로 | 설명 |
|---|---|
| cred | kubeconfig |
| db | etcd 데이터 |
| manifests | helm addon |
| tls | 인증서 |
| token | node join token |
| 경로 | 설명 |
|---|---|
| containerd | runtime 데이터 |
| etc/containerd | config.toml |
| pod-manifests | static pod |
| logs | kubelet 로그 |
경로:
/var/lib/rancher/rke2/agent/pod-manifests
포함:
rke2 certificate check --output table
systemctl stop rke2-server
rke2 certificate rotate
systemctl start rke2-server
cat /var/lib/rancher/rke2/server/node-token
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE=agent sh -
server: https://192.168.10.11:9345
token: <NODE_TOKEN>
systemctl enable --now rke2-agent
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
kubectl delete node <node>
systemctl stop rke2-agent
rke2-uninstall.sh
Deployment + NodePort Service
image: traefik/whoami
확인:
kubectl get deploy,pod,svc
curl -sfL https://get.rke2.io | INSTALL_RKE2_CHANNEL=v1.34 sh -
systemctl restart rke2-server
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE=agent INSTALL_RKE2_CHANNEL=v1.34 sh -
systemctl restart rke2-agent
kubectl get node -owide
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/crd.yaml -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/system-upgrade-controller.yaml
kind: Plan
spec:
concurrency: 1
cordon: true
nodeSelector:
control-plane
upgrade:
image: rancher/rke2-upgrade
channel: stable
prepare:
- server-plan
kubectl -n system-upgrade get plans
kubectl -n system-upgrade get jobs
Cluster API (CAPI) 는 Kubernetes 스타일의 선언적 API(CRD) 를 사용해 여러 Kubernetes 클러스터의 생성 · 확장 · 업그레이드 · 삭제 를 자동화하는 프로젝트
클러스터 전체 정의
Cluster
├─ infrastructureRef
└─ controlPlaneRef
Machine = Kubernetes Node를 호스팅하는 인프라
Machine
├─ infrastructureRef
└─ bootstrap.configRef
graph TD
MD[MachineDeployment]
MS[MachineSet]
M[Machine]
Infra[Infrastructure Resource]
VM[Actual VM]
MD --> MS
MS --> M
M --> Infra
Infra --> VM
Cluster API = 인터페이스 + 구현체
CNI 구조와 동일 개념.
| 구분 | CNI | Cluster API |
|---|---|---|
| 표준 인터페이스 | CNI | Cluster API Core |
| 구현체 | Calico, Flannel | Infrastructure Provider |
실제 인프라 생성 담당
예:
역할:
Control Plane 구성 방식 정의
Machine → Node 변환 담당
역할:
대표:
기본 원칙:
Machine은 immutable (불변)
여러 버전 업그레이드 자동 수행
예:
v1.33 → v1.34 → v1.35
사용자는:
v1.35 지정만 하면 됨
리소스 간 부모-자식 관계 정의.
Deployment 삭제
→ ReplicaSet 삭제
→ Pod 삭제
Cluster API도 동일 방식 사용.
➡️ Cluster 삭제 시 하위 인프라 자동 정리
kind Kubernetes = Management Cluster
Docker daemon = Workload Cluster 인프라
Management Cluster (kind)
├─ Core Provider (CAPI)
├─ Bootstrap Provider (kubeadm)
├─ ControlPlane Provider (kubeadm)
└─ Infrastructure Provider (CAPD)
↓ reconcile
Workload Cluster (Docker Containers)
├─ Control Plane Nodes
├─ Worker Nodes
└─ HAProxy LoadBalancer
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: capi-test
nodes:
- role: control-plane
extraMounts:
- hostPath: /var/run/docker.sock
containerPath: /var/run/docker.sock
kind create cluster --config kind.yaml
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/latest/download/clusterctl-linux-amd64 -o clusterctl
chmod +x clusterctl
sudo mv clusterctl /usr/local/bin/
확인:
clusterctl version
clusterctl init --infrastructure docker
설치되는 Provider:
| 타입 | Provider |
|---|---|
| Core | cluster-api |
| Bootstrap | kubeadm |
| Control Plane | kubeadm |
| Infrastructure | docker (CAPD) |
kubectl get pods -A
kubectl get pods -n cert-manager
kubectl get certificates -A
역할:
Webhook TLS 인증서 자동 관리
clusterctl generate cluster capi-quickstart --flavor development > cluster.yaml
kubectl apply -f cluster.yaml
kubectl get cluster
kubectl get machines
kubectl get kubeadmcontrolplanes
kubectl get machinedeployments
ClusterClass = 설계도.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: capi-quickstart
spec:
topology:
class: quick-start
version: v1.29.0
controlPlane:
replicas: 3
workers:
machineDeployments:
- class: default-worker
name: md-0
replicas: 3
Cluster
→ KubeadmControlPlane
→ MachineDeployment
→ Machine
→ DockerMachine
→ Docker Container(Node)
Workload cluster 접근:
clusterctl get kubeconfig capi-quickstart > workload.kubeconfig
테스트:
kubectl --kubeconfig workload.kubeconfig get nodes
초기 상태:
Node = NotReady (정상)
kubectl --kubeconfig workload.kubeconfig apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml
확인:
kubectl --kubeconfig workload.kubeconfig get nodes
kubectl get cluster
kubectl get machines
kubectl get dockerclusters
kubectl get dockermachines
MachineDeployment
↓
MachineSet
↓
Machine
↓
DockerMachine
↓
Docker Container
ConfigMap 확인:
kubectl --kubeconfig workload.kubeconfig -n kube-system get cm kubeadm-config -o yaml
확인 포인트:
Management Cluster:
kubectl get secrets | grep capi-quickstart
Bootstrap 흐름:
cloud-init → kubeadm init/join → Node 등록
실제 노드는 Docker 컨테이너:
docker ps | grep capi-quickstart
Management Cluster (kind)
↓
Cluster API Controllers
↓
Workload Cluster (Docker)
- Control Plane
- Worker
- HAProxy