Kind로 로컬 쿠버네티스 클러스터 구성하고 첫 Pod 배포하기

·origin ↗
// INDEX

들어가며

쿠버네티스 (Kubernetes)는 현대 클라우드 네이티브 애플리케이션 개발에서 필수적인 도구입니다.

이번 글에서는 로컬 환경에서 쿠버네티스를 쉽게 사용해 볼 수 있는 여러 방법 중 Kind(Kubernetes IN Docker) 를 이용해 멀티 노드 클러스터를 구성하고 간단한 Go 애플리케이션을 배포해 테스트해 보도록 하겠습니다.


Kubernetes

Kubenetes 는 컨테이너 오케스트레이션 시스템의 사실상 표준입니다. kubernetes 단어의 k과 s의 사이에 8개의 알파벳이 있어 k8s로 불리기도 합니다 (이하 k8s 혹은 쿠버네티스).

운영환경에는 다양한 역할을 하는 컨테이너화된 애플리케이션이 복잡하게 얽혀 있습니다. 특히 마이크로 서비스 아키텍처로 구성된 환경의 경우 수 많은 애플리케이션이 각자의 라이프사이클을 가진다.

이렇게 복잡한 환경의 컨테이너화된 애플리케이션에 대해 배포, 스케일링, 네트워킹, 접근 관리 등 통합적인 관리를 할 수 있는 컨테이너 오케스트레이션 플랫폼이 바로 k8s입니다.

클라우드 네이티브 애플리케이션의 핵심적인 기술인 k8s는 2018 년 CNCF 인 쿠버네티스와 같은 클라우드 네이티브 기술의 발전과 표준화를 지원하는 단체의 첫 번째 졸업 프로젝트로 선정되었습니다.

클라우드 네이티브 애플리케이션은 클라우드 환경에 최적화되도록 설계되고 개발된 애플리케이션을 의미합니다.
컨테이너화된 애플리케이션, 마이크로서비스 아키텍처, 컨테이너 오케스트레이션, CI/CD 파이프라인 등의 기술을 활용하여 유연성, 확장성, 복원력을 갖춘 애플리케이션 시스템을 의미합니다.

k8s는 다음과 같은 핵심적인 기능들을 제공하여 컨테이너화된 애플리케이션의 관리를 쉽게 할 수 있도록 도와줍니다.

  • 컨테이너 관리 : k8s에서 사용되는 Pod라는 단위를 기반으로 컨테이너를 그룹화해 관리합니다.
  • 조건에 따른 자동화된 스케일링 : 사용자의 요구사항에 맞는 조건을 기준으로 애플리케이션 워크로드를 자동으로 늘리거나 줄입니다.
  • 서비스 디스커버리 및 로드 밸런싱 : 애플리케이션을 인식하고 애플리케이션 간 트래픽을 분산합니다.
  • 자동 복구 : 장애 발생 시 컨테이너를 재시작합니다.

Kind (Kubernetes IN Docker)

k8s를 구성하기 위해서는 먼저 클러스터를 생성해야 합니다.

클러스터는 k8s 가 애플리케이션을 배포하고 관리하는 기본 단위로, 컨트롤 플레인과 워크 노드들로 구성된 시스템을 의미합니다. 여러 컴퓨터를 모아 관리하는 단위로 이해할 수 있습니다.

클러스터를 생성하는 방법은 여러 가지가 존재합니다. 클라우드 환경에서 사용하는 경우 AWS EKS, Google GKE, Azure AKS와 같이 관리형 쿠버네티스 서비스를 제공하고 있습니다. 해당 서비스를 통해 쿠버네티스 클러스터를 쉽게 구성할 수 있습니다. 다만 이는 비용이 발생한다는 문제가 있습니다.

관리형 쿠버네티스 서비스가 아닌 네이티브 쿠버네티스를 구성하기 위해선 kubeadm과 같은 도구를 사용할 수 있습니다.

