본문 바로가기

Kubernetes

Ubuntu 22.04 환경에서 kind 클러스터 구축하기

Ubuntu 환경에서 kind를 이용하여 쿠버네티스 클러스터를 구축해 보겠습니다.

 

kind는 Kubernetes In Docker의 약자이며, 쿠버네티스 노드 = container 와 같은 개념입니다.

 

따라서, 사용자는 container를 사용할 수 있는 환경이면, 멀티 노드 클러스터를 구축하거나 HA 클러스터를 구축할 수도 있습니다.

 

다음 설치 과정은 Ubuntu OS를 설치한 직후를 가정하고 작성하였습니다.

 

 

OS : Ubuntu 22.04.4 LTS

kind : 0.24.0

 

0. 기본 환경 구성

sudo apt update
sudo apt upgrade 
sudo apt install curl

 

 

1. docker 설치

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

 

 

1-2. 사용자에게 docker 권한 부여 (dial unix /var/run/docker.sock: connect: permission denied)

sudo groupadd docker
sudo usermod -aG docker ${USER}
newgrp docker
sudo systemctl restart docker
docker ps

 

 

2. kubectl 설치

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"

echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check


sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl



3. kind 설치

[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

 

 

kind cluster에서 GPU 사용을 하고 싶으시면 다음 설정을 하시길 바랍니다.

 

3-0. (optional)  GPU 사용을 위한 설정

nvidia container toolkit 설치

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
    
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

 

kind 클러스터에서 GPU 사용을 하기 위한 설정

sudo nvidia-ctk runtime configure --runtime=docker --set-as-default
sudo systemctl restart docker

sudo sed -i '/accept-nvidia-visible-devices-as-volume-mounts/c\accept-nvidia-visible-devices-as-volume-mounts = true' /etc/nvidia-container-runtime/config.toml

 

 

 

3-1. kind cluster 생성을 위해 해당 클러스터에 대한 manifest 파일을 작성합니다.

 

1개의 마스터노드와 2개의 worker노드를 생성하도록 설정했습니다. 또한, GPU를 사용할 수 있는 설정을 추가하였습니다.

 

필요한 부분은 수정하여 사용하시길 바랍니다.

 

노드를 많이 추가하거나, 고 가용성 클러스터를 구축하기 위해 control-plane노드를 추가하면 예상치 못한 에러가 발생할 수 있습니다.

# kind-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: kind-cluster
networking:
  # WARNING: It is _strongly_ recommended that you keep this the default
  # (127.0.0.1) for security reasons. However it is possible to change this.
  apiServerAddress: "127.0.0.1"
  # By default the API server listens on a random open port.
  # You may choose a specific port but probably don't need to in most cases.
  # Using a random port makes it easier to spin up multiple clusters.
  #  apiServerPort: 6443
  disableDefaultCNI: false
nodes:
  # https://github.com/kubernetes-sigs/kind/releases
- role: control-plane
  image: kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865
  # Ingress Controller
  kubeadmConfigPatches:
    - |
      kind: InitConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"
  extraPortMappings:
    # Ingress Controller
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    - containerPort: 443 
      hostPort: 443
      protocol: TCP
- role: worker
  image: kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865
  extraMounts:
    - hostPath: /dev/null
      containerPath: /var/run/nvidia-container-devices/all
- role: worker
  image: kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865
  extraMounts:
    - hostPath: /dev/null
      containerPath: /var/run/nvidia-container-devices/all

 

+ kubernetes version에 대한 kind Image는 여기에서 확인이 가능합니다.

 

 

 

3-2. kind cluster를 생성합니다.

# kind.yaml 위치에서 명령어 실행
kind create cluster --config kind.yaml

 

설치가 잘 되었는지 확인해 봅시다.

kubectl get nodes

 

노드 정보

 

 

4. (Optional) k9s 설치

# k9s 바이너리 설치
wget https://github.com/derailed/k9s/releases/download/v0.32.5/k9s_Linux_amd64.tar.gz && \
    tar -zxvf ./k9s_Linux_amd64.tar.gz && \
    chmod +x k9s && \
    sudo mv ./k9s /usr/local/bin/ && \
    rm ./k9s_Linux_amd64.tar.gz LICENSE README.md

 

 

k9s 명령어를 실행해 봅시다.

k9s

 

다음과 같이 나온다면 설치가 완료되었습니다.

 

 


 

추가) 컴퓨터 재부팅 혹은 도커 재시작 후에 kind cluster 연결이 되지 않는 문제 해결

 

