MLOps

k8s v1.25.2 master node 구축

Crysis 2022. 10. 11. 14:06

쿠버네티스 릴리즈 1.24부터 Dockershim이 제거되었다.

Docker 지원을 하지 않는 이유는 쿠버네티스를 서비스하고 있는 회사 CNCF는 Vendor Lock을 싫어한다. Docker는 사기업이기 때문에 Vendor Lock에 걸릴 가능성이 있었고 이에 Docker의 의존성을 없애는 판단을 한 것 같다.

 

최근 Minkube로 Kubeflow pipeline을 구축하였었는데 GPU를 할당하는 과정에서 driver=docker는 GPU지원이 되지 않았다.

그래서 Docker를 사용하지 않는 최신버전을 공부할 필요를 느끼게 되었고 그렇지 않아도 쿠버네티스 자격증을 따볼까 생각하던 차에 이렇게 되버렸으니 k8s를 제대로 공부할 생각이다.

 

이번 포스트의 환경은 k8s v1.25.2버전이며 ubuntu20.04 LTS로 master, node1, node2를 구축해놓은 상태이며 구축하면서 발생된 에러에 대한 부분을 설치 command와 같이 설명할 예정이다


K8s Install

메모리 스왑을 끄는 command(쿠버네티스는 반드시 끄라고 말한다) 끄지 않으면 init 할 때 에러가 난다

swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

 

 

container runtimes

su -

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

 

k8s 설치

cat <<EOF | 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 --system
apt-get update
apt-get install -y apt-transport-https ca-certificates curl
curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

 

 

container runtimes와 k8s를 기본적으로 설치하고 들어가야한다

 

필자는 container runtimes를 containerd로 진행하였다.

쿠버네티스 공홈 https://kubernetes.io/docs/setup/production-environment/container-runtimes/ 에서 docker로 설정하는 방법도 설명하고 있으니 위 사이트를 참고하면 되겠다.(도커는 cri-dockerd를 추가로 설치해야한다)

 

Cgroup drivers

container runtimes와 k8s의 Cgroup을 맞추어 주어야한다.

containerd와 k8s는 자동으로 systemd로 설정되어 추가로 해주어야 할 필요가 없지만 Docker는 cgroupfs로 되어있는것을 systemd로 설정해 주어야 한다.

해당 문제는 https://hyeo-noo.tistory.com/m/386 여기에서 확인해 보면 된다.

 

cgroup를 개념을 처음엔 몰랐어서 개념을 알 필요가 있었다. 추가로 알고싶으면 아래 글을 펼치면 된다.

 

더보기

cgroup이란?

cgroup은 control group의 준말로 컨테이너 생성에 있어서 기초되는 개념이다.
컨테이너가 생성될 때 저수준 런타임 단계에서 linux kernel의 namespace와 cgroup을 이용해서 컨테이너를 만들고 실행시킨다.

 

컨테이너라는 격리된 공간에서 자원을 격리된 것처럼 사용할 수 있는 것이다.

cgroups(Control Groups)는 자원(resources)에 대한 제어를 가능하게 해주는 리눅스 커널의 기능이다.

cgroups는 다음 리소스를 제어할 수 있다.

  • 메모리
  • CPU
  • I/O
  • 네트워크
  • device 노드(/dev/)

cgroup 드라이버

Control group은 프로세스에 할당된 리소스를 제한하는데 사용된다.

리눅스 배포판의 init 시스템이 systemd인 경우,

init 프로세스 root control group(cgroup)을 생성 및 사용하는 cgroup 관리자로 작동한다.

Systemd는 cgroup과의 긴밀한 통합을 통해 프로세스당 cgroup을 할당한다.

그리고 cgroup 드라이버로 cgroupfs가 존재하는데,

컨테이너 런타임 kubelet만이 cgroupfs를 사용하도록 설정할 수 있다.

systemd와 함께 cgroupfs를 사용하면 두 개의 서로 다른 cgroup 관리자가 존재하게 된다는 뜻이다.

 

  • cgroupfs driver
    cgroupfs는 cgroup을 제어하기 위해 만들어진 특수한 file system 방식
  • systemd driver
    systemd 자체가 init process 역할도 하면서, cgroup 또한 제어

단일 cgroup 관리자는 할당되는 리소스가 무엇인지를 단순화하고, 기본적으로 사용할 수 있는 리소스와 사용 중인 리소스를 일관성있게 볼 수 있다.

시스템에 두 개의 cgroup 관리자가 있으면, 이런 리소스도 두 개의 관점에서 보게 된다.

그런데 실무에서 kubelet과 도커에 cgroupfs를 사용하고, 나머지 프로세스는 systemd를 사용하도록 노드가 설정된 경우, 리소스가 부족할 때 불안정해지는 사례가 있다고 한다.

 

문제를 해결하기 위해서 컨테이너 런타임과 kubelet의 cgroup 드라이버로 systemd를 선택하도록 설정을 변경하면 시스템을 안정화 할 수 있다.

도커(컨테이너 런타임)에 대해 cgroup을 systemd로 구성하려면, native.cgroupdriver=systemd를 설정한다.

(설정 방법은 아래에.)

 

k8s나 docker를 접하게 되면, cgroup driver를 cgroupfs 또는 systemd로 설정하는 부분을 마주하게 된다.

이 때 cgroup을 systemd로 맞추는 것을 권장하고, 이는 위에서 언급했듯이 시스템을 안정적으로 운영하기 위함이다.

 

출처: https://hyeo-noo.tistory.com/m/386

 

kubeadm init 에러

[init] Using Kubernetes version: v1.25.2
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR CRI]: container runtime is not running: output: E0714 16:19:47.735413    6012 remote_runtime.go:925] "Status from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
time="2022-07-14T16:19:47+09:00" level=fatal msg="getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

설치를 마무리하고 kubeadm init 커맨드를 실행하면 위와 같은 에러가 났을 수도 있다.

필자는 2가지 에러가 났었는데 처음에 메모리 스왑기능을 꺼주지 않아서 위 에러에서 메모리 스왑에러가 하나 더 있었다.

 

에러의 원인은 ubuntu 20.04, containerd.io 1.3.7 이상시 문제가 발생한다고 한다  https://github.com/containerd/containerd/issues/4581 

 

 

해결방법

sudo rm /etc/containerd/config.toml
sudo systemctl restart containerd
sudo kubeadm init

 

kubeadm init 이후 생성되는 토큰을 node1, node2에 적용시키고 container runtime이 위 사진과 같이 containerd로 나오면 성공.