Search
Duplicate
🐍

KinD: multi node 지원 개발용 Kubernetes

Category
S/W 엔지니어
Tags
kind
k8s
Created time
2023/01/07

Introduction

local 환경에서 multi node 기반의 Kubernetes Cluster를 사용을 가능하게 하는 KinD 사용법 및 관련 주요 설정에 관한 논의이다.

다루는 내용

kind가 무엇인지, 어떻게 사용하는지
kind를 이용한 로컬 환경에서의 multi-node의 Kubernetes 클러스터 구성
LoadBalancer 생성(metallb) 및 LoadBalancer 타입의 service 생성 및 동작 확인
ingress controller 생성(NGINX) 및 ingress 생성, 동작 확인

KinD란?

(아마도) Kubernetes in Docker의 약자인 듯(공식 문서에 약자 풀이가 안보임). docker 컨테이너를 k8s node로 사용하여 docker만으로도 별도의 host machine없이 k8s 클러스터를 구성할 수 있도록 하는 도구.
Kubernetes 공식 문서에서 추천하는 첫 번째 도구 : 가장 잘 알려진 minikube는 (놀랍게도) 두 번째(참조)
별도 virtual machine 요구 없음 : 오직 docker만 prerequisite임
주요 OS 모두 지원 : Linux, macOS, Windows
믿을만 함 : 원래 k8s 그 자체를 테스트하기 위해 만들어졌다고
공식 documentation : https://kind.sigs.k8s.io

사전 준비

1. Prerequisite : docker 설치

2. kind 설치

https://github.com/kubernetes-sigs/kind#installation-and-usage 참고 (Linux, macOS, Windows 모두 다 있음. 무지 간단)

3. 첨부 파일 설치

하기 첨부 파일 모두는 working directory에 위치해야 함
kind-config.yaml
kind 클러스터 생성 시 사용할 configuration 파일
k8s가 올라갈 host machine 환경에 대한 설정 - 노드 개수/타입, 네트워크
특히, 로컬에서의 테스트를 위한 전용 포트포워딩 설정이 중요
세부 설정에 대한 설명은 파일 내 comment 참조
deployment-http-echo.yaml
2개의 http echo 서버(foo, bar) 컨테이너 pod 설정
http echo 서버는 사전 설정에 따라, 호출 시 단순히 foo!, bar!를 응답
세부 설정에 대한 설명은 파일 내 comment 참조
services.yaml
상기 http echo 서버를 노출하기 위한 설정 (config type : service)
foo-service, bar-service
ClusterIP 타입(default)의 k8s 서비스
ingress를 통해 80 port로 외부에 노출됨
http-echo-service
LoadBalancer 타입의 k8s 서비스
LoadBalancer 타입 특성 상 external IP로 접근 가능하지만, macOS, Windows에서는 docker network를 host에 노출하지 않으므로 여기서는 NodePort를 통해 외부에 노출 (port : 31593.참고로 이 땜시 개고생함. NodePort로 우회하는 전략을 설명하는 문서가 전무. 오직 hint만 kind 공식 문서에 있을 뿐. macOS의 경우 docker network를 노출하는 방법이 있긴 한데, 이 문서의 prerequisite인 tuntap 설치가 macOS에서는 이제 불가)
세부 설정에 대한 설명은 파일 내 comment 참조
ingress.yaml
ingress 규칙 설정
/foo path로 호출하면 foo-service가, /bar path로 호출하면 bar-service가 서비스됨
세부 설정에 대한 설명은 파일 내 comment 참조
metallib-configmap.yaml
load balancer 설정 : 외부 노출 주소 범위를 설정하는데, linux에서만 해당 주소 범위에 접근 가능.
세부 설정에 대한 설명은 파일 내 comment 참조

k8s 클러스터, ingress controller, load balancer 설치하기

ingress controller로는 NGINX 사용
load balancer로는 metallb 사용

k8s 클러스터 생성

-config 옵션으로 클러스터 설정 파일 지정하여 생성하기 (w/ 성공 output - 3개 노드 생성됨)
> kind create cluster --config ./kind-config.yaml ... Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.21.1) 🖼 ✓ Preparing nodes 📦 📦 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 ✓ Joining worker nodes 🚜 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ ... > kubectl get nodes ... NAME STATUS ROLES AGE VERSION kind-control-plane Ready control-plane,master 18m v1.21.1 kind-worker Ready <none> 18m v1.21.1 kind-worker2 Ready <none> 18m v1.21.1 kind-worker3 Ready <none> 18m v1.21.1
Shell
복사

NGINX (ingress controller) 설치하기

ingress controller 설치를 위해서는 클러스터에 관련 설정이 요구됨(extraPortMappings, node-labels. 여기서는 위에서 이미 설정함)
1.
설치 command (w/ 성공 output)
> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml ... namespace/ingress-nginx createdserviceaccount/ingress-nginx createdserviceaccount/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx createdrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created configmap/ingress-nginx-controller created service/ingress-nginx-controller created service/ingress-nginx-controller-admission created deployment.apps/ingress-nginx-controller created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
Shell
복사
2.
내부 설정 완료 기다리기 (w/ 성공 output)
> kubectl wait --namespace ingress-nginx \ --for=condition=ready pod \ --selector=app.kubernetes.io/component=controller \ --timeout=90s ... pod/ingress-nginx-controller-bdf7bf984-vtkkc condition met
Shell
복사