kind cluster를 구성하고, 컴퓨터를 재시작하면 kind 클러스터와 통신이 되지 않는 문제가 발생합니다.

 

docker ps를 실행하면, 컨테이너는 실행중이지만 다음과 같은 status를 출력합니다.

 

up less than a second..

 

 

이는 도커가 재시작되면 컨테이너(kind node)의 IP가 바뀌게 되어, 통신할 수 없는 문제입니다.

 

kind는 0.24.0 버전 기준현재 클러스터 중지와 재시작과 같은 옵션을 제공하지 않기 때문에 PC를 재부팅하는 경우 이러한 문제를 겪을 수 있습니다.

 

우선,

해당 오류가 발생하시는 분은 kind node 개수를 줄여보시길 바랍니다. 

 

 

저는 1개의 control-plane과 3개의 worker로 클러스터를 구성하였을 때 오류가 발생하여, 현재는 1개의 control-plane과 2개의 worker 노드로 클러스터를 구성하였습니다.

 

그 다음에 아래의 스크립트를 실행해 보시길 바랍니다.

 

 

저는 다음 script를 이용하여 정적IP를 각 노드(컨테이너)에 할당하는 방법을 사용했습니다.

 

kind_static_ips.sh

#!/bin/bash
set -e

CLUSTER_NAME="kind-cluster"

# Workaround for https://github.com/kubernetes-sigs/kind/issues/2045
all_nodes=$(kind get nodes --name "${CLUSTER_NAME}" | tr "\n" " ")
declare -A nodes_table
ip_template="{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}"

echo "Saving original IPs from nodes"

for node in ${all_nodes}; do
  nodes_table["${node}"]=$(docker inspect -f "${ip_template}" "${node}")
  echo "${node}: ${nodes_table["${node}"]}"
done

echo "Stopping all nodes and registry"
docker stop ${all_nodes} >/dev/null

echo "Re-creating network with user defined subnet"
subnet=$(docker network inspect -f "{{(index .IPAM.Config 0).Subnet}}" "kind")
echo "Subnet: ${subnet}"
gateway=$(docker network inspect -f "{{(index .IPAM.Config 0).Gateway}}" "kind")
echo "Gateway: ${gateway}"
docker network rm "kind" >/dev/null
docker network create --driver bridge --subnet ${subnet} --gateway ${gateway} "kind" >/dev/null

echo "Assigning static IPs to nodes"
for node in "${!nodes_table[@]}"; do
  docker network connect --ip ${nodes_table["${node}"]} "kind" "${node}"
  echo "Assigning IP ${nodes_table["${node}"]} to node ${node}"
done

echo "Starting all nodes and registry"
docker start ${all_nodes} >/dev/null

echo -n "Wait until all nodes are ready "

while :; do
  [[ $(kubectl get nodes | grep Ready | wc -l) -eq ${#nodes_table[@]} ]] && break
  echo -n "."
  sleep 5
done

echo

 

 

 해당 스크립트를 실행합니다.

(스크립트 마지막 kubectl 명령에서 오류가 발생할 수 있습니다.)

 

bash kind_static_ips.sh

 

 

 

클러스터 상태를 확인해 봅니다.

kubectl get nodes

 

 


 

이번 포스팅은 kind cluster를 구축해보았습니다.

 

다음은 GPU 사용을 위한 환경 구성을 진행해보겠습니다.