다음 프로젝트를 쿠버네티스로 배포해보고자 계획중
여기서 한가지 고민이 생겼는데
스프링부트 애플리케이션 deployment-replica 2 / 데이터베이스 deployment-replica 1를 구성한다고 했을 때
과연 스프링부트 애플리케이션에 datasource정보를 어떻게 전달할것인가?
- 3개의 워커노드를 활용한다고 했을 때 나는 데이터베이스파드가 어디에 생성될지 예측할 수 없다.
- 물론 무조건 데이터베이스를 먼저 띄우고 매번 수정해서 애플리케이션을 띄울 순 있겠지만.. 이는 근본적인 해결법이 아니라고 생각
- 추가로 db컨테이너가 어디에 뜰 지 지정해줄 수 있다면 데이터베이스 컨테이너가 스프링부트 애플리케이션보다 늦게 뜨는건 restart always를 통해 해결할 수 있다고 생각
해결법
쿠버네티스는 파드와 서비스를 위한 DNS 레코드를 생성한다. 사용자는 IP 주소 대신에 일관된 DNS 네임을 통해서 서비스에 접속할 수 있다
파드에서 다른 파드와의 통신을 위해서는 쿠버네티스의 DNS 구조에 따라 metadata.name 의 값을 hostname으로 사용하게되는데,
이를 정의하여파드의 IP를 입력하지 않아도 DNS에서 hostname에 대한 IP를 반환하게 되어 통신이 가능하도록 할 수 있다.
예시
예를들어 springboot-application yaml or properties에 아래처럼 변수를 사용한다면
상황 :
해결법
쿠버네티스는 파드와 서비스를 위한 DNS 레코드를 생성한다. 사용자는 IP 주소 대신에 일관된 DNS 네임을 통해서 서비스에 접속할 수 있다
DNS에서 hostname에 대한 IP를 반환
하게 되어 통신이 가능하도록 할 수 있다.예시
DNS에서 hostname에 대한 IP를 반환
하게 되어 통신이 가능apiVersion: v1 kind: Service metadata: annotations: kompose.cmd: kompose convert kompose.version: 1.26.0 (HEAD) creationTimestamp: null labels: io.kompose.service: mongodb name: mongodb spec: ports:
A service의 hostname은 기본적으로 service or deployment yaml에서 정의한 metadata.name을 활용한다 즉 이 hostname이 ip를 대신하여 파드간 소통에 사용될 수 있다.
ex)
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://{mysql}:3306/xxx
....