다만, 해당 도구를 사용해서 클러스터를 생성하고 k8s를 구성하는 과정은 복잡하고 설정이 까다로워 간단한 테스트를 진행하려는 경우에는 배보다 배꼽이 커질 수 있습니다.

이를 위해 로컬 환경에서 클러스터를 간편하게 구성할 수 있는 도구가 여러 가지 존재합니다. 대표적으로는 Minikube, Kind 등이 있으며 해당 도구들은 운영 환경 수준의 클러스터 구성이 아닌 테스트와 개발에 최적화된 간략한 방식의 클러스터 구성을 도와줍니다.

Kind는 Docker 컨테이너를 활용해 경량화된 쿠버네티스 클러스터를 빠르게 생성할 수 있도록 도와주는 오픈소스 도구입니다.

가상머신 대신 Docker 컨테이너로 노드를 시뮬레이션하기 때문에 실행 속도가 빠르고 설치가 간단합니다. 또한 여러 os를 지원하며, 단일 노드부터 멀티 노드 클러스터까지 유연하게 구성이 가능하기 때문에 개발 및 테스트 환경에서 사용할 수 있습니다.


macOS 에서 Kind로 멀티 노드 클러스터 만들기

Kind 공식문서에선 설치 및 실행 등 여러 유저 가이드를 제공하고 있습니다.

이번 과정도 해당 유저 가이드를 따라 수행합니다.

Kind를 사용하기 위해서는 docker, kubectl 이 로컬에 설치되어 있어야 합니다.


Install kind

여러 설치 방법이 있지만 두 가지 방법을 통해서 설치해 보도록 하겠습니다.

1. homebrew

homebrew 패키지 매니저를 사용하면 간편하게 설치할 수 있습니다.

brew install kind

kind --version  # kind version 0.27.0

2. go install

go 1.16 버전 이상이 설치되어 있는 경우 go install을 통해서 kind를 설치할 수 있습니다.

go install sigs.k8s.io/kind@v0.27.0

# go: downloading sigs.k8s.io/kind v0.27.0
# go: downloading al.essio.dev/pkg/shellescape v1.5.1
# go: downloading golang.org/x/sys v0.6.0
# go: downloading github.com/BurntSushi/toml v1.4.0
# go: downloading github.com/evanphx/json-patch/v5 v5.6.0
# go: downloading sigs.k8s.io/yaml v1.4.0
# go: downloading github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2

kind --version  # kind version 0.27.0

멀티 노드 클러스터 생성

Kind는 멀티 노드 클러스터 구성을 위해 설정 파일(kind-config.yaml) 작성이 필요합니다. 해당 파일은 워커 노드 2개를 가진 클러스터를 정의합니다.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

작성한 설정 파일을 이용하여 kind 클러스터를 생성합니다.

kind create cluster --config kind-config.yaml --name my-cluster

클러스터가 성공적으로 생성되면 다음과 같은 메시지를 확인할 수 있습니다.

Creating cluster "my-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.32.2)   
 ✓ Preparing nodes        
 ✓ Writing configuration   
 ✓ Starting control-plane  ️ 
 ✓ Installing CNI   
 ✓ Installing StorageClass   
 ✓ Joining worker nodes   
Set kubectl context to "kind-my-cluster"
You can now use your cluster with:

kubectl cluster-info --context kind-my-cluster

Thanks for using kind!  

클러스터 확인

다음 명령어를 통해 클러스터가 제대로 생성되었는지 확인할 수 있습니다.

kubectl cluster-info

# Kubernetes control plane is running at https://127.0.0.1:53152
# CoreDNS is running at https://127.0.0.1:53152/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

# To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


애플리케이션 실행

이제 생성된 클러스터에 애플리케이션을 띄우고 로컬에서 확인해 보도록 하겠습니다.


Pod로 애플리케이션 배포

Docker 이미지를 pull 하고 kind 클러스터로 로드합니다.

docker image pull sag0108/hivebox:0.0.1

# image load to kind
kind load docker-image sag0108/hivebox:0.0.1 --name my-cluster

해당 프로젝트에서 필요한 api 키를 Secret object로 생성합니다.

