새소식

Recent Study/udemy - CKA with Practice Tests

Section 11 : Deploy with Kubeadm(+프로비저닝 중 문제점 해결과정)

  • -

전에 얘기한 바와 같이, 쿠버네티스 클러스터는 kubeAPI서버, etcd, controller 등 다양한 컴포넌트로 구성됩니다. 그리고 우리는 이러한 컴포넌트 간의 통신을 가능하게 하기 위한 보안과 인증서 관련한 몇 가지 요구사항도 보았습니다. 이러한 다양한 컴포넌트를 각각의 노드에서 개별적으로 모두 설치하고 configuration file들을 수정하여 컴포넌트가 서로를 가리키는지 확인하고 인증서가 잘 작동하는지 확인하는 것은 지루한 작업입니다. kubeadm 툴은 이러한 모든 작업을 처리함으로써 우리에게 도움을 줍니다.

Steps

kubeadm 툴을 사용해서 쿠버네티스 클러스터를 설정하는 단계를 대략적으로 살펴보겠습니다.

 

첫째, 클러스터를 구성하기 위한 여러 시스템 또는 프로비저닝된 가상머신이 있어야 합니다. 우리는 랩탑에서 설정하는 방법을 볼 것입니다. 익숙하지는 않은 경우입니다. 시스템이 생성되면 하나의 노드를 마스터로 지정하고 다른 노드는 워커노드로 둡니다.

다음 단계는 호스트에서 컨테이너 런타임을 설치하는 것입니다. 우리는 도커를 사용할 것입니다. 따라서 모든 노드에 도커를 설치해야 합니다.

 

두번째, kubeadm 툴을 모든 노드에 설치하는 것입니다. kubeadm 툴은 필요한 모든 컴포넌트를 올바른 노드에 올바른 순서로 설치하고 구성하는 쿠버네티스 솔루션 부트스트랩을 지원합니다.

 

셋째, 마스터를 초기화하는 것입니다. 이 과정을 통해 마스터 서버에 필요한 모든 컴포넌트가 설치되고 구성되었습니다. 마스터가 초기화되면, 워커 노드를 마스터에 결합하기 전에 네트워크 전제조건이 충족되었는지 확인해야 합니다. 시스템 간의 정상적인 네트워크 연결로는 충분하지 않습니다. 쿠버네티스에는 마스터 노드와 워커 노드 사이의 특별한 네트워킹 솔루션이 필요합니다. 이를 파드 네트워크라고 합니다.

 

넷째 워커 노드를 마스터 노드에 조인시키는 것입니다. 이렇게 쿠버네티스에서 우리의 애플리케이션을 시작하기 위한 준비가 완료되었습니다. 

 

직접 vagrant와 virtualbox를 통해 vm을 프로비저닝 해봅시다.

일단 아래 url에서 필요한 정보를 clone 해옵니다. https://github.com/kodekloudhub/certified-kubernetes-administrator-course/blob/master/docs/11-Install-Kubernetes-the-kubeadm-way/04-Demo-Deployment-with-Kubeadm.md 

 

certified-kubernetes-administrator-course/docs/11-Install-Kubernetes-the-kubeadm-way/04-Demo-Deployment-with-Kubeadm.md at maste

Certified Kubernetes Administrator - CKA Course. Contribute to kodekloudhub/certified-kubernetes-administrator-course development by creating an account on GitHub.

github.com

 

clone 해온 후 /desktop/certified-kubernetes-administrator-course/kubeadm-clusters/virtualbox 들어가시면, Vagrant 파일이 있는데 해당 위치에서 vagrant up 명령을 실행시켜 vm을 생성할 수 있습니다. 실행 전에는 아래의 machine 상태가 죽어있습니다. 하지만 1.vagrant up을 실행하는 과정에서 아래와 같은 문제점이 발생했는데요.

 

 

가장 많은 해결책으로는 virtualbox 확장팩을 설치해주는 것이 대표적이었습니다. 저처럼 Mac을 사용하시는 분은 설정의 정보보호 및 보안 쪽에서 안전하지 않은 소프트웨어에 알림이 뜨지 않았나 확인해주시면 좋을 것 같습니다. 확장팩은 virtualbox 공식 홈페이지에 들어가보시면 메인에 나와있으니 다운받으실 수 있습니다. 하지만 이처럼 해도 결과는 다르지 않았습니다. 제 기억으로 vagrant와 virtualbox 설치를 한지 1,2년 정도 된 것으로 아는데, 혹시 버전 호환이나 패키지 문제가 아닐까 했습니다.

 

 