Metallb (load balancer) 설치하기

1.
metallb namespace 생성하기 (w/ 성공 output)
> kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml ... namespace/metallb-system created
Shell
복사
2.
metallb manifest 적용하기 (w/ 성공 output)
> kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml ... Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+ podsecuritypolicy.policy/controller created podsecuritypolicy.policy/speaker created serviceaccount/controller created serviceaccount/speaker created clusterrole.rbac.authorization.k8s.io/metallb-system:controller created clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created role.rbac.authorization.k8s.io/config-watcher created role.rbac.authorization.k8s.io/pod-lister created role.rbac.authorization.k8s.io/controller created clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created rolebinding.rbac.authorization.k8s.io/config-watcher created rolebinding.rbac.authorization.k8s.io/pod-lister created rolebinding.rbac.authorization.k8s.io/controller created daemonset.apps/speaker createddeployment.apps/controller created
Shell
복사
3.
내부 설정 완료 기다리기 (w/ 성공 output)
> kubectl get pods -n metallb-system --watch ... NAME READY STATUS RESTARTS AGE controller-66445f859d-6pq8b 1/1 Running 0 2m1s speaker-4mk7h 1/1 Running 0 2m1s speaker-8rjd9 1/1 Running 0 2m1s speaker-dptgm 1/1 Running 0 2m1s
Bash
복사
아래부터는 Linux에서만 유의미함(macOS, Windows에서는 docker network에 접근 불가하기 때문)
4.
load balancer에서 사용하는 주소 풀 설정 (w/ 성공 output)
> docker network inspect -f '{{.IPAM.Config}}' kind ... [{172.18.0.0/16 172.18.0.1 map[]} {fc00:f853:ccd:e793::/64 fc00:f853:ccd:e793::1 map[]}]
Shell
복사
5.
상기 주소 결과로 Updatemetallb-configmap.yaml address 섹션 수정
... addresses: - 172.18.255.200-172.18.255.250 ...
YAML
복사
6.
metallb-configmap.yaml 적용 (w/ 성공 output)
> kubectl apply -f ./metallb-configmap.yaml ... configmap/config created
Shell
복사

ingress, Load balancer 테스트 준비하기

1.
http-echo 서버인 4개 pod(foo 2개, bar 2개) 생성하기 (w/ 성공 output)
> kubectl apply -f ./deployment-http-echo.yaml ... deployment.apps/foo createddeployment.apps/bar created ... > kubectl get deployments...NAME READY UP-TO-DATE AVAILABLE AGE bar 2/2 2 2 13m foo 2/2 2 2 13m ... > kubectl get pods ... NAME READY STATUS RESTARTS AGE bar-565c58bc76-lv9zn 1/1 Running 0 14m bar-565c58bc76-p2zt4 1/1 Running 0 14m foo-7d77c84f46-lcwnq 1/1 Running 0 14m foo-7d77c84f46-lh6qs 1/1 Running 0 14m
Shell
복사
2.
서비스 생성하기 (w/ 성공 output)
> kubectl apply -f services.yaml ... service/http-echo-service created service/foo-service created service/bar-service created ... > kubectl get services ... NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE bar-service ClusterIP 10.96.130.5 <none> 5000/TCP 6s foo-service ClusterIP 10.96.104.8 <none> 5000/TCP 6s http-echo-service LoadBalancer 10.96.31.254 172.18.255.200 5678:31593/TCP 6s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 49m
Shell
복사
3.
ingress rule 생성하기 (w/ 성공 output)
> kubectl apply -f ./ingress.yaml...ingress.networking.k8s.io/ingress-foobar created ... > kubectl get ingresses ... NAME CLASS HOSTS ADDRESS PORTS AGE ingress-foobar <none> * 80 6s
Shell
복사

ingress, load balancer 테스트하기

ingress 테스트

확인 대상 : L7 기반(http path)으로 routing
테스트 방법 : 테스트 동일 hostname (L4) 임에도 path가 다른 (L7) /foo, /bar로 각기 호출 및 각기 다른 결과 발생 확인
(참고) : echo.local/etc/hosts에 추가해주어야 함 : 127.0.0.1 echo.local
> curl echo.local/foo...foo!...> curl echo.local/bar...bar!
Shell
복사

load balancer 테스트

확인 대상 : load balancer의 주 미션인 부하 분산 동작
테스트 방법 : 동일 hostname:port (L4) 로 반복 호출 시 각기 다른 결과 발생 확인
for _ in {1..10}; do curl localhost:31593done...bar!foo!foo!bar!bar!bar!bar!foo!foo!bar!
Shell
복사

클러스터 삭제하기

생성 시 클러스터 name을 지정하지 않으면 default로 kind가 지정됨
> kind delete cluster...Deleting cluster "kind" ...
Shell
복사