Study/CS

[Cilium Study] 1주차 - 1. 실습 환경 구성

마늘김 2025. 7. 19. 00:03

 '가시다'님의 [Cilium Study] 1기의 내용을 정리하는 시리즈 구성의 포스팅을 시작하려고 합니다. 이번 스터디를 통해 Kubernetes의 Network에 대해 깊이 이해할 수 있기를 희망합니다. 본 포스팅은 [Cilium Study 1기]의 1주 차 내용으로 실습 환경을 구성하는 방법부터 소개합니다.

VirtualBox와 Vagrant를 활용한 가상 머신 구성

 이번 [Cilium Study]를 시작하면서 평소 막연하게 생각해왔던 VirtualBox와 Vagrant를 체험해 볼 수 있게 되었습니다. 원래 VMware의 제품군에 많이 익숙해서 VMware Workstation Pro나 VMware vSphere를 자주 사용했었고, 소규모 환경은 주로 Manual 하게 구성하는 경우가 많아서 Vagrant를 사용해 볼 기회가 많이 없었습니다.

 조훈님의 강의인 '그림으로 배우는 Kubernetes'를 들을 때도, Kubernetes 클러스터를 직접 구축해보고 싶어 가상머신으로 매뉴얼 하게 설치하는 방법을 주로 사용하다 보니, 더욱 Vagrant와는 친해지지 못했던 것 같습니다. 이번 스터디를 기회로 Vagrant와도 친해져야겠습니다.

Apple silicon 환경에서 VirtualBox와 Vagrant 설치

# VirtualBox 설치
brew install --cask virtualbox

VBoxManage --version
7.1.10r169112				# 포스팅 시점 2025년 7월 기준

# Vagrant 설치
brew install --cask vagrant

vagrant version    	
Installed Version: 2.4.7	# 포스팅 시점 2025년 7월 기준

 MacOS의 터미널에서 brew 명령어를 통해 손쉽게 VirtualBox와 Vagrant를 설치할 수 있습니다.

실습 환경 네트워크 토폴로지

VirtualBox의 네트워크 구조에 대한 이해

실습환경 네트워크 다이어그램

 위 그림은 제가 이해한 VirtualBox의 네트워크 구조로(다소 잘못된 부분이 있을 수 있음) VMware Workstation Pro에서 제공하는 방식과 확연한 차이가 있습니다. VirtualBox의 경우 VM별로 별도의 격리된 NAT용 네트워크 공간(다이어그램의 붉은색 선)을 제공합니다. 그래서 모든 VM들의 eth0 인터페이스의 IP 주소가 같아도 문제가 없습니다. 그런데 이런 구조를 가지다 보니 VM 간 통신을 위해서는 따로 Private Network를 만들어 주어야 합니다. 바로 위 다이어그램의 파란색 선입니다.

 vagrant up 명령어를 통해 가상머신이 생성되면 Host(Mac)에는 bridege100이라는 인터페이스가 생기면서 VM들의 Private Network 공간인 192.168.10.0/24로 향하는 라우팅 테이블이 업데이트 됩니다. 게다가, ssh를 통한 접근이나 ping 테스트 같은 것이 모두 이 Private Network로 가능하게 됩니다. 즉 Private Network가 구성되어야 L2 주소 공간이 형성되고 이를 통해 Host - VM 간, 또는 VM -VM 간의 통신이 가능하게 되는 것입니다. 단, VirtualBox는 VM에 대한 ssh 경로의 경우 Host에서 localhost의 특정 포트를 호출하여 VM에 접근할 수 있는 우회 경로를 제공합니다.

VMware Workstaion Pro의 NAT 네트워크에 대한 이해

VMware Workstation Pro의 NAT 네트워크 토폴로지

 VMware의 경우에는 NAT 네트워크가 생성되면 Host와는 별개의 네트워크 공간이 생성됩니다. 별도의 NAT 네트워크 전용 인터페이스가 Host에 등록되며(예 - 192.168.10.1의 IP 주소를 가진 인터페이스) VM들에게는 같은 주소 공간의 특정 IP(예 - 192.168.10.2)를 Gateway로 지정하여 사용하도록 합니다. 그리고 보이지 않는 L2 스위치가 생성되어 여기에 192.168.10.0/24의 IP 주소 범위 내에서 IP를 할당하게 합니다. 이렇게 되면 NAT Interface와 VM Gateway는 마치 L3 라우터 간 세그먼트와 같은 모습이 되게 됩니다. VM들은 별도의 네트워크 인터페이스 추가 없이 192.168.10.0/24의 IP 주소 범위 내에서 통신을 할 수 있게 되고, 외부와의 통신은 192.168.10.2를 통해 하게 됩니다.

 개인적으로는 VMware Workstation Pro의 네트워크 토폴로지가 더욱 직관적이라고 느껴집니다. 별도의 네트워크 공간의 분리가 명확하고, Gateway 구조를 이해하기에도 쉽습니다. (다만 제가 처음부터 VMware 제품에 익숙하서 그런지도 모르겠다는 생각은 있습니다.)

