05D. Spring Boot Docker ์ด๋ฏธ์ง์ ๋ํ๋ก์ด๋จผํธ ์์ฑํ๊ธฐ
05D. Spring Boot Docker ์ด๋ฏธ์ง์ ๋ํ๋ก์ด๋จผํธ ์์ฑํ๊ธฐ ๊ด๋ จ
์ด์ Spring Boot Docker ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๊ฒ ์ต๋๋ค. Spring Boot ํ๋ก์ ํธ ์์ฑ ๋ถ๋ถ์ ๋ค์ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋ฐ๋๋๋ค.
์์ค ์ฝ๋๋ ๋ค์ GitHub ์ ์ฅ์์์ ๋ฐ์ ์ ์์ต๋๋ค.
์์ค ์ฝ๋๋ฅผ ๋ฐ์ ๋ค Unit05/initial
ํด๋๋ก ์ด๋ํ์ฌ Docker ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค.
- GitHub Packages ๋ ์ง์คํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํ์ผ๋ฏ๋ก ํ๊ทธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ ํ์์ผ๋ก ์ง์ ํฉ๋๋ค.
ghcr.io/<GitHub ๊ณ์ >/spring-boot
cd jHLsKubernetes/Unit05/initial
sudo docker build --tag ghcr.io/<GitHub ๊ณ์ >/spring-boot .
cd jHLsKubernetes/Unit05/initial
docker build --tag ghcr.io/<GitHub ๊ณ์ >/spring-boot .
๊ทธ๋ฆฌ๊ณ docker push
๋ช
๋ น์ผ๋ก ์ด๋ฏธ์ง๋ฅผ GitHub Packages ๋ ์ง์คํธ๋ฆฌ์ ํธ์ํฉ๋๋ค.
sudo docker push ghcr.io/<GitHub ๊ณ์ >/spring-boot:latest
๋ค์ ๋ด์ฉ์ spring-boot-deployment.yaml
ํ์ผ๋ก ์ ์ฅํฉ๋๋ค.
spring-boot-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot
spec:
replicas: 1
selector:
matchLabels:
app: spring-boot
template:
metadata:
labels:
app: spring-boot
spec:
containers:
- name: spring-boot
image: ghcr.io/<GitHub ๊ณ์ >/spring-boot:latest
ports:
- containerPort: 8080
env:
- name: MYSQL_HOST
value: mysql
imagePullSecrets:
- name: ghcr-cred
.apiVersion
: ํ์ฌ ๋ํ๋ก์ด๋จผํธ์ ๋ฒ์ ์apps/v1
์ ๋๋ค..kind
: ๋ํ๋ก์ด๋จผํธ๋ฅผ ์์ฑํ๋ฏ๋กDeployment
๋ฅผ ์ง์ ํฉ๋๋ค..metadata.name
: ํ์ฌ ๋ํ๋ก์ด๋จผํธ์ ์ด๋ฆ์ ๋๋ค. ์ฌ๊ธฐ์๋spring-boot
๋ฅผ ์ค์ ํฉ๋๋ค..spec.replicas
: ํ๋๋ฅผ 1๊ฐ๋ง ์์ฑํฉ๋๋ค..spec.selector
: ๋ํ๋ก์ด๋จผํธ๊ฐ ๊ด๋ฆฌํ ํ๋๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค. ์ฌ๊ธฐ์๋matchLabels
์spring-boot
๋ก ์ค์ ํ์ผ๋ฏ๋ก ํค๊ฐapp
, ๊ฐ์ดspring-boot
๋ก ์ ํํ ์ผ์นํ๋ ํ๋๋ฅผ ์ฐพ์ต๋๋ค..spec.template
: ์ฌ๊ธฐ์๋ถํฐ ํ๋ ์ค์ ์ ๋๋ค.metadata
:labels
์ ํค-๊ฐ์ ์ค์ ํ์ฌ ๋ํ๋ก์ด๋จผํธ๊ฐ ์ฐพ์ ์ ์๋๋ก ํฉ๋๋ค. ์ฌ๊ธฐ์๋app: spring-boot
๋ฅผ ์ค์ ํ์ต๋๋ค.spec
: ํ๋์spec
์ ๋๋ค. ํ๋์๋ ์ปจํ ์ด๋๊ฐ ์ฌ๋ฌ ๊ฐ ๋ค์ด๊ฐ ์ ์์ด์containers
๋ก ๋์ด์๊ณ , ๊ทธ ์๋์๋-
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด(Array)๋ก ๊ฐ์ ์ค์ ํฉ๋๋ค.containers
:name
์๋ ์ปจํ ์ด๋์ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค. ์ฌ๊ธฐ์๋spring-boot
๋ก ์ค์ ํ์ง๋ง ์ ๋ ํฐ์๋ ์๊ด์ด ์์ต๋๋ค.image
์๋ ์ปจํ ์ด๋๋ฅผ ์คํํ Docker ์ด๋ฏธ์ง๋ฅผ ์ค์ ํฉ๋๋ค.<์ด๋ฏธ์ง>:<ํ๊ทธ>
ํ์์ด๋ฉฐ ์ฌ๊ธฐ์๋ghcr.io/<GitHub ๊ณ์ >/spring-boot:latest
์ ์ค์ ํ์ต๋๋ค. <GitHub ๊ณ์ > ๋ถ๋ถ์ ๋ฐ๋์ ๋ณธ์ธ์ GitHub ๊ณ์ ์ผ๋ก ์์ ํด์ค๋๋ค.ports
: ๋ฐฐ์ด ํํ๋กcontainerPort
๋ฅผ ์ค์ ํฉ๋๋ค.containerPort
๋ ์ปจํ ์ด๋์์ ๊ฐ๋ฐฉํ ํฌํธ ๋ฒํธ๋ฅผ ๋ปํฉ๋๋ค. ์ฌ๊ธฐ์๋ Spring Boot์ ํฌํธ์ธ 8080์ ์ค์ ํ์ต๋๋ค.env
: ํ๊ฒฝ ๋ณ์์ ๋๋ค. ๋ฐฐ์ด ํํ๋ก ์ค์ ํ๋ฉฐname
,value
ํ์์ ๋๋ค. ์ฌ๊ธฐ์๋MYSQL_HOST
์mysql
๋ฅผ ์ค์ ํ์ฌ ์คํ ์ดํธํ์ ์ ์ฐ๊ฒฐ๋ ์๋น์ค์ ์ ๊ทผํ๋๋ก ํฉ๋๋ค.
imagePullSecrets
: GitHub Packages ๋ ์ง์คํธ๋ฆฌ์ ์ ๊ทผํ๊ธฐ ์ํ ์ํฌ๋ฆฟ์ ๋๋ค.ghcr-cred
์ํฌ๋ฆฟ์ ๋ค์์ ๋ง๋ค๊ฒ ์ต๋๋ค.
์ด์ ๋ค์ ๋ช
๋ น์ผ๋ก ghcr-cred
์ํฌ๋ฆฟ์ ์์ฑํฉ๋๋ค.
kubectl create secret docker-registry ghcr-cred \
--docker-server=ghcr.io \
--docker-username=<GitHub ๊ณ์ > \
--docker-password=<Personal Access Token>
์ํฌ๋ฆฟ ์์ฑ์ด ๋๋ฌ์ผ๋ฉด Spring Boot ๋ํ๋ก์ด๋จผํธ๋ฅผ ์์ฑํด๋ด ๋๋ค.
kubectl create -f spring-boot-deployment.yaml
kubectl get all
๋ช
๋ น์ผ๋ก ์ค๋ธ์ ํธ ๋ชฉ๋ก์ ์ถ๋ ฅํด๋ณด๋ฉด ๋ํ๋ก์ด๋จผํธ, ๋ ํ๋ฆฌ์นด์
, ํ๋๊ฐ ์์ฑ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
kubectl get all
#
# NAME READY STATUS RESTARTS AGE
# pod/mysql-0 1/1 Running 0 4h51m
# pod/spring-boot-85cc99859d-mpq28 1/1 Running 0 5s
#
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d2h
# service/mysql ClusterIP None <none> 3306/TCP 6h30m
#
# NAME READY UP-TO-DATE AVAILABLE AGE
# deployment.apps/spring-boot 1/1 1 1 6s
#
# NAME DESIRED CURRENT READY AGE
# replicaset.apps/spring-boot-85cc99859d 1 1 1 6s
#
# NAME READY AGE
# statefulset.apps/mysql 1/1 4h51m
์ด์ Spring Boot ์๋น์ค์
๋๋ค. ๋ค์ ๋ด์ฉ์ spring-boot-service.yaml
ํ์ผ๋ก ์ ์ฅํฉ๋๋ค.
spring-boot-service.yaml
apiVersion: v1
kind: Service
metadata:
name: spring-boot
spec:
selector:
app: spring-boot
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
.apiVersion
: ํ์ฌ ์๋น์ค์ ๋ฒ์ ์v1
์ ๋๋ค..kind
: ์ฌ๊ธฐ์๋ ์๋น์ค๋ฅผ ์์ฑํ๋ฏ๋กService
๋ฅผ ์ง์ ํฉ๋๋ค..metadata.name
: ํ์ฌ ์๋น์ค์ ์ด๋ฆ์ ๋๋ค. ์ฌ๊ธฐ์๋spring-boot
๋ฅผ ์ค์ ํฉ๋๋ค..spec.selector
: ์๋น์ค๊ฐ ํธ๋ํฝ์ ์ ๋ฌํ ํ๋๋ฅผ ์ ํํฉ๋๋ค. ์ฌ๊ธฐ์๋app: spring-boot
์ ์ค์ ํ์ผ๋ฏ๋ก ํค๊ฐapp
, ๊ฐ์ดspring-boot
์ธ ํ๋๋ฅผ ์ฐพ์ต๋๋ค..spec.ports
:protocol
์ TCP,port
๋ ์๋น์ค๊ฐ ๊ฐ๋ฐฉํ ํฌํธ์ด๋ฉฐ 8080์ผ๋ก ์ค์ ํฉ๋๋ค.targetPort
๋ ํ๋์ ์ด๋ ค ์๋ ํฌํธ๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ฐ๋ผ์ 8080์ ์ค์ ํฉ๋๋ค..spec.type
: ์๋น์ค์type
์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ง๋ง ์ฌ๊ธฐ์๋ClusterIP
๋ฅผ ์ค์ ํ์ฌ ์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํฌ ์์์๋ง ํฌํธ๋ฅผ ๋ ธ์ถํ๋๋ก ํฉ๋๋ค.
๋ค์ ๋ช ๋ น์ผ๋ก Spring Boot ์๋น์ค๋ฅผ ์์ฑํฉ๋๋ค.
kubectl create -f spring-boot-service.yaml
kubectl get all
๋ช
๋ น์ผ๋ก ์ค๋ธ์ ํธ ๋ชฉ๋ก์ ์ถ๋ ฅํด๋ณด๋ฉด ์๋น์ค๊ฐ ์์ฑ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
kubectl get all
#
# NAME READY STATUS RESTARTS AGE
# pod/mysql-0 1/1 Running 0 5h
# pod/spring-boot-85cc99859d-mpq28 1/1 Running 0 9m17s
#
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d3h
# service/mysql ClusterIP None <none> 3306/TCP 6h39m
# service/spring-boot ClusterIP 10.111.229.189 <none> 8080/TCP 6s
#
# NAME READY UP-TO-DATE AVAILABLE AGE
# deployment.apps/spring-boot 1/1 1 1 9m18s
#
# NAME DESIRED CURRENT READY AGE
# replicaset.apps/spring-boot-85cc99859d 1 1 1 9m18s
#
# NAME READY AGE
# statefulset.apps/mysql 1/1 5h
๊ทธ๋ผ kubectl
์ port-forward
๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ์๋น์ค์ ์ ๊ทผํด๋ณด๊ฒ ์ต๋๋ค.
kubectl port-forward service/spring-boot 8080:8080
#
# Forwarding from 127.0.0.1:8080 -> 8080
# Forwarding from [::1]:8080 -> 8080
์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด๊ณ http://127.0.0.1:8080
์ ์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ด์ฉ์ด ํ์๋ฉ๋๋ค(์๋ก ๊ณ ์นจํ๋ฉด ๋ฐ์ดํฐ๊ฐ ๊ณ์ ๋์ ๋์ ํ์๋ ๊ฒ์
๋๋ค).
[{"id":1,"name":"hello","email":"hello@world.com"}]
์ด๋ ๊ฒ MySQL ์คํ ์ดํธํ์ ์ ์์ฑํ๊ณ Spring Boot ๋ํ๋ก์ด๋จผํธ(ํ๋)์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์์ต๋๋ค.
Minikube ํด๋ฌ์คํฐ ์ ์ง, ์ญ์
MiniKube ํด๋ฌ์คํฐ๋ฅผ ์ ์งํ๋ ค๋ฉด minikube stop
๋ช
๋ น์ ์คํํฉ๋๋ค.
minikube stop
์ ์ง๋ Minikube ํด๋ฌ์คํฐ๋ minikube start
๋ช
๋ น์ผ๋ก ๋ค์ ์์ํ ์ ์์ต๋๋ค.
minikube start
ํด๋ฌ์คํฐ๋ฅผ ์ญ์ ํ๊ณ ์ถ๋ค๋ฉด minikube delete
๋ช
๋ น์ ์คํํ๋ฉด ๋ฉ๋๋ค.
minikube delete
์ฐธ๊ณ ๋ก ์๋์ฐ์์ ์ ๋ช ๋ น์ ์คํํ๋ ค๋ฉด PowerShell ๋๋ ๋ช ๋ น ํ๋กฌํํธ๋ฅผ ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ์คํํ์ฌ์ผ ํฉ๋๋ค.