그래서 설치되어있는 vagrant와 virtualbox를 모두 삭제한 후 최신 버전으로(2024.08.11일 기준 vagrant : 2.4.1, virtualbox : 7.0.20)재설치했습니다. 재시동 후 명령어를 작성하였을 때, 성공적으로 vm이 모두 잘 돌아가고 있는 것을 확인할 수 있었습니다. (해당 문제를 고치려고 2시간 정도 서칭하는데 시간을 사용..)

 

하지만 이번에는 다른 문제가 발생.. 2. Error 내용을 봐보면 인자의 잘못된 개수 때문에 발생했다고 나오는데요. 이는 서칭을 해도 답변이 전부 상이해서 Gpt에게 어떤 문제인지 조언을 구했습니다.

 

 

답변 결과 : 에러 메시지에서 문제의 핵심은 I18n.translate 메서드가 잘못된 인자 개수를 받았기 때문입니다. I18n.translate는 기본적으로 0개에서 1개의 인자를 받도록 설계되어 있는데, 2개의 인자를 전달해서 에러가 발생했습니다. 이 문제가 발생한 경로는 vagrant-vbguest라는 플러그인의 일부 코드에서 시작된 것 같습니다. vagrant-vbguest는 VirtualBox Guest Additions를 관리하는 Vagrant 플러그인입니다. 이 플러그인이 I18n.translate를 호출하는 과정에서 잘못된 인자를 전달하고 있어 충돌이 발생한 것입니다.

 

> vagrant plugin update vagrant-vbguest

 

라고 친절하게 설명해주네요. gpt가 전부 맞는 솔루션만 주는 것이 아니라, 반신반의로 위처럼 해보았는데요. 결과는 성공적이었습니다. :)

 

 

이제 running 상태의 3개 노드를 확인할 수 있고, 이에 접근하고자 합니다. 특정 노드의 이름을 입력하면 되는데요. 아래 명령으로 해당 vm에 들어온 것을 확인할 수 있었습니다. 실습을 위해 모든 노드에 접속을 해놓았습니다. 아래 그림처럼요.

> vagrant ssh controlplane

 

 

이제 쿠버네티스 클러스터 설치를 시작할 것이죠. kubeadm 설치 페이지로 가면 되는데, 모든 노드에 Container runtime을 설치해야합니다. 예제에서는 containerD를 설치하겠습니다.

 

(kubernetes docs 내용)

파드에서 컨테이너를 실행하기 위해, 쿠버네티스는 컨테이너 런타임을 사용합니다. 기본적으로, 쿠버네티스는 컨테이너 런타임 인터페이스(CRI)를 사용하여 사용자가 선택한 컨테이너 런타임과 인터페이스한다. 런타임을 지정하지 않으면, kubeadm은 잘 알려진 엔드포인트를 스캐닝하여 설치된 컨테이너 런타임을 자동으로 감지하려고 한다. 컨테이너 런타임이 여러 개 감지되거나 하나도 감지되지 않은 경우, kubeadm은 에러를 반환하고 사용자가 어떤 것을 사용할지를 명시하도록 요청할 것이다.

 

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 필요한 sysctl 파라미터를 설정하면, 재부팅 후에도 값이 유지된다.
cat <<EOF | sudo 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 파라미터 적용하기
sudo sysctl --system

 

매우 간단합니다. 위 내용을 모든 노드에서 실행하면 되죠. 그리고 확인을 위해 아래 명령어를 사용하시면 됩니다. 그리고 시스템의 변수를 1로 설정했는지는 그 아래 명령어를 통해 알 수 있습니다.

> lsmod | grep br_netfilter, > lsmod | grep overlay

> sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

 

 

좋습니다. 이제 runtime으로 가서 containerD를 선택해보죠. 저희는 Ubuntu를 사용하고 있고, 해당 조건에 맞는 것을 선택하면 페이지로 이동하게 됩니다. containerD를 설치하는 과정은 Docker Engine을 설치하는 것과 비슷합니다.

 

첫째로, 할 일은 저장소를 설정하는 것이죠. 아래 내용을 3개의 노드에 붙여넣어 주세요. 저장소 설정이 끝나면 apt-get update를 실행해주세요.

 

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
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" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

sudo apt-get update

 

이제 containerd를 추가하려면 아래 명령어를 실행해주세요. (공식 문서에는 추가적인 명령이 있지만 docker 패키지가 필요한 것이 아니니 아래처럼만 하셔도 괜찮습니다.)

> sudo apt install containerd.io

 

 

성공적이네요. :)