Vagrantfile과 Kubernetes 클러스터 구성을 위한 Shell scripts

Vagrantfile

 이 부분이 애써 외면하고 있던 IaC의 한 부분인 Vagrantfile입니다. 수동으로 해오던 가상머신 생성 과정을 자동화 시켜주는 아주 기본적이면서도 중요한 부분이죠. 확실히 이런 부분은 제가 배워야 하고 극복해 나가야 할 부분입니다.

# Variables
K8SV = '1.33.2-1.1' # Kubernetes Version : apt list -a kubelet , ex) 1.32.5-1.1
CONTAINERDV = '1.7.27-1' # Containerd Version : apt list -a containerd.io , ex) 1.6.33-1
N = 2 # max number of worker nodes

# Base Image  https://portal.cloud.hashicorp.com/vagrant/discover/bento/ubuntu-24.04
## Rocky linux Image https://portal.cloud.hashicorp.com/vagrant/discover/rockylinux
BOX_IMAGE = "bento/ubuntu-24.04"
BOX_VERSION = "202502.21.0"

Vagrant.configure("2") do |config|
#-ControlPlane Node
    config.vm.define "k8s-ctr" do |subconfig|
      subconfig.vm.box = BOX_IMAGE
      subconfig.vm.box_version = BOX_VERSION
      subconfig.vm.provider "virtualbox" do |vb|
        vb.customize ["modifyvm", :id, "--groups", "/Cilium-Lab"]
        vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
        vb.name = "k8s-ctr"
        vb.cpus = 2
        vb.memory = 2048
        vb.linked_clone = true
      end
      subconfig.vm.host_name = "k8s-ctr"
      subconfig.vm.network "private_network", ip: "192.168.10.100"
      subconfig.vm.network "forwarded_port", guest: 22, host: 60000, auto_correct: true, id: "ssh"
      subconfig.vm.synced_folder "./", "/vagrant", disabled: true
      subconfig.vm.provision "shell", path: "init_cfg.sh", args: [ K8SV, CONTAINERDV]
      subconfig.vm.provision "shell", path: "k8s-ctr.sh", args: [ N ]
    end

#-Worker Nodes Subnet1
  (1..N).each do |i|
    config.vm.define "k8s-w#{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", "/Cilium-Lab"]
        vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
        vb.name = "k8s-w#{i}"
        vb.cpus = 2
        vb.memory = 1536
        vb.linked_clone = true
      end
      subconfig.vm.host_name = "k8s-w#{i}"
      subconfig.vm.network "private_network", ip: "192.168.10.10#{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: [ K8SV, CONTAINERDV]
      subconfig.vm.provision "shell", path: "k8s-w.sh"
    end
  end
end

Shell script

 Shell script의 경우에도 변수화가 잘 되어 있어서 향후 사용성이 상당히 뛰어나 배울점이 많았습니다.

# init_cfg.sh
# Kubernetes 구성 전 필요한 작업 및 패키지 설치를 위한 Shell script

#!/usr/bin/env bash

echo ">>>> Initial Config Start <<<<"

echo "[TASK 1] Setting Profile & Change Timezone"
echo 'alias vi=vim' >> /etc/profile
echo "sudo su -" >> /home/vagrant/.bashrc
ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime


echo "[TASK 2] Disable AppArmor"
systemctl stop ufw && systemctl disable ufw >/dev/null 2>&1
systemctl stop apparmor && systemctl disable apparmor >/dev/null 2>&1


echo "[TASK 3] Disable and turn off SWAP"
swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab


echo "[TASK 4] Install Packages"
apt update -qq >/dev/null 2>&1
apt-get install apt-transport-https ca-certificates curl gpg -y -qq >/dev/null 2>&1

# Download the public signing key for the Kubernetes package repositories.
mkdir -p -m 755 /etc/apt/keyrings
K8SMMV=$(echo $1 | sed -En 's/^([0-9]+\.[0-9]+)\..*/\1/p')
curl -fsSL https://pkgs.k8s.io/core:/stable:/v$K8SMMV/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$K8SMMV/deb/ /" >> /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# packets traversing the bridge are processed by iptables for filtering
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/k8s.conf

