spring boot - certmanager를 통해 http2 설정 및 테스트 (2/2)
개요
이전 문서에서 쿠버네티스 환경에 cert-manager를 설치해서 환경구성을 완료했다면, 이번 문서에서는 spring boot
환경 구성 및 테스트까지 알아 볼 수 있도록 합니다.
준비
http2 테스트를 위해선 다음과 같은 테스트 환경이 필요합니다.
- key, crt 파일
- 해당 파일은 이전 문서에서 진행 후 생성된 secrets에서 추출합니다.
- 테스트용 API 서버
- Spring Boot로 간단하게 환경구성 합니다.
- kubernetes 환경에 배포를 위해 Dockerfile 과 deployment, service yaml 까지 준비합니다.
spring boot 서버 기본 구성은 아래와 같이 진행했습니다.
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.11'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.example'
version = '0.0.1'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("/test")
public String getTest() {
return "test";
}
}
방법
로컬 테스트
인증파일 추출
cert-manager를 통해 생성된 secrets 파일을 보면 ca.crt, tls.crt, tls.key 파일이 있습니다. 이 중, tls.crt, tls.key 파일을 추출해보도록 합니다.
secrets 파일을 json 형식으로 읽은 뒤, data.tls.key(crt)를 가져온 다음, 인코딩된 base64를 디코딩 한 다음, 파일로 만드는 명령어 입니다.
# tls.key
kubectl get secrets selfsigned-cert-tls -o jsonpath='{.data.tls\.key}' | base64 --decode >> tls.key
# tls.crt
kubectl get secrets selfsigned-cert-tls -o jsonpath='{.data.tls\.crt}' | base64 --decode >> tls.crt
추출된 파일은 spring boot로 만든 서버 중 원하는 경로 또는 관리하는 경로에 위치시켜 주도록 합니다.
이번 문서에서는 classpath 경로인 src/main/resources 하위에 위치시키도록 합니다.
application.yaml
http2 설정을 위해 application.yaml에 설정을 추가 및 tls.key, tls.crt 파일의 경로를 잡아줘야 합니다.
server:
ssl:
enabled: true
certificate: classpath:tls.crt
certificate-private-key: classpath:tls.key
http2:
enabled: true
테스트 진행
서버를 실행 하고나서, 브라우저에서 API를 호출 하면 다음과 같은 사실을 알아낼 수 있습니다.
- https 실행
- h2(http2) 프로토콜 실행
쿠버네티스 테스트
Dockerfile 생성
쿠버네티스 배포를 위해 먼저 컨테이너 이미지를 만들 수 있도록 Dockerfile를 작성합니다.
build/libs 하위에 있는 jar를 파일을 찾아 app.jar 파일로 복사하여 실행할 수 있도록 합니다.
FROM eclipse-temurin:11.0.16.1_1-jdk
ENV TZ=Asia/Seoul
#COPY ./target/*.jar app.jar
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
jar 생성
Dockerfile을 통해 이미지에 jar파일을 복사하기 위해 동작할 수 있는 jar파일을 생성해야 합니다.
gradle 기준으로 다음과 같습니다.
gradle clean bootJar
image 빌드
Dockerfile과 jar파일까지 준비 되었으면, 이미지를 빌드 할 수 있도록 합니다.
docker build -t http2-test:0.0.1 .
deployment, service yaml 작성
쿠버네티스에 배포하기 위한 deployment와 배포된 pod에 접근하기 위한 service를 생성할 수 있는 yaml을 작성합니다.
deployment.yaml
yaml 작성 시 이전 문서에서 진행된 cert-manager를 통해 만들어진 secrets를 volumeMount하여 컨테이너 내부에 마운트 할 수 있도록 작성합니다. 마운트된 파일은 환경변수를 통해서 매핑할 수 있도록 합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: http2-test-deployment
labels:
app.kubernetes.io/name: spring
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: spring
template:
metadata:
labels:
app.kubernetes.io/name: spring
spec:
containers:
- name: http2-test
# 로컬에서 빌드한 이미지를 작성하면 된다.
image: http2-test:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: spring-port
# 인증서 파일을 매핑하는 환경변수
env:
- name: SERVER_SSL_CERTIFICATE
value: /etc/secret-volume/tls.crt
- name: SERVER_SSL_CERTIFICATE-PRIVATE-KEY
value: /etc/secret-volume/tls.key
# secrets에 있는 인증서를 특정 디렉토리에 마운트
volumeMounts:
- name: tls-secret-volume
mountPath: /etc/secret-volume
# secrets에 있는 인증서를 특정 디렉토리에 마운트하기 위해 볼륨 설정
volumes:
- name: tls-secret-volume
secret:
# cert-manager에 인증서 설정하면서 생긴 secrets명
secretName: selfsigned-cert-tls
작성 완료된 yaml은 배포할 수 있도록 합니다.
kubectl apply -f deployment.yaml
service.yaml
deployment.yaml에서 작성한 container port와 label selector를 잘 맞춰서 작성해주도록 합니다.
NodePort로 타입을 지정하여 pod에 접근 할 수 있도록 합니다.
apiVersion: v1
kind: Service
metadata:
name: http2-test-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: spring
ports:
- protocol: TCP
port: 8080
targetPort: spring-port
name: http2-test-port
작성 완료된 yaml은 배포할 수 있도록 합니다.
kubectl apply -f service.yaml
테스트
정상적으로 배포가 완료 되었다면 다음과 같이 실행하는 모습을 확인할 수 있습니다.
이제, NodePort로 생성된 port를 통해 접근하여, https와 http2 프로토콜이 정상적으로 적용되었는지 확인할 수 있도록 합니다.
정상적으로 동작하는 것을 확인할 수 있습니다.
또한, deployment.yaml에서 volumeMount 이용하여 인증파일을 마운트 한 것은 다음과 같이 pod에 직접적으로 접근하여 확인할 수 있습니다.
kubectl exec -it {pod명} -- bash
# pod 내부에서
cd /etc/secret-volume
ls
예제코드는 아래 깃허브 주소 링크를 참고하시면 됩니다.
https://github.com/devy1540/http2-test
이것으로 cert-manager를 통해 spring boot http2 설정 및 테스트에 대해 알아봤습니다.
감사합니다.