MSA 서비스 만들기 2
개요
이번에는 지난번에 젠킨스로 만든 이미지를 가지고, 쿠버네티스로 실행해 보겠다.
빠른 작업을 위해, 윈도우 환경에서 실행하는 점 양해부탁~
쿠버네티스 설치
윈도우에서 쿠버네티스 설치는 Docker desktop에서 간편하게 가능하다.
설정→Kubernetes로 들어간 뒤, Enable Kubernetes를 활성화해주기만 하면 된다!
쿠버네티스 설정
콘솔 접속하기
쿠버네티스가 설치되면, 콘솔창에
1
kubectl proxy
를 입력한 다음, 콘솔창을 닫지 말고 웹브라우저에서
1
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/workloads?namespace=default
여기로 접속하면 된다.
쿠버네티스 구성
본인이 쿠버네티스로 사용할 것들은 다음과 같다.
- 디플로이먼트: 실제 pod를 배포하는 곳
- 서비스: 외부와 연결시키는 곳
- 콘피그맾: 설정파일들을 모아놓는 곳
- 씨크릿: 설정파일들 중 민감정보들을 모아놓는 곳
각각 yaml 파일로 만들어서 업로드하면 되는데, yaml 파일 업로드는
웹콘솔 우측 위 쁠러스 버튼을 눌러 입력하면 된다.
디플로이먼트
디플로이먼트는 pod 실행 설정을 하는 곳이다.
즉 우리가 만들어놓은 이미지가 이 디플로이먼트를 통해 쿠버네티스 포드로 변환되어 실행되는 것이다.
yaml 작성법은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: apps/v1
kind: Deployment
metadata:
name: (디플로이먼트 이름)
spec:
replicas: 1
selector:
matchLabels:
app: (마이크로서비스 이름)
template:
metadata:
labels:
app: (마이크로서비스 이름)
spec:
containers:
- name: (이미지 이름)
image: (도커허브 아이디)/(이미지 이름):(버전)
imagePullPolicy: Always
env:
- name: SPRING_PROFILES_ACTIVE
value: (환경-dev, prod 등..)
ports:
- containerPort: 8080
위 예시는 spring boot 환경 기준인데,
1
2
3
env:
- name: SPRING_PROFILES_ACTIVE
value: dev
env가 이렇게 되어있으면 스프링부트의 환경 설정으로 application-dev.yaml를 읽는다는 것이 된다.
써비스
서비스가 무엇이냐 하면, 클러스터 밖의 서비스들을 클러스터 안에 있는 것처럼 해줄 수 있는 설정이다.
예시로 spring boot 서비스는 디플로이먼트로 pod 올려놓았는데, 해당 서비스와 연결되는 db는 클러스터 밖에 구현되어 있다.
이때 써비스를 사용해서 db 주소와 포트를 지정해 놓으면 포드들이 db를 해당 주소로 접속할 수 있게 하는 것이다.
yaml 작성법은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Service
metadata:
name: (써비스 이름)
spec:
ports:
- port: (클라스터 내에서 접속할 포트)
---
apiVersion: v1
kind: Endpoints
metadata:
name: (써비스 이름)
subsets:
- addresses:
- ip: (해당 프로그램이 실행중인 IP)
ports:
- port: (해당 프로그램이 실행중인 포트)
kind가 Service는 쿠버 내에서 사용할 환경, Endpoints는 실제 프로그램이 실행중인 환경을 작성해주면 된다.
콘피그맾
보통 config 파일은(spring boot라면 application.yaml 등) 소스코드에 넣어 놓는데, 이를 콘피그맾으로 대체할 수 있다.
yaml 파일 예시는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: v1
kind: ConfigMap
metadata:
name: (내 콘피그맾 이름)
data:
application-dev.yml: |
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://(db 써비스이름):(db 써비스포트)/(db명)?serverTimezone=UTC&useSSL=true&autoReconnect=true&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
connection-test-query: SELECT 1
validation-timeout: 5000
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
open-in-view: false
logging:
level:
com.gorae.gorae_post.api.open: DEBUG
이렇게 data: application-dev.yaml(또는 prod 등): |
아래에 소스코드의 application-dev 내용을 그대로 붙여놓기만 하면 된다.
참고로 db 접속 등을 써비스로 할 경우 써비스명과 포트 등은 kind: Service 기준으로 입력해야 한다.
씨크릿
콘피그맵맾 중 db 아이디와 비밀번호, AWS 액세스 키와 같은 중요한 정보는 따로 씨크릿으로 관리 해야 한다.
아래는 yaml 파일 예시~
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Secret
metadata:
name: (씨크릿 이름)
stringData:
application-secret.yml: |
spring:
datasource:
username: user
password: 1234
jwt:
header: Authorization
secret-key: jwtisbestjwtisbestjwtisbestjwtisbest
콘피그맾에서 중요한 정보만 따로 떼어다 동일하게 넣어주면 된다.
디플로이먼트에 콘피그맾과 씨크릿 적용하기
콘피그맾과 씨크릿을 포드에 적용하기 위해서는 추가 설정을 해줘야 한다.
디플로이먼트 yaml에 volumeMounts와 volumes를 아래처럼 추가한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
containers:
...
volumeMounts:
- name: (콘피그맾 볼륨명)
mountPath: /etc/config
readOnly: true
- name: (씨크릿 볼륨명)
mountPath: /etc/secret
readOnly: true
volumes:
- name: (콘피그맾 볼륨명)
configMap:
name: (콘피그맾 이름)
items:
- key: application-dev.yml
path: application-dev.yml
- name: (씨크릿 볼륨명)
secret:
secretName: (씨크릿 이름)
items:
- key: application-secret.yml
path: application-secret.yml
그리고 가장 중요한, 소스코드의 application-dev.yaml에
1
2
3
4
5
spring:
config:
import:
- file:/etc/config/application-dev.yml
- file:/etc/secret/application-secret.yml
이렇게 넣어 주고 이미지 빌드 해야 spring boot 프로젝트가 콘피그맾과 씨그릿에 있는 대로 환경설정을 한다!
그리고 소스코드의 application.yaml에
1
2
3
spring:
profiles:
active: local
이런 식으로 profiles: active: 설정이 되어 있으면 configmap보다 이녀석을 먼저 읽어버리기 때문에 이것도 지워줘야 한다!!
노드포트
마지막으로 외부에서 이 써비스들을 부르려면 Nodeport라는 써비스를 추가해줘야 한다.
노드포트는 쉽게 말해 톡정 포트를 전부 외부에 노출시키는 것이다.
지난 시간의 구조도처럼 spring gateway를 통해 다른 서비스들을 호출하기 때문에 spring gateway 서비스에 대한 노드포트만 추가하면 된다.
yaml 파일 예시는 다음과 같이~
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: (노드포트 이름)
spec:
type: NodePort # default는 ClusterIp
selector:
app: (대상 디플로이먼트 이름)
ports:
- protocol: TCP
port: (디플로이가 실행중인 포트)
targetPort: (디플로이가 실행중인 포트)
nodePort: (외부에 노출시킬 포트)