# enable br_netfilter for iptables 
modprobe br_netfilter
modprobe overlay
echo "br_netfilter" >> /etc/modules-load.d/k8s.conf
echo "overlay" >> /etc/modules-load.d/k8s.conf


echo "[TASK 5] Install Kubernetes components (kubeadm, kubelet and kubectl)"
# Update the apt package index, install kubelet, kubeadm and kubectl, and pin their version
apt update >/dev/null 2>&1

# apt list -a kubelet ; apt list -a containerd.io
apt-get install -y kubelet=$1 kubectl=$1 kubeadm=$1 containerd.io=$2 >/dev/null 2>&1
apt-mark hold kubelet kubeadm kubectl >/dev/null 2>&1

# containerd configure to default and cgroup managed by systemd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# avoid WARN&ERRO(default endpoints) when crictl run  
cat <<EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
EOF

# ready to install for k8s 
systemctl restart containerd && systemctl enable containerd
systemctl enable --now kubelet


echo "[TASK 6] Install Packages & Helm"
apt-get install -y bridge-utils sshpass net-tools conntrack ngrep tcpdump ipset arping wireguard jq tree bash-completion unzip kubecolor >/dev/null 2>&1
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash >/dev/null 2>&1


echo ">>>> Initial Config End <<<<"
# k8s-ctr.sh
# Kubernetes Clsuter Control Plane 구성을 위한 Shell script

#!/usr/bin/env bash

echo ">>>> K8S Controlplane config Start <<<<"

echo "[TASK 1] Initial Kubernetes"
kubeadm init --token 123456.1234567890123456 --token-ttl 0 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16 --apiserver-advertise-address=192.168.10.100 --cri-socket=unix:///run/containerd/containerd.sock >/dev/null 2>&1


echo "[TASK 2] Setting kube config file"
mkdir -p /root/.kube
cp -i /etc/kubernetes/admin.conf /root/.kube/config
chown $(id -u):$(id -g) /root/.kube/config


echo "[TASK 3] Source the completion"
echo 'source <(kubectl completion bash)' >> /etc/profile
echo 'source <(kubeadm completion bash)' >> /etc/profile


echo "[TASK 4] Alias kubectl to k"
echo 'alias k=kubectl' >> /etc/profile
echo 'alias kc=kubecolor' >> /etc/profile
echo 'complete -F __start_kubectl k' >> /etc/profile


echo "[TASK 5] Install Kubectx & Kubens"
git clone https://github.com/ahmetb/kubectx /opt/kubectx >/dev/null 2>&1
ln -s /opt/kubectx/kubens /usr/local/bin/kubens
ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx


echo "[TASK 6] Install Kubeps & Setting PS1"
git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1 >/dev/null 2>&1
cat <<"EOT" >> /root/.bash_profile
source /root/kube-ps1/kube-ps1.sh
KUBE_PS1_SYMBOL_ENABLE=true
function get_cluster_short() {
  echo "$1" | cut -d . -f1
}
KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
KUBE_PS1_SUFFIX=') '
PS1='$(kube_ps1)'$PS1
EOT
kubectl config rename-context "kubernetes-admin@kubernetes" "HomeLab" >/dev/null 2>&1


echo "[TASK 6] Install Kubeps & Setting PS1"
echo "192.168.10.100 k8s-ctr" >> /etc/hosts
for (( i=1; i<=$1; i++  )); do echo "192.168.10.10$i k8s-w$i" >> /etc/hosts; done


echo ">>>> K8S Controlplane Config End <<<<"
# k8s-w.sh
# Kubernetes Cluster의 워커 노드 Join을 위한 Shell script

#!/usr/bin/env bash

echo ">>>> K8S Node config Start <<<<"

echo "[TASK 1] K8S Controlplane Join" 
kubeadm join --token 123456.1234567890123456 --discovery-token-unsafe-skip-ca-verification 192.168.10.100:6443  >/dev/null 2>&1


echo ">>>> K8S Node config End <<<<"

 특히, kubeadm init 시에 Token 값을 미리 지정하여 워커 노드의 Join까지 자동화 한 점은 제가 놓치고 있었던 부분이었습니다. 게다가 토큰 만료시간에 대한 옵션인 --token-ttl 0을 통해 만료시간을 설정하지 않아 언제든지 같은 토큰 값으로 워커 노드들이 Join 할 수 있게 한 것도 실습 환경에서는 중요한 요소인 것 같습니다.

Vagrant Up

mkdir cilium-lab && cd cilium-lab

curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/1w/Vagrantfile