그럼 이제 다음 단계로 넘어가기 전에 containerD와 할 일이 하나 더 있어요. Cgroup Drivers 페이지로 이동하세요. 이 부분이 중요한데, 개요를 설명드리면 Linux 컴퓨터에 컨트롤 그룹이란게 있습니다. 컨트롤 그룹은 여러분의 머신에서 실행되는 다른 프로세스에 할당된 자원을 제한하는데 사용됩니다. kubelet과 container Runtime 둘 다 이 컨트롤 그룹과 인터페이스해야 합니다. 그러면 Pod에 대해 다양한 리소스 관리가 가능하죠.

 

결론적으로 컨트롤 그룹과 인터페이스하려면 Cgroup drivers를 사용하면 됩니다.

 

(kubernetes 공식 문서 내용 중)

리눅스에서, control group은 프로세스에 할당된 리소스를 제한하는데 사용된다. kubelet과 그에 연계된 컨테이너 런타임 모두 컨트롤 그룹(control group)들과 상호작용 해야 하는데, 이는 파드 및 컨테이너 자원 관리가 수정될 수 있도록 하고 cpu 혹은 메모리와 같은 자원의 요청(request)과 상한(limit)을 설정하기 위함이다. 컨트롤 그룹과 상호작용하기 위해서는, kubelet과 컨테이너 런타임이 cgroup 드라이버를 사용해야 한다. 매우 중요한 점은, kubelet과 컨테이너 런타임이 같은 cgroup group 드라이버를 사용해야 하며 구성도 동일해야 한다는 것이다. 두 가지 cgroupfs, systemd의 cgroup 드라이버가 이용 가능하다.

 

보통 cgroupfs가 default이지만, 명심해야할 것은, 똑같은 Cgroup drivers를 사용해야하죠. 따로 다른것을 이용할 수 없다는 뜻입니다. 저희가 사용하고 있는 것은 어떤 것일까요?

 

 

systemd이군요. Cgroup drivers의 내용은 /etc/containerd/config.toml에 있네요. 그리고 아래를 만족하면 됩니다. 작업해보죠.

 

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

 

기본적으로 설정되어 있는 것은 모두 지우세요. 위 구문에서 ...만 지우고, 3개의 모든 노드에서 해당 파일을 바꿔주세요.  그리고

> sudo systemctl restart containerd 를 실행하면 컨테이너 런타임 설치가 끝이 납니다.

 

이제 kubeadm 설치 페이지로 돌아가보죠. 이번에는 kubelet과 kubectl을 설치할 예정입니다. kubeadm은 클러스터 부트스트랩을 책임지는 도구죠. 아래는 kubeadm 설치 페이지에 들어가시면 나오시니 참고하시면 좋을 것 같습니다. 아래 명령어를 3개의 노드에 붙여주죠.

 

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/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.30/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

 

이 실행이 성공적이라면, kubectl, kubeadm, kubelet 설치가 완료된 것 입니다. 이제 쿠버네티스 클러스터 구성 및 프로비저닝을 시작할 수 있습니다.

 

k8s docs 내용 중

 

이제는 마스터 노드에서 > kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.56.2 실행하죠. 이렇게 controlplane이 성공적으로 초기화되면, 해야할 일이 있습니다.

 

1. 관리입니다. 쿠버네티스 클러스터에 연결할 수 있도록 만들어졌죠. 저희는 홈 디렉터리에 .kube 폴더를 만들고 이 관리자를 복사하겠습니다. 아래 명령을 마스터 노드에서 실행하면, 이제 클러스터에 연결을 할 수 있게 됩니다. 확인해보죠.

 

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

> kubectl get pod 명령어를 통해 [ No resources found in default namespace. ] 가 반환된다면 성공적으로 연결되신겁니다. 그리고, 이제 Weave net 링크로 들어갑니다. 아래를 복사해서 마스터 노드에서 실행해주세요.

> kubectl apply -f https://github.com/weaveworks/weave/release/download/v2.8.1/weave-daemonset-k8s.yaml

 

그리고 > kubectl get pods -A 를 실행하시면, namespace에 모든 pod를 확인할 수 있고, control-plane 노드에 배포되고 있는 pod를 하나 발견할 수 있습니다. 하지만 아직 worker 노드에서는 이가 보이지 않는데, 연결을 해주지 않았기 때문이죠. Daemonset의 파일을 수정해서, 네트워크를 setup 후, worker 노드를 클러스터에 조인하면 서로 연결되어 있는 클러스터를 구성할 수 있게 됩니다.

 

위 마스터 노드에서 kubeadm join~ 로 반환된 것이 있는데, 이를 worker 노드에 붙여 넣어주면 완성입니다. 고생하셨습니다!!

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.