kubectl create secret generic forecast-api-secret \
    --from-literal=FORECAST_SERVICE_KEY=xxxxxxxx \
    -n hivebox

쿠버네티스의 Secret 은 비밀번호, API 키, 인증토큰 등 민감 데이터를 인코딩 된 방법으로 저장하고 Pod에 제공하기 위해 사용하는 리소스입니다.

Base64로 인코딩되어 값이 저장되며 환경변수 혹은 volume으로 Pod에 주입하여 사용할 수 있습니다.

Pod는 하나 이상의 컨테이너로 묶는 k8s의 가장 작은 배포 단위입니다. 일반적으로 하나의 Pod에 하나의 주요 컨테이너를 배포합니다.

다음은 pod 생성을 위한 manifest 파일을 다음과 같이 정의합니다.

hivebox-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hivebox
  labels:
    app: hivebox
  namespace: hivebox
spec:
  containers:
    - name: hivebox
      image: sag0108/hivebox:0.0.1
      ports:
        - containerPort: 8888
      envFrom:
        - secretRef:
            name: forecast-api-secret

kubectl apply 명령어로 manifest 파일을 옵션으로 사용하여 Pod 리소스를 생성합니다.

kubectl apply -f hivebox-pod.yaml
# pod/hivebox created

kubectl get pods -n hivebox


Service 생성하고 애플리케이션 테스트

쿠버네티스에서는 pod를 생성하는 경우 해당 애플리케이션에 접근하거나 테스트할 수 있는 방법이 없습니다.

Pod에 IP 가 할당되지만 해당 IP 는 쿠버네티스의 클러스터 내부에서만 유효한 가상 네트워크 IP 이기 때문에 외부와의 연결이 차단되어 있습니다.

로컬 네트워크는 클러스터 내부 네트워크에 직접 접근할 수 없기 때문에 외부에서 접근을 위해서 Service 오브젝트를 생성하여야 합니다.

Service 오브젝트는 쿠버네티스에서 특정 Pod 집합에 안정적이고 일관된 네트워크 진입점을 제공하는 리소스입니다.

클러스터 내부 외부에서 Pod 에 접근할 수 있도록 도와주며, Pod IP 가 되어도 도메인 이름으로 Pod 에 접근할 수 있도록 도와줍니다.

hivebox-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: hivebox-service
  namespace: hivebox
spec:
  type: ClusterIP
  selector:
    app: hivebox
  ports:
    - protocol: TCP
      port: 8888
      targetPort: 8888

그리고 kubectl apply 명령어를 사용하여 리소스를 생성합니다.

kubectl apply -f hivebox-service.yaml
# service/hivebox-service created

이후 로컬에서 접근 가능하도록 포트 포워딩합니다.

kubectl port-forward service/hivebox-service 8888:8888 -n hivebox

# Forwarding from 127.0.0.1:8888 -> 8888
# Forwarding from [::1]:8888 -> 8888

애플리케이션 테스트

이제 브라우저 혹은 curl로 http://localhost:8888/version에 요청하면 응답을 확인할 수 있습니다.


마치며

이번 글에서는 쿠버네티스의 기본 개념과 kind를 활용해 macOS 에서 멀티 노드 클러스터를 구성하고, 간단한 Go 애플리케이션을 배포하고 테스트하는 과정을 살펴보았습니다.

Kind는 간단한 설치와 설정으로 빠르게 테스트 클러스터 환경을 구축할 수 있는 장점이 있습니다.

쿠버네티스는 이미 활발하게 사용하는 기술로 10년이 넘는 시간 동안 오픈소스로 성숙된 기술입니다. 클라우드 네이티브 애플리케이션을 개발하거나 자동화된 인프라 환경을 구축하는 경우 반드시 익혀야 하는 기술입니다.

이번 시간에 간략한 실습으로 알아본 쿠버네티스에 대해 앞으로 다양한 개념과 사용 그리고 트러블슈팅 등 깊이 있는 학습을 공유하겠습니다.