먼저, gcp terminal에서 편집기를 이용할 수 있다! 어제 vs code로 연결할라고 아득바득 할 필요가 없었다...
1. mysql 배포
GKE 기반 kubenertes에서 mysql을 수행하기 위해서는 pvc 생성, deploy 및 service가 필요하다.
/home/hyelie/k8s-test/mysql-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
GKE에서 1Gi의 pvc를 만들겠다는 것이다. 그냥 kubernetes만 사용하낟면 pvc, pv도 생성해야 하지만 gke이기 때문에 pvc만 생성해도 된다.
/home/hyelie/k8s-test/mysql-service.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-service
labels:
app: database
spec:
type: LoadBalancer
ports:
- port: 3306
selector:
app: mysql
tier: backend
/home/hyelie/k8s-test/mysql-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
spec:
selector:
matchLabels:
app: mysql
tier: backend
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
tier: backend
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-pw
key: rootpw
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: dbinfo
key: dbname
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: userinfo
key: username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: userinfo
key: userpw
- name: LANG
value: C.UTF-8
ports:
- containerPort: 3306
name: mysql
args:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
# mysql-root-pw : rootpw
# kubectl create secret generic mysql-root-pw --from-literal=rootpw=root
# userinfo: username, userpw
# kubectl create secret generic userinfo --from-literal=username='depuser' --from-literal=userpw='depuserpw'
# dbinfo : dbname, url
# kubectl create secret generic dbinfo --from-literal=dbname=bizschema --from-literal=url='jdbc:mysql://35.184.171.248:3306/bizschema?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnectForPools=true&serverTimezone=UTC'
# kubectl get secrets
다음으로 mysql의 service, deploy 양식을 맞춰준다. 보안을 위해 secret을 사용한다. 아래에 주석쳐져 있는 것을 각각 terminal에 입력하면 된다. 이후
$ kubectl apply -f mysql-pvc.yml -f mysql-service.yml -f mysql-deploy.yml
$ kubectl get all
을 입력하면 아래와 같은 결과가 출력된다.
service external IP도 열려있고, deploy, pod도 잘 열려있다. pod에 접속해보자.
$ kubectl exec -it [pod 이름] bash
내 경우엔 pod 이름이 mysql-deploy-85fd874857-kvl7x니까 이것을 입력해 주었다.
# mysql -u root -p root
mysql> show databases;
mysql > select user, host from mysql.user;
이렇게 입력하면, 위 사진과 같이 board라는 database가 만들어져 있고 user도 만들어져 있다.
2. local spring에서 db로 접속, CI 서버에서 build
저번에 작성한 게시판 예제의 application.properties에서, datasource url의 IP와 username, password를 수정한다.
/src/main/resources/applictaion.properties
#MySQL 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://34.71.181.183:3306/board?autoReconnect=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnectForPools=true&serverTimezone=UTC
spring.datasource.username=user1
spring.datasource.password=userpw1
#JPA
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
이렇게 하고 실행하니 아주 잘 된다. git에 push하면 미리 만들어 둔 CI 서버로 넘어간다.
/build.gradle
plugins {
id 'org.springframework.boot' version '2.5.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id "org.sonarqube" version "3.0"
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'mysql:mysql-connector-java'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
}
test {
useJUnitPlatform()
}
build.gradle에 sonar qube plugin도 넣어야 한다. 그리고 sonar qube에서는 새 프로젝트를 만들어야 할 것이다.
build가 끝났고, gcr에 내 image가 들어갔다.
3. GCR image GKE에 올리고 배포
/home/hyelie/k8s-test/spring-board.yml
apiVersion: apps/v1
kind: Deployment
metadata: # deployment의 metadata
name: spring-board-deploy
spec: # deployment의 spec
replicas: 4
selector:
matchLabels:
app: spring
tier: backend
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 2
template: # 다음 줄부터는 각각 pod의 설정
metadata:
labels: # 각 pod들의 metadata
app: spring
tier: backend
spec: # pod의 spec
containers:
- name: echo
image: gcr.io/numeric-replica-320807/boardex
ports: #
- containerPort: 8080
readinessProbe: # 로드가 너무 많아 일시적 처리 불가 상태를 확인
httpGet:
port: 8080
path: /
initialDelaySeconds: 10
failureThreshold: 5
livenessProbe: # 응답이 없으면 자동 재시작.
httpGet:
port: 8080
path: /
initialDelaySeconds: 10
failureThreshold: 5
env:
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: userinfo
key: username
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: userinfo
key: userpw
- name: SPRING_DATASOURCE_URL
valueFrom:
secretKeyRef:
name: dbinfo
key: url
---
apiVersion: v1
kind: Service
metadata: # Service의 metadata
name: spring-board-service
spec:
type: LoadBalancer
ports:
- port: 8080 # Service가 생성할 Port
targetPort: 8080 # Service가 접근할 pod의 port
selector: # Service가 접근할 pod의 label 조건
app: spring
tier: backend
secret은 앞에서 사용했던 것들이다.
$ kubectl apply -f spring-board.yml
로 실행시킨다.
1개의 mysql이 돌아가고 있고, loadbalancer가 외부 포트를 할당했으며, 입력을 4개의 pod로 나누어 주게 되었다. 이후에는 spring-board-service의 external IP로 접속해 보자.
넘모 감격스럽다.....