주녁, DevNote
article thumbnail

개요

DevOps 관련 작업을 할 때면, 운영중인 클러스터에 반영하기 선뜻 겁나는 작업들이 있다.

그렇다고 Local 개발 환경에 적용하자니 실제 환경과 비슷하게 Node를 여러개 만들기 어렵기도 하다.

이럴 때 사용할 수 있는 좋은 프로젝트가 있어서 같이 학습해보고자 한다.

목표

  • KinD(Kubernetes in Docker)의 특징과 사용 이유에 대해 이해한다.
  • Kind를 이용한 On-Premise 클러스터를 구축한다.

여정

KinD가 무엇인가요?

kind – Initial design (k8s.io)

  • "Kubernetes IN Docker"의 약자로, Kubernetes 클러스터를 로컬 환경에서 간편하게 생성하고 관리하기 위한 도구
  • Docker 컨테이너 내에서 Kubernetes 노드를 실행하여 클러스터를 구성

KinD 개념도(출처 : KinD 공식 문서)


왜 KinD를 사용하나요?

여러 블로그에도 비슷한 의견이겠지만 몸소 설치하고 겪으면서 느낀 바는 아래와 같다.

  1. 로컬 환경에서 개발 및 테스트를 목적으로 사용
  2. Docker 컨테이너 기반으로 Kubernetes 노드를 실행(별도 설정 없음)
  3. 경량 및 빠른 배포 (2분 이내)
  4. 다양한 시나리오를 시뮬레이션하기 위한 단일 노드 또는 다수 노드 클러스터 지원
  5. 사용자 정의 Kubernetes 버전 설정 가능

KinD 설치하기

바이너리 파일만 다운로드 받으면 되기 때문에 설정이 간편하다.

  • KinD 바이너리
  • Kubectl 바이너리(KinD로 생성한 Kubernetes 제어)
# KinD 바이너리 설치
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 && \
  chmod +x ./kind && \
  sudo mv ./kind /usr/bin

# Kubectl 바이너리 설치
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && \
  chmod +x ./kubectl && \
  sudo mv ./kubectl /usr/local/bin/kubectl

 

추가로, 일반적인 Kubernetes와 동일하게 단축어, 자동완성 설정도 적용해주면 좋다(선택사항임)

# Kubectl 단축어 및 자동완성 설정
echo 'alias k=kubectl' >>~/.bashrc && \
  sudo apt-get install bash-completion && \
  echo 'source <(kubectl completion bash)' >>~/.bashrc && \
  echo 'complete -F __start_kubectl k' >>~/.bashrc
  echo -e "you can now use kubectl with the alias k"

KinD를 이용한 Kubernetes 구축하기

KinD로 클러스터를 생성하기 위해서는 아래와 같이 Inline Command로도 쉽게 생성할 수 있다.

kind create cluster --name test-cluster

 

그러나, 이렇게 되면 Control Plane 1개만 만들어지므로 실제 사용하기 어렵다

따라서, 다음과 같은 YAML 파일로 클러스터를 정의해서 생성해주자.

# kind-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: my-cluster
nodes:
  # 버전 확인 : https://github.com/kubernetes-sigs/kind/releases
- role: control-plane
  image: kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570
  # Ingress Controller를 사용하기 위해 필요한 설정
  kubeadmConfigPatches:
    - |
      kind: InitConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"
  extraPortMappings: # 외부에서 접속할 수 있도록 포트 매핑
    # Container Port와 Node Port가 같아야 한다.
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    - containerPort: 443
      hostPort: 443
      protocol: TCP
- role: worker
  image: kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570
- role: worker
  image: kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570
- role: worker
  image: kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570

 

여기서 눈여겨 보아야 할 것은 두가지 이다.

 

첫 번째는 KinD 버전에 따른 Kubernetes 지원 버전이 다르다는 점이다.

우리가 설치한 KinD 버전이 몇인지 확인하고 설치했는가?

모르겠다면 다시 위로 올라가서 확인하고 오자.

 

이후, 공식 릴리즈(Releases · kubernetes-sigs/kind)에서 지원가능한 버전을 확인하고

레지스트리 주소를 입력해주면 된다.

 

두 번째는 Docker 환경에서 Network를 구현해놓았기 때문에 외부 노출 설정이 필요하다는 점이다.

이게 무슨 말이냐 하면 실제 컴퓨터 →  Docker → KinD ControlPlane 순으로 트래픽이 전달되어야 한다는 뜻이다.

엥? 당연한 소리 아니냐? 라고 생각할 수도 있겠지만

아래 그림을 보면 그리 간단한 이야기는 아니다.

KinD Network 개념도(출처 : https://gist.github.com/aojea/00bca6390f5f67c0a30db6acacf3ea91)

쉽게 얘기하자면,

우리가 Docker 컨테이너를 실행해도

외부 노출(expose) 설정을 하지 않으면 접근할 수 없는 것과 같다.

 

따라서, 아래 두 가지가 동일해야 한다.

  • Docker port 외부 노출(=NodePort)
  • KinD Control Plane(=ContainerPort)

그래서 Ingress를 사용하기 위해서 80, 443 포트가 필요했고

YAML 파일에 적어준 바와 같이 설정해줄 필요가 있었다.

다른 포트(8080, 5432 등)이 필요하다면 동일하게 추가해서 생성하면 된다.

(안타깝게도 수정이 안되므로 삭제 후 재생성..이 필요한 것 같다... 아니면 제보 바람!!)

  extraPortMappings: # 외부에서 접속할 수 있도록 포트 매핑
    # Container Port와 Node Port가 같아야 한다.
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    - containerPort: 443
      hostPort: 443
      protocol: TCP

추가로 Ingress 설정은 Label이 부착되어야 한다는 점을 잊지 말자!

  # Ingress Controller를 사용하기 위해 필요한 설정
  kubeadmConfigPatches:
    - |
      kind: InitConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"

 

Q & A

  • KinD의 알려진 문제들은 아래 링크에서 확인 가능하다(주로 권한을 다루는 보안문제가 많은 듯 하다.)

참고자료

쿠버네티스 엔터프라이즈 가이드

kind – Quick Start (k8s.io)

 

profile

주녁, DevNote

@junwork

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!