- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
로컬에서 Kubernetes 클러스터 구축하기
Vagrantfile 살펴보기
이번에는 앞에서 실행했던 Vagrantfile
의 내용을 살펴보겠습니다. 양이 많은 것 같지만 그렇게 복잡하지는 않습니다.
Vagrant.configure("2") do |config|
config.vm.boot_timeout = 3000
config.vm.define "master" do |master|
master.vm.box = "ubuntu/jammy64"
master.vm.network "private_network", ip: "192.168.56.10"
master.vm.hostname = "master"
master.vm.provider "virtualbox" do |v|
v.memory = 4096
v.cpus = 4
end
master.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.10
EOF
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
OUTPUT_FILE=/vagrant/join.sh
rm -rf $OUTPUT_FILE
rm -rf /vagrant/.kube
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.56.10 --apiserver-advertise-address=192.168.56.10
sudo kubeadm token create --print-join-command > $OUTPUT_FILE
chmod +x $OUTPUT_FILE
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
cp -R $HOME/.kube /vagrant/.kube
cp -R $HOME/.kube /home/vagrant/.kube
sudo chown -R vagrant:vagrant /home/vagrant/.kube
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl completion bash >/etc/bash_completion.d/kubectl
echo 'alias k=kubectl' >>/home/vagrant/.bashrc
EOC
end
(1..3).each do |i|
config.vm.define "worker#{i}" do |worker|
worker.vm.box = "ubuntu/jammy64"
worker.vm.network "private_network", ip: "192.168.56.1#{i}"
worker.vm.hostname = "worker#{i}"
worker.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
end
worker.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.1#{i}
EOF
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
EOC
end
end
end
먼저 Vagrantfile
의 첫 부분입니다(참고로 Vagrantfile
은 Ruby 언어로 작성이 되어 있습니다). Vagrantfile
은 Vagrant.configure("2") do |config|
로 시작하며 그 아래에 각종 설정을 넣게 됩니다. 여기서 "2"
는 Vagrant.configure
버전 2라는 뜻이며 가상머신을 2개 만들겠다는 뜻이 아닙니다.
Vagrant.configure("2") do |config|
config.vm.boot_timeout = 3000
config.vm.boot_timeout
: 가상머신 부팅 대기 시간입니다. 이 값을 짧게 설정하면 부팅이 끝나기 전에vagrant up
명령이 실패할 수 있습니다.
이제 master 노드 설정 부분입니다. config.vm.define "master" do |master|
으로 마스터 노드 정의하고 그 아래에 설정을 넣게 됩니다.
config.vm.define "master" do |master|
master.vm.box = "ubuntu/jammy64"
master.vm.network "private_network", ip: "192.168.56.10"
master.vm.hostname = "master"
master.vm.provider "virtualbox" do |v|
v.memory = 4096
v.cpus = 4
end
master.vm.box
: Vagrant는 가상머신 이미지를 box라고 부릅니다. 여기서는 Ubuntu 22.04 버전인"ubuntu/jammy64"
를 사용하도록 설정했습니다.master.vm.network
: 네트워크 설정입니다."private_network"
로 내부 네트워크를 사용하도록 했고 master 노드의 IP 주소는"192.168.56.10"
으로 설정했습니다.master.vm.hostname
: 가상머신의 호스트 이름입니다. master 노드이므로"master"
로 설정했습니다.master.vm.provider "virtualbox" do |v|
: 우리는 가상머신 프로그램으로 VirtualBox를 사용하기로 했으므로 VirtualBox 관련 설정을 해줍니다.v.memory
: 가상머신의 메모리 크기입니다. 여기서는 4096(4Gi)을 설정했습니다.v.cpus
: 가상머신의 CPU 개수입니다. 여기서는 4개로 설정했습니다.
여기서부터는 provision
이라고 해서 Vagrant가 가상머신을 생성한 뒤 실행할 스크립트를 정의하는 부분입니다. 이 부분의 내용이 많은데, 부분 부분 나눠서 설명하겠습니다.
master 노드의 provision
설정은 이렇게 시작합니다. master.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
에서 "0"
은 provision의 이름, "shell"
은 셸 스크립트, preserve_order: true
는 실행 순서를 유지하겠다는 뜻입니다. privileged: true
는 현재 스크립트를 root 권한으로 실행하겠다는 뜻입니다. 마지막으로 inline: <<-EOC
다음 줄부터 스크립트가 시작됩니다.
다음은 kubeadm
실행에 필요한 커널 모듈을 로딩하고, 커널 설정값을 변경하는 부분입니다.
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
br_netfilter
: iptables를 사용하기 위해 필요한 커널 모듈입니다. 부팅할 때 로딩할 수 있도록/etc/modules-load.d/kubernetes.conf
파일 안에도 넣어줍니다. 그리고sudo modprobe br_netfilter
명령으로br_netfilter
커널 모듈을 지금 즉시 로딩해줍니다.net.ipv4.ip_forward = 1
은 IPv4 포워딩 기능을 활성화합니다.net.bridge.bridge-nf-call-iptables = 1
과net.bridge.bridge-nf-call-ip6tables = 1
은 컨테이너의 네트워크 패킷을 호스트의 iptables 설정에 따라 제어되도록 합니다. 부팅할 때 설정값을 반영할 수 있도록/etc/sysctl.d/kubernetes.conf
파일 안에도 넣어줍니다. 그리고sudo sysctl --system
명령을 실행하여 설정값을 지금 즉시 반영해줍니다.
kubelet
설정입니다. 이 Vagrantfile
에서 생성한 VirtualBox 가상머신은 네트워크 인터페이스가 2개 생성됩니다. 여기서 master.vm.network "private_network", ip: "192.168.56.10"
으로 생성한 두 번째 네트워크 인터페이스의 IP 주소인 192.168.56.10
을 --node-ip
에 설정해줍니다.
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.10
EOF
containerd 설치 및 설정 부분입니다. 우리는 쿠버네티스의 컨테이너 런타임 인터페이스(CRI)로 containerd를 사용할 것이므로 다음과 같이 작성했습니다.
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
sudo apt update
로 apt 패키지 목록을 업데이트해주고sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
로 필요한 패키지들을 설치합니다.sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
로 Docker 인증서를 설치하고,sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
로 apt 저장소 목록에 Docker 저장소를 추가해줍니다.- 다시
sudo apt update
로 apt 패키지 목록을 업데이트해주고,sudo apt install -y containerd.io
로 containerd를 설치합니다. 이 과정없이sudo apt install -y containerd
로 우분투에 내장된 containerd를 설치하면kubeadm
이 제대로 실행되지 않으므로 주의해야 합니다. containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
로 containerd 기본 설정값을 만들어내고,sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
로SystemdCgroup
을true
로 변경해줍니다. 우리는 쿠버네티스의 Cgroups로 systemd를 사용할 것이기 때문입니다.sudo systemctl restart containerd
로 containerd 서비스를 재시작하여 바뀐 설정을 반영해주고,sudo systemctl enable containerd
로 부팅했을 때 containerd 서비스가 실행되도록 설정해줍니다.
이 부분이 핵심입니다. kubeadm init
으로 쿠버네티스 클러스터의 master 노드를 생성합니다.
OUTPUT_FILE=/vagrant/join.sh
rm -rf $OUTPUT_FILE
rm -rf /vagrant/.kube
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.56.10 --apiserver-advertise-address=192.168.56.10
sudo kubeadm token create --print-join-command > $OUTPUT_FILE
chmod +x $OUTPUT_FILE
OUTPUT_FILE=/vagrant/join.sh
은kubeadm init
명령 실행 후 출력되는kubeadm join
명령을 일일이 복사해서 붙여넣기 번거로우므로 스크립트 파일로 저장하기 위한 부분입니다. 특히/vagrant
디렉터리는 Vagrant로 생성한 모든 가상머신에서 공유하는 디렉터리이며Vagrantfile
이 있는 로컬 폴더(디렉터리)와도 공유되는 곳입니다.rm -rf $OUTPUT_FILE
로 이전 스크립트 파일을 삭제하고,rm -rf /vagrant/.kube
로 이전.kube
디렉터리도 삭제합니다.sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.56.10 --apiserver-advertise-address=192.168.56.10
으로 쿠버네티스 클러스터의 master 노드를 생성합니다.--pod-network-cidr=10.244.0.0/16
: 우리는 쿠버네티스 컨테이너 네트워크 인터페이스(CNI)로 flannel을 사용할 것이므로--pod-network-cidr
를10.244.0.0/16
로 설정해줍니다.--control-plane-endpoint=192.168.56.10
: 로컬 환경이라 도메인이 필요없으므로 제어 플레인 엔드포인트를 master 노드의 IP 주소192.168.56.10
으로 설정합니다.--apiserver-advertise-address=192.168.56.10
: apiserver 주소도 master 노드의 IP 주소192.168.56.10
으로 설정합니다.
kubeadm init
실행 후에도kubeadm join
명령이 나오지만 스크립트 파일에 저장하기 위해sudo kubeadm token create --print-join-command > $OUTPUT_FILE
를 실행해줍니다. 그리고chmod +x $OUTPUT_FILE
로 스크립트 파일에 실행 권한을 부여합니다.
이제 클러스터 바깥에서 클러스터를 제어할 수 있도록 .kube
디렉터리와 설정파일을 만들어주고, CNI인 flannel을 설치합니다. 그리고 bash 자동 완성 설정과 kubectl
을 k
로 약칭(alias)을 만들어줍니다.
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
cp -R $HOME/.kube /vagrant/.kube
cp -R $HOME/.kube /home/vagrant/.kube
sudo chown -R vagrant:vagrant /home/vagrant/.kube
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl completion bash >/etc/bash_completion.d/kubectl
echo 'alias k=kubectl' >>/home/vagrant/.bashrc
mkdir -p $HOME/.kube
로 홈 디렉터리에.kube
디렉터리를 생성합니다. 그리고sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
로/etc/kubernetes/
안에 있는admin.conf
를.kube
아래에config
파일로 복사해줍니다. 마지막으로sudo chown $(id -u):$(id -g) $HOME/.kube/config
로config
파일의 소유자와 그룹을 현재 사용자와 그룹으로 변경해줍니다. 이때$HOME
은/root
이고 사용자와 그룹은root
입니다. 이렇게 해야kubectl
을 실행하여 flannel을 설치할 수 있습니다.- 가상머신 바깥에서
.kube
디렉터리를 가져갈 수 있도록cp -R $HOME/.kube /vagrant/.kube
를 실행합니다. - root가 아닌 vagrant 일반 계정에서도
kubectl
을 실행할 수 있도록cp -R $HOME/.kube /home/vagrant/.kube
을 실행하여.kube
디렉터리를 복사하고sudo chown -R vagrant:vagrant /home/vagrant/.kube
로 소유자와 그룹을 vagrant로 변경합니다. kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
를 실행하여 CNI flannel을 설치합니다. CNI는 여러 종류가 있지만 여기서는 flannel을 설치하겠습니다.kubectl completion bash >/etc/bash_completion.d/kubectl
를 실행하여 bash 자동 완성 설정을 해주고,echo 'alias k=kubectl' >>/home/vagrant/.bashrc
를 실행하여kubectl
을k
로 약칭(alias)을 만들어줍니다.
다음은 worker 노드 부분입니다. worker 노드는 (1..3)
으로 1부터 3까지 루프를 돌면서 노드 3개를 생성합니다.
(1..3).each do |i|
config.vm.define "worker#{i}" do |worker|
worker.vm.box = "ubuntu/jammy64"
worker.vm.network "private_network", ip: "192.168.56.1#{i}"
worker.vm.hostname = "worker#{i}"
worker.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
end
worker.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
worker.vm.box
: master 노드와 마찬가지로 Ubuntu 22.04 버전인"ubuntu/jammy64"
를 사용하도록 설정했습니다.worker.vm.network
: 네트워크 설정입니다."private_network"
로 내부 네트워크를 사용하도록 했고 worker 노드의 IP 주소는"192.168.56.1#{i}"
로 설정해서 11부터 13까지 사용하도록 합니다.worker.vm.hostname
: 가상머신의 호스트 이름입니다."worker#{i}"
로 설정하여 worker1부터 3까지 사용하도록 합니다.worker.vm.provider "virtualbox" do |v|
: worker 가상머신의 VirtualBox 설정입니다.v.memory
: 가상머신의 메모리 크기입니다. 여기서는 2048(2Gi)을 설정했습니다.v.cpus
: 가상머신의 CPU 개수입니다. 여기서는 2개로 설정했습니다.
worker.vm.provision
:join.sh
스크립트 생성 부분,kubeadm init
으로 master 노드를 생성하는 부분, flannel을 설치하는 부분,.kube
디렉터리 복사 부분 등을 제외하면 스크립트는 master와 동일하게 containerd와kubeadm
을 설치합니다.
지금까지 Vagrantfile
로 가상머신을 생성하는 부분과 쿠버네티스 클러스터를 생성하기 위한 스크립트들을 알아보았습니다. Vagrant 없이 수동으로 가상머신을 생성하고, 스크립트를 입력해도 동일하게 쿠버네티스 클러스터를 만들 수 있습니다.
다음 장에서는 이 쿠버네티스 클러스터에서 Nginx 디플로이먼트와 서비스를 생성한 뒤 인그레스도 설정해보겠습니다.
저작권 안내
이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.- 블로그, 게시판 등에 퍼가는 것을 금지합니다.
- 비공개 포스트에 퍼가는 것을 금지합니다.
- 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
- 링크 및 SNS 공유는 허용합니다.