개요 목적
이번 시간에는 Kubenetes를 사용하여, Spring boot container image를 쉽게 배포 관리하는 방법에 대해서 알아본다.
구체적인 동작으로는 api 서버를 Minikube에 3개의 복제본으로 배포하고 Service - Load Balancing 기능을 사용해 사용자 요청을 3개의 복제본으로 고르게 분산하는 배포 환경을 만든다.
결과를 먼저 보면, /status 요청마다 3개의 각 서버의 hostname을 응답 값을 전달하여, 로드 밸런싱 기능이 잘 작동하는 것을 확인할 수 있다.
로드 밸런싱 확인 용 spring boot application 생성
로드 밸런싱 확인 method 작성
org.springframework.core.env.Environment을 빈으로 등록하여 요청이 들어오면 각 레플리카 서버의 hostname을 출력할 수 있도록 method를 만든다. kubernetes의 loadbalance기능이 잘 작동한다면 /status 요청마다 다른 response 정보를 얻게 된다.
@RestController
public class Controller {
@Autowired
Environment env;
@GetMapping("/status")
public String status() {
return "Status - returned by Pod - " + env.getProperty("HOSTNAME");
}
}
//application.yml port 정보는 5510으로 설정했다.
server:
port: 5510
docker hub에 해당 application 이미지 올리기
kubernetes가 pod으로 등록할 이미지를 dockerhub에서 다운 받아서 사용할 수 있도록 해당 application image를 dockerhub에 올린다.
- 해당 프로젝트 루트 디렉토리에 Dockerfile 생성
FROM openjdk:11.0.7-jre-slim
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar", "-Dspring.profiles.active=server", "app.jar"]
- jar 파일 생성하기
./gradlew clean build
- 도커 이미지 생성
docker build -t {dockerusername/원하는 이미지 이름:원하는 tag} .
ex) docker build -t hwangdy/load:latest .
- 도커 이미지 도커 허브에 push
docker push {만든 도커 이미지 이름}
ex) docker push hwangdy/load:latest
Deployment.yaml 구성
Kubernetes deployment이란
kubernetes에서 실행하려고 하는 application에 대한 정보를 설정한다. 앱에 사용할 이미지, 있어야 하는 pod 수, 업데이트 방법과 같은 애플리케이션의 수명 주기를 설정할 수 있다. deployment.yaml 파일은 이러한 설정 정보를 담고 있고, kubectl apply를 적용하여 kubernetes 클러스터에 적용된다.
deployment.yaml이라는 파일을 만든다. 파일의 이름은 제한이 없다.
#해당 kubernetes 객체를 생성하는 데 사용할 Kubernetes API 버전(통신 방법 명시)
#현재 쿠버네티스에서 공식적으로 제공하고 있는 deployment 객체에 대한 api는 apps/v1이다.
#쿠버네티스 API의 지속적 성장과 변경이 가능하게 만든다.
apiVersion: apps/v1
#만들려는 객체의 종류 명시
kind: Deployment
#객체를 구분해주는 name, UID, namespace 정보를 지정
metadata:
name: spring-boot-load
spec:
#운영하고 싶은 복제본 수 지정
replicas: 3
#원하는 레플리카 수를 유지 운영하기 위해, 각 pod가 어떤 명령에 속하는 pod인지 파악해야한다.
#그래서 pod을 구분해주는 label을 붙이는 spec.template.metadata.labels.app
#와 current state를 측정하기 위해 어떤 container를 counting해야 하는지를 정하는
#spec.selector.matchLabels 설정
selector:
matchLabels:
app: spring-boot-load
template:
metadata:
labels:
app: spring-boot-load
spec:
#containers: pod에서 운영할 컨테이너 정보 명시 name image exposed port
containers:
- name: spring-boot-load
image: hwangdy/load:latest
#imagePullPolicy는 container에 사용할 이미지를 어떻게 공급할 것인지 정한다.
#로컬에 있는 이미지만 사용할 것인지, 다운을 받을 것이지 옵션을 통해 정할 수 있다.
imagePullPolicy: Always
#클러스터 안에 있는 컨테이너로 통할 port를 설정
ports:
- protocol: TCP
containerPort: 5510
Service.yaml 구성
kubernetes service란 pod에서 실행되는 어플리케이션의 네트워크를 노출하는 방법을 명시한다. 기존 어플리케이션에 대한 조정 없이, 서비스로 분리하여 네트워크 설정을 할 수 있다.
service.yaml 파일 생성
# Kubernetes API version
apiVersion: v1
# Kubernetes resource kind
kind: Service
# Metadata of the resource kind
metadata:
name: spring-boot-load-svc
#서비스의 타입을 정한다.
spec:
type: LoadBalancer
#서비스가 트래픽을 전달할 pod을 설정
selector:
app: spring-boot-load
#서비스의 port 설정
ports:
- protocol: TCP
port: 5510
targetPort: 5510
nodePort: 32000
NodePort 외부에서 접속하기 위해 사용하는 포트,
port는 Cluster 내부에서 사용할 Service 객체의 포트,
targetPort service객체로 전달된 요청을 Pod(deployment)로 전달할때 사용하는 포트이다.
Deployment와 Service를 하나의 파일로 설정
kind에 List로 설정하여 하나의 yaml 파일에 deployment 설정과 service 설정을 담을 수 있다.
apiVersion: v1
#List로 설정하여 하나의 yaml 파일 안에 설정할 수 있다.
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
name: spring-boot-load-svc
spec:
type: LoadBalancer
selector:
app: spring-boot-load
ports:
- protocol: TCP
port: 5510
targetPort: 5510
nodePort: 32000
- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-load
spec:
replicas: 3
selector:
matchLabels:
app: spring-boot-load
template:
metadata:
labels:
app: spring-boot-load
spec:
containers:
- name: spring-boot-load
image: hwangdy/load:latest
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 5510
Deployment, Service 작동 - 결과 확인
해당 yaml파일이 잇는 디렉토리에 이동하여 deployment.yaml과 service.yaml를 cluster에 적용한다.
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
deployment와 service, pod 동작하는 지 확인
- kubectl get all 한번에 확인할 수 있고
- get service, pod, deployment로 개별 적 확인이 가능하다.
- kubeclt logs [pod name] 으로 실행 중인 spring boot application log를 확인할 수 있다.
minikube tunnel을 통해 로드 밸런싱 기능 확인(Postman)
minikube tunnel 명령어를 통해LoadBalancer 유형으로 배포된 서비스에 대한 경로를 생성하여 로드 밸런싱 서비스를 테스트할 수 있다.
서비스의 External IP가 생성된 것을 확인할 수 있다.
minikube tunnel
이제 위에서 먼저 알린 postman 결과처럼 connection keep-alive header을 제거하고 http://127.0.0.1:5510/status 요청으로 보내게 되면 요청 마다 새로운 host 정보를 response하는 것을 확인할 수 있다.(로드 밸런싱이 잘 이루어지고 있음)
'리눅스 인프라 > Docker, Jenkins, Kubernates' 카테고리의 다른 글
GitOps에 대한 이해와 ArgoCD를 이용한 SpringBoot 배포 방법 (0) | 2023.06.25 |
---|---|
AWS VPC에 대한 이해와 VPC 내 private 통신하기 (0) | 2023.06.25 |
kubernetes 구성 요소에 대한 이해 (0) | 2023.06.08 |
Spring boot(gradle) docker container 배포, docker-compose적용 (0) | 2023.05.30 |
docker, compose, swarm에 대한 이해 (0) | 2023.05.30 |