vagrant up

 위에서 소개된 Vagrantfile과 각종 Shell script를 한번에 다운로드할 수 있는 명령어와 가상머신을 자동으로 프로비저닝 할 수 있는 명령어입니다. vagrant up 명령어를 통해 VirtualBox에 가상머신을 생성하고 자동으로 Kubernetes 클러스터를 구성하게 됩니다.

Kubernetes 클러스터 구성 후 작업

가상머신 기본 정보 확인

# ssh 접속 전, 노드들의 eth0 IP 확인
for i in ctr w1 w2 ; do echo ">> node : k8s-$i <<"; vagrant ssh k8s-$i -c 'ip -c -4 addr show dev eth0'; echo; done #
>> node : k8s-ctr <<
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    altname enp0s8
    inet 10.0.2.15/24 metric 100 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 79621sec preferred_lft 79621sec

>> node : k8s-w1 <<
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    altname enp0s8
    inet 10.0.2.15/24 metric 100 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 79707sec preferred_lft 79707sec

>> node : k8s-w2 <<
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    altname enp0s8
    inet 10.0.2.15/24 metric 100 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 79764sec preferred_lft 79764sec

 앞서 VirtualBox의 네트워크 구조에 대해서 논의하면서 살펴본 내용을 직접 확인할 수 있었습니다. 모든 VM들의 eth0 인터페이스의 IP 주소가 10.0.2.15로 동일하며, 이는 VirtualBox의 NAT 네트워크 구조의 특징에 기인합니다. 각각 독립된 NAT 네트워크 공간을 가지기 때문입니다.

# k8s-ctrl에 접속 후 기본 정보 확인
vagrant ssh k8s-ctr			# vagrant ssh 명령어를 통해 'ks8-ctr'이라는 이름을 가진 가상머신에 ssh로 접속

# 기본 호스트 정보 및 프로세스 확인
whoami
pwd
hostnamectl
htop

# 호스트 파일 내용 확인과 각 워커 노드 호스트 이름 확인
cat /etc/hosts
ping -c 1 k8s-w1
ping -c 1 k8s-w2
sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w1 hostname
sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@k8s-w2 hostname


# vagrant ssh 로 접속 시 tcp 연결 정보 : NAT Mode 10.0.2.2(GateWay)
ss -tnp |grep sshd
ESTAB 0      0           [::ffff:10.0.2.15]:22          [::ffff:10.0.2.2]:52791 users:(("sshd",pid=5176,fd=4),("sshd",pid=5129,fd=4))

# nic 정보
ip -c addr

# default 라우팅 정보 
ip -c route

# dns 서버 정보 : NAT Mode 10.0.2.3
resolvectl
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.0.2.3
       DNS Servers: 10.0.2.3
        DNS Domain: basphere.local

Link 3 (eth1)
    Current Scopes: none
         Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Kubernetes 클러스터 정보 확인 및 수정

# Kubernetes 클러스터 상태 정보 확인
kubectl cluster-info
Kubernetes control plane is running at https://192.168.10.100:6443
CoreDNS is running at https://192.168.10.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'

# 노드 정보 : 상태, INTERNAL-IP 확인
kubectl get node -owide
NAME      STATUS     ROLES           AGE    VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s-ctr   NotReady   control-plane   123m   v1.33.2   192.168.10.100   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w1    NotReady   <none>          122m   v1.33.2   10.0.2.15        <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w2    NotReady   <none>          121m   v1.33.2   10.0.2.15        <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27

# 파드 정보 : 상태, 파드 IP 확인 - kube-proxy 확인
kubectl get pod -A -owide
NAMESPACE     NAME                              READY   STATUS    RESTARTS   AGE    IP          NODE      NOMINATED NODE   READINESS GATES
kube-system   coredns-674b8bbfcf-d28x7          0/1     Pending   0          121m   <none>      <none>    <none>           <none>
kube-system   coredns-674b8bbfcf-llbdd          0/1     Pending   0          121m   <none>      <none>    <none>           <none>
kube-system   etcd-k8s-ctr                      1/1     Running   0          121m   10.0.2.15   k8s-ctr   <none>           <none>
kube-system   kube-apiserver-k8s-ctr            1/1     Running   0          121m   10.0.2.15   k8s-ctr   <none>           <none>
kube-system   kube-controller-manager-k8s-ctr   1/1     Running   0          121m   10.0.2.15   k8s-ctr   <none>           <none>
kube-system   kube-proxy-2sxhl                  1/1     Running   0          120m   10.0.2.15   k8s-w1    <none>           <none>
kube-system   kube-proxy-8k2rn                  1/1     Running   0          119m   10.0.2.15   k8s-w2    <none>           <none>
kube-system   kube-proxy-ldrml                  1/1     Running   0          121m   10.0.2.15   k8s-ctr   <none>           <none>
kube-system   kube-scheduler-k8s-ctr            1/1     Running   0          121m   10.0.2.15   k8s-ctr   <none>           <none>

