구축 환경

  • Mac Apple Sillicon (arm64)

  • 기존 docker-compose.yaml 파일을 k8s 클러스터 구성하기 위한 yaml 파일로 convert하기 위해 kompose 툴 사용

brew install kompose
kompose convert -f docker-compose.yml --out converted.yaml

converted.yaml

  • minikube, 위의 converted.yaml 활용하여 로컬에 k8s 클러스터 구축

minikube 사용하여 기존 Kafka Application 구축

minikube 설치

brew install minikube

minikube 클러스터 시작

minikube start

(설치하고나면 ~/.kube/config 파일에 클러스터와 컨텍스트 관련 정보 자동으로 설정 완료)

(option) 사용할 Namespace 설정

kubectl create ns kafka-app
kubectl config set-context --current --namespace=kafka-app

로컬 image 사용하도록 설정

Registry에 올리지 않은, 로컬에만 있는 image를 사용하기 위해서는 다음과 같은 커맨드 실행이 필요하다.

기본적으로 yaml에 명시되어있는 이미지는 로컬에 있는것부터 참조 후 없으면 Registry에서 찾는다. 그런데 로컬에 뻔히 있는데도 minikube는 그것을 알지 못하여 Registry에서 찾으려고시도 후 결국 찾지 못해 Pod를 생성해내지 못하는 에러가 발생한다.

minikube가 로컬에있는 image를 참조할 수 있도록 아래 명령어 실행.

eval $(minikube docker-env)

yaml 파일로 k8s 리소스 생성

kubectl apply -f converted.yaml

생성된 리소스

  • zookeeper

  • kafka

  • kafka-ui 관련 Deployment

  • Service

빌드 되어있는 jar파일 → Docker image

Gradle로 빌드하여 생성된 Spring Boot 애플리케이션 jar파일 → docker image로 변환

Dockerfile 코드
# 베이스 이미지를 지정
# 이미지가 로컬에 존재하지 않을 경우에만 다운로드
# 이미지가 로컬에 있을 경우에는 다시 다운로드 X
FROM arm64v8/openjdk:11-jdk-slim@sha256:482a519d80f99a32117003a369c14fdc180c3175ca3ee8b2bf659b9de05cf53b

# 작업 디렉토리를 설정
WORKDIR /app

# 호스트의 JAR 파일을 Docker 이미지로 복사
COPY build/libs/kafka-chat-0.0.1-SNAPSHOT.jar /app/kafka-chat-0.0.1-SNAPSHOT.jar

# 어플리케이션을 실행
CMD ["java", "-jar", "kafka-chat-0.0.1-SNAPSHOT.jar"]
# Dockerfile이 있는 경로에서
# [usage] docker build -t {생성할 image 명}:{지정할 tag 혹은 버전정보} .
docker build -t my-spring-application:0.0.14 .

리소스 생성 확인

minikube dashboard

→ Output URL 접속하여 생성된 k8s 리소스 확인

(화면상단 Namespace 확인)

(화면상단 Namespace 확인)

로그 확인

kubectl logs pod/kafka-ui-57f44b6bb8-cgwzq

네트워크 연결 체크 - 특정 pod에서 다른 pod로 통신 되는지 확인

# Pod(ex: kafka-ui) 접속
kubectl exec -it pod/kafka-ui-57f44b6bb8-cgwzq -- sh

# netcat 설치
apk update && apk add netcat-openbsd

# 다른 Pod(kafka server)로의 통신 체크
# [usage] nc -zv {수신 target container IP} {open 되어있는지 확인하고자 하는 port}
nc -zv 10.244.0.74 9092
Success case → Connection to 10.244.0.74 9092 port [tcp/*] succeeded!
Fail case → connect to 10.244.0.74 port 9094 (tcp) failed: Connection refused 
  • -z 옵션은 데이터를 보내지 않고 연결만 시도

  • -v 옵션은 자세한 출력(Verbose)을 활성화하여 연결 과정을 출력

minikube 특정 서비스 외부접속허용(로컬에서 접속할 수 있도록)

# minikube 클러스터 내 특정 서비스 <--> local 터널링 (새로운 port 생성되며 해당 포트에서 터널링)
minikube service kafka-ui --url --namespace {애플리케이션 구성되어있는 네임스페이스이름}

# OR # minikube 클러스터 내 전체 서비스 <--> local 터널링 (새로운 port 생성되며 해당 포트에서 터널링)
minikube service --all --namespace {애플리케이션 구성되어있는 네임스페이스이름}

# (option) 위 과정으로 생성된 포트 확인(위 명령으로 확인된 포트와 일치하는지 확인), 다른 터미널에서 실행
ps -ef | grep [email protected]

# 브라우저에서 접속

Pod > Application log check

# 스프링 부트 애플리케이션 pod로 접속
kubectl exec -it pod/spring-boot-application-647647954d-g9rxp -- sh

# curl 설치
apt-get update && apt-get install -y curl

# 리스닝하고있는 포트 확인하기 위해 net-tools 설치
apt-get install -y net-tools

# 리스닝하고있는 포트 확인
netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
## 8080포트를 리스닝 확인

# 다른터미널에서 스프링 부트 애플리케이션 pod 로그확인
kubectl logs -f spring-boot-application-647647954d-g9rxp

curl --location 'http://localhost:8080/kafka/send/message' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'message=kafka chat sample'