상세 컨텐츠

본문 제목

K8s 테스트용 3tier sample

> Tech

by Ryusstory 2025. 9. 5.

본문

개요

cilium 을 공부하면서 테스트 클러스터는 vagrant 와 kind를 사용하면 대부분 테스트가 큰 무리 없이 가능했고, bgp 구성 관련해서도 쉽지는 않지만 containerlab을 사용하면 되어서 만족하고 있었다.
테스트를 하면서도 결국 올려야하는 앱이 제대로 없어서 테스트 할 때 쓸데없는 시간을 더 많이 쓰기도 했다.
그래서 frontend-backend-database 구조의 3tier 샘플 앱을 만들어봤다.

https://github.com/ryusstory/k8s-3tier-sample-clickcounter/tree/cni/kindnet

 

GitHub - ryusstory/k8s-3tier-sample-clickcounter

Contribute to ryusstory/k8s-3tier-sample-clickcounter development by creating an account on GitHub.

github.com

 

frontend와 backend 코드는 Grok의 도움을 받았고, frontend의 index.html은 Genspark의 도움을 받았다.

goal

  • 간단할 것
  • 지우고 재배포하기 쉬울 것
  • http와 grpc를 사용한 요청, database에 읽고 쓰는 기능을 포함할 것
  • 사용자의 동작 없이도 요청이 생성되도록 할 것

구성

구성도

일단 cilium hubble에서 보면 이렇게 구성된다.
처음에 cilium을 가지고 구성했지만, 범용으로 쓸 수 있을 것 같아서 cilium를 사용하지 않고 kind의 기본 kindnet으로 작성했다.

kind 구성

테스트 클러스터이다 보니 control plane과 worker 노드 두 개로 구성되어 있으며, 호스트 머신에서 bridge 네트워크를 통해 연결된다. 이는 Kind를 사용하여 로컬 환경에서 간단히 Kubernetes 클러스터를 생성하고 테스트할 수 있도록 설계된 구조이다.

앱 구조 설명

이 샘플 앱은 3-tier 아키텍처를 따르며, 다음과 같은 컴포넌트로 구성된다

Frontend

Node.js 기반의 웹 애플리케이션으로, 사용자 인터페이스를 제공한다. 포트 3000(TCP/HTTP)을 통해 접근 가능하며, 백엔드로 요청을 전달한다. 구성도에서 보듯이, HTTP와 gRPC 백엔드로 분기되어 연결된다.
configmap을 통해 backend 주소를 얻어와서 배포된다.

웹 기능 - Click Actions

웹에도 HTTP와 gRPC 클릭 버튼을 별도로 구성했다., (데이터베이스 쓰기 동작)

웹 기능 - Click History

history를 보여주는 것도 http와 grpc 를 별도로 구성했다. (데이터베이스 읽기 동작)
default는 click 후 바로 데이터베이스로부터 데이터를 읽어와서 보여주는데, 이 동작을 http로 할지 grpc로 할지 선택하는 버튼이다.

웹 기능 - Auto cron

start로 시작하면 nodejs에서 1초 정도 간격으로 랜덤하게 http와 grpc도 랜덤으로 선택해서 요청하게 된다.

Backend

두 가지 버전으로 구현되어 있다.

backend-http: HTTP 프로토콜을 사용하며, 포트 5000(TCP)으로 frontend로부터 요청을 받는다.
backend-grpc: gRPC 프로토콜을 사용하며, 포트 50051(TCP)으로 frontend로부터 요청을 받는다.
둘 다 데이터베이스(MySQL)와 연결되어 데이터를 처리한다.
데이터베이스 정보는 configmap을 통해서 전달되며, password는 secret을 적용할까 했지만 그냥 configmap으로 통일했다.

Database

kubernetes.io에서 제공하는 스테이트풀셋 mysql을 사용할까 했지만 이게 들어가면 어떻게 해도 간단하게 보이지가 않을 것 같아 단순하게 1대로 구성했다.
데이터베이스는 클릭 카운터 등의 데이터를 저장하고, 스토리지는 Rancher local-path-provisioner를 사용해서 간단하게 배포했다.


사용법

파일 구성

.
├── app
│   ├── be
│   │   ├── Dockerfile
│   │   ├── app.py
│   │   ├── click.proto
│   │   ├── click_pb2.py
│   │   ├── click_pb2_grpc.py
│   │   └── venv (생략)
│   ├── fe
│   │   ├── Dockerfile
│   │   ├── app.js
│   │   ├── click.proto
│   │   └── public
│   │       └── index.html
│   ├── k8s-be.yaml
│   ├── k8s-db.yaml
│   └── k8s-fe.yaml
├── build.sh
├── deploy.sh
└── recreate.sh

클러스터 배포

recreate.sh 실행시 아래 절차 진행

  • kind 클러스터 삭제
  • kind 클러스터 배포
  • local-path-provisioner 설치

앱 빌드

build.sh 실행시

  • app/fe 의 docker image build
  • app/be 의 docker image build
  • kind 클러스터 내에 image 업로드

kind는 load 명령어를 통해서 kind 클러스터에 이미지를 업로드 할 수 있어서, 빌드된 이미지를 각 클러스터의 노드에 넣어준다.

docker exec kind-control-plane crictl image ls 명령어로 올라간 이미지를 확인할 수 있다.
그리고, 테스트 시에 계속 앱을 다시 만들고 배포 했어서, id=3tier-app 이라는 태그를 각각 frontend와 backend 에 적용해놨다. 그래서 마지막에 kubectl delete pod -l id=3tier-app --now=true 를 실행해서 앱을 재시작 해준다.

배포

deploy.sh 실행시

  • k8s-db.yaml 배포
  • k8s-be.yaml 배포
  • k8s-fe.yaml 배포

배포시 프론트페이지는 먼저 뜨지만 mysql이 올라오기까지 시간이 걸려 클릭하더라도 에러가 나지만 기다리면 정상적으로 동작한다. init container를 넣을까 했지만 패스했다.
backend의 경우 app.py에서는 http와 grpc를 둘다 구현하고, SERVER_MODE 환경변수를 통해 http와 grpc를 전달하면 각각 프로토콜에 맞는 형태로 동작한다.


마무리

빨리 정리하고 cilium 테스트를 진행해보면서 업데이트 해야겠다.

'> Tech' 카테고리의 다른 글

Cilium:Securing gRPC 테스트  (0) 2025.09.05
kube-burner measurement 테스트  (1) 2025.08.30
kube-burner 툴 소개  (0) 2025.08.28

관련글 더보기