# 단축어 확인(kc = kubecolor) & coredns 파드 상태 확인
k  describe pod -n kube-system -l k8s-app=kube-dns
kc describe pod -n kube-system -l k8s-app=kube-dns

 위 명령어들을 통해서 전반적인 Kubernetes 클러스터의 정보를 확인할 수 있습니다. 특히 노드의 정보를 보면 워커 노드 1번과 워커 노드 2번의 INTERNAL IP가 10.0.2.15로 같은 것으로 나옵니다. 또한 kube-system에 있는 Pod들의 IP 주소도 모두 10.0.2.15인 것을 확인할 수 있습니다. 이 부분에 대한 수정이 필요하며, 두 번째로 아직 CNI가 배포되지 않아 coredns pod가 Pending 상태인 것입니다.

# kubelet 서비스에 대한 환경 변수와 실행 인자 설정 확인
# k8s-w1/w2에서 모두 실행
cat /var/lib/kubelet/kubeadm-flags.env

# INTERNAL-IP 변경 설정
NODEIP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
sed -i "s/^\(KUBELET_KUBEADM_ARGS=\"\)/\1--node-ip=${NODEIP} /" /var/lib/kubelet/kubeadm-flags.env
systemctl daemon-reexec && systemctl restart kubelet

cat /var/lib/kubelet/kubeadm-flags.env

# 워커노드에서 실행 완료 후 INTERNAL-IP 주소 변경 확인
kubectl get node -owide
NAME      STATUS     ROLES           AGE    VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s-ctr   NotReady   control-plane   133m   v1.33.2   192.168.10.100   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w1    NotReady   <none>          132m   v1.33.2   192.168.10.101   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27
k8s-w2    NotReady   <none>          131m   v1.33.2   192.168.10.102   <none>        Ubuntu 24.04.2 LTS   6.8.0-53-generic   containerd://1.7.27

  우선 위 명령어를 통해 각 kubelet이 실행될 때 환경 변수 설정을 통해 올바른 INTERNAL-IP가 설정되도록 합니다. 워커 노드 1번과 2번에 모두 실행한 후 Control Plane에서 다시 노드들의 정보를 조회해 보면 INTERNAL-IP가 eth1의 인터페이스 IP 주소와 일치하게 설정된 것을 확인할 수 있습니다.

Static Pod의 IP 주소 변경

 위 명령어들을 통해 static pod의 IP 정보가 변경되지 않는다면 수동으로 이를 변경해 주어야 합니다. static pod의 manifests 파일은 control plane node에 /etc/kubernetes/manifests 디렉토리 아래에 위치하고 있습니다.

# static pod의 manifests 파일 정보
tree /etc/kubernetes/manifests
/etc/kubernetes/manifests
├── etcd.yaml
├── kube-apiserver.yaml
├── kube-controller-manager.yaml
└── kube-scheduler.yaml

 위 파일들을 직접 편집하여 10.0.2.15로 되어있는 IP 주소를 192.168.100.100으로 변경할 수 있습니다. 다만, 이번 실습 과정에서는 kubelet 서비스에 대한 환경 변수 설정만으로도 이것이 변경된 것을 확인할 수 있었습니다.


 이렇게 해서 CNI 배포 전 Kubernetes 클러스터를 VirtualBox와 Vagrant를 통해 구성해 보았습니다. 개인적으로는 이미 EKS나 OKE 환경에서 기존 CNI를 Cilium으로 마이그레이션 해본 경험이 있어 이후의 Flannel 배포와 Cilium 마이그레이션의 경우에는 실습을 진행하기에 수월했습니다. 단, Native Routing을 구현하는 부분은 On-premise 환경에서는 어렵다고 알고 있었는데 그렇지 않아서 또 한 번 배우는 시간이 되었습니다. Native Routing에 대한 구현에 대해서는 이어지는 포스팅에서 다뤄 보도록 하겠습니다.

 

[Cilium Study] 1주차 - 2. CNI와 Kubernetes 네트워킹

이전 포스팅 [Ciliu Study] 1주 차 - 1. 실습 환경 구성에서 이어집니다. [Cilium Study] 1주차 - 1. 실습 환경 구성'가시다'님의 [Cilium Study] 1기의 내용을 정리하는 시리즈 구성의 포스팅을 시작하려고 합니

tech-recipe.tistory.com