๐ŸšขGKE [๐ŸƒWAS ์•ฑ ๋ฐฐํฌ(SpringBoot) & ๐ŸšจํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…]

๊น€์„ฑ์ธยท2023๋…„ 10์›” 13์ผ
1

[DevOps] ๐ŸณDocker & Kubernetes

๋ชฉ๋ก ๋ณด๊ธฐ
29/62

์ฒซ๋ฒˆ์งธ ManifestFile

Deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jpapractice-deployment
spec:
  replicas: 3  # Set the desired number of replicas
  selector:
    matchLabels:
      app: jpapractice
  template:
    metadata:
      labels:
        app: jpapractice
    spec:
      containers:
        - name: jpapractice
          image: adultkim/jpapractice:latest  # Your Spring Boot application image
          ports:
            - containerPort: 8081  # Port your Spring Boot application is running on

Service.yaml

apiVersion: v1
kind: Service
metadata:
  name: jpapractice-service
spec:
  selector:
    app: jpapractice
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8081  # Port your Spring Boot application is running on
  type: LoadBalancer

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jpapractice-ingress
spec:
  rules:
    - host: insung-jpadocker.store  # ์‹ค์ œ ๋„๋ฉ”์ธ ์„ค์ •
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: jpapractice-service
                port:
                  number: 80

๋ฌธ์ œ์  ํ™•์ธ

์•„๋ฌด๋ฆฌ ์‹คํ–‰ํ•ด๋„ ์™ธ๋ถ€์—์„œ ์ ‘์†์ด ์•ˆ๋˜๊ณ , ๋„ˆ๋ฌด ๋‹ต๋‹ตํ–ˆ์—ˆ๋‹ค..
1. ์šฐ์„  pod์— ์ด์–ด์ง€๋Š” ํฌํŠธ ์„ค์ •์„ 8080์œผ๋กœ ์‹œ์ž‘ํ–ˆ์—ˆ๋Š”๋ฐ, application ์„ค์ •์„ 8081๋ฒˆ์œผ๋กœ ํฌํŠธ ์ง€์ •์„ ํ•ด๋†”์„œ ๊ณ ์ณค์Œ.

  1. ์ฒ˜์Œ์— ingress ํŒŒ์ผ์— host๋ฅผ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์•˜๋Š”๋ฐ ๊ทธ๊ฒƒ ๋•Œ๋ฌธ์ธ๊ฐ€? ๋ผ๋Š” ๊ณ ๋ฏผ๋„ ํ•ด์„œ, ์›๋ž˜ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ DNS๋ฅผ ์šฐ์„  ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค. (์•„์ง IPํ• ๋‹น์€ ํ•  ์ค„ ๋ชฐ๋ž์Œ)

ํ•ด๊ฒฐ์‹œ๋„

  1. host์˜ ๋„๋ฉ”์ธ ์ฃผ์†Œ๋ฅผ IP ์„œ๋น„์Šค์—์„œ ์—ฐ๊ฒฐํ•˜๊ธฐ์œ„ํ•ด์„œ ์„œ๋น„์Šค์˜ ์™ธ๋ถ€ IP ์ฃผ์†Œ๋ฅผ ํ™•์ธํ•˜์˜€๋‹ค.
    kubectl get svc jpapractice-service
  2. IP ์ฃผ์†Œ๋ฅผ ํ™•์ธํ–ˆ๊ณ  DNS ์„œ๋น„์Šค์—์„œ DNS์ฃผ์†Œ์— IP์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•ด์ฃผ์—ˆ๋‹ค.
  3. curl http://insung-jpadocker.store ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ ์š”์ฒญํ™•์ธ์„ ํ–ˆ๋Š”๋ฐ, ์ปค๋„ฅ์…˜ ํƒ€์ž„์•„์›ƒ์ด ๋– ๋ฒ„๋ฆผ..
curl http://insung-jpadocker.store
curl: (7) Failed to connect to insung-jpadocker.store port 80: Connection refused

์—ฌ๊ธฐ์„œ Ingress ๋ฆฌ์†Œ์Šค๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ƒ์„ฑ๋˜์ง€ ์•Š์€๊ฑด๊ฐ€..? ๋™์ž‘์ด ์ž˜๋ชป๋œ๊ฑด๊ฐ€ ํ•ด์„œ ๋‹ค์‹œ ํ™•์ธ ํ•ด๋ด๋„ ๋ฌธ์ œ์—†์Œ..
kubectl get ingress -> ์ธ๊ทธ๋ ˆ์„œ ์ž์› ์ž˜ ์‹คํ–‰๋˜๊ณ  ์žˆ์—ˆ์Œ

  1. ๋ฐฉํ™”๋ฒฝ ๋ฌธ์ œ์ธ๊ฐ€ ์‹ถ์–ด์„œ ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ณด์•˜์ง€๋งŒ ๋”ฑํžˆ ๋ฐฉํ™”๋ฒฝ ๋ฌธ์ œ๋กœ ๋ณด์ด์ง€์•Š์•˜๋‹ค..

  2. ์ค‘๊ฐ„์— service ํƒ€์ž…์ด ๋ฌธ์ œ์ธ๊ฐ€ ์‹ถ์–ด์„œ type: ClusterIP๋กœ ํ• ๋‹นํ–ˆ๋‹ค๊ฐ€, ์„œ๋น„์Šค์˜ External IP๊ฐ€ ํ• ๋‹น๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ๋‹ค์‹œ LoadBalancer๋กœ ์ˆ˜์ •ํ•จ.


๋ฌธ์ œ์  ๋ฐœ๊ฒฌ

๋„๋Œ€์ฒด ๋˜ ๋ญ๊ฐ€ ๋ฌธ์ œ์ง€ ํ•˜๋‹ค๊ฐ€ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ์ด๋ฏธ vmํ™˜๊ฒฝ์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐฐํฌํ•œ ๊ฒฝํ—˜์ด ์žˆ์–ด์„œ ์‹คํ–‰ํ•  was ์ด๋ฏธ์ง€ ํŒŒ์ผ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์„๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐ๋„ ๋ชปํ–ˆ๋‹ค..

@cloudshell:~/prac (jpa-practice)$ kubectl get all
NAME                                          READY   STATUS             RESTARTS      AGE
pod/jpapractice-deployment-555d5bbc64-h84rg   0/1     CrashLoopBackOff   2 (16s ago)   39s
pod/jpapractice-deployment-555d5bbc64-jk4k7   0/1     CrashLoopBackOff   2 (18s ago)   39s
pod/jpapractice-deployment-555d5bbc64-jrr2r   0/1     CrashLoopBackOff   2 (15s ago)   39s

NAME                          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/jpapractice-service   ClusterIP   10.8.9.32    <none>        80/TCP    30s
service/kubernetes            ClusterIP   10.8.0.1     <none>        443/TCP   106s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jpapractice-deployment   0/3     3            0           40s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/jpapractice-deployment-555d5bbc64   3         3         0       40s
a01043753181@cloudshell:~/prac (jpa-practice)$ kubectl get all
NAME                                          READY   STATUS             RESTARTS      AGE
pod/jpapractice-deployment-555d5bbc64-h84rg   0/1     CrashLoopBackOff   3 (14s ago)   64s
pod/jpapractice-deployment-555d5bbc64-jk4k7   0/1     Error              3 (43s ago)   64s
pod/jpapractice-deployment-555d5bbc64-jrr2r   0/1     Error              3 (40s ago)   64s

NAME                          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/jpapractice-service   ClusterIP   10.8.9.32    <none>        80/TCP    56s
service/kubernetes            ClusterIP   10.8.0.1     <none>        443/TCP   2m12s

pod์˜ ์ƒํƒœ๋ฅผ Status๋ฅผ ํ™•์ธํ•˜๋‹ˆ CrashLoopBackOff ์™€ Error ์ƒํƒœ์ธ ๊ฒƒ์„ ๋’ค๋Šฆ๊ฒŒ ํ™•์ธํ•˜์˜€๋‹ค..


์ง€ํ”ผํ‹ฐ์˜ ๋„์›€์„ ๋ฐ›์•„์„œ ์›์ธ์„ ๋“œ๋””์–ด ์ฐพ์•„๋‚ด๊ฒŒ๋จ... ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด๋ณด๋‹ˆ

ERROR org.springframework.book.SpringApplication - Application run failed
java.lang.IllegalArguemtnException: Could not resolve placeholder 'active' in value "${active}"

active๋ผ๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์—๋Ÿฌ....
๋„์ปค ์ด๋ฏธ์ง€๋ฅผ TravisCI๋ฅผ ํ†ตํ•ด์„œ CI ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•  application.ymlํŒŒ์ผ ์„ค์ •์„ ๊ฐœ๋ฐœ(dev), ๋ฐฐํฌ(prod) ๋‘๊ฐ€์ง€๋กœ ๋”ฐ๋กœ ํ•ด๋†จ์—ˆ๋Š”๋ฐ, ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์ˆœ๊ฐ„์— jar ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜๋Š” ์˜ต์…˜ ํƒœ๊ทธ๋ฅผ ์ฃผ์—ˆ๋˜ ๊ฒƒ์ด ์›์ธ ์ด์—ˆ๋‹ค..

FROM openjdk:11
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar", "-Dspring.profiles.active=${active}", "-Duser.timezone=Asia/Seoul", "/app.jar"]
  • ์ด์ „์—๋Š” ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด์„œ vm ํ™˜๊ฒฝ์—์„œ docker-compose ํŒŒ์ผ์„ ์ด์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ ํ•ด๋‹น ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ฑ„์›Œ์คฌ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„์„œ ์•ฑ ์‹คํ–‰ ์ž์ฒด๊ฐ€ ๋˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ...

๋ฌธ์ œ์  ํ•ด๊ฒฐ

์ด๋ฏธ์ง€ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด์„œ ๋‹ค์‹œ ๋นŒ๋“œํ•˜๊ณ  ๋„์ปคํ—ˆ๋ธŒ์— ํ‘ธ์‰ฌํ•ด์•ผํ•˜๋‚˜? ํ–ˆ์ง€๋งŒ, ์ด๋Š” ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€๊ณ , Pod์—์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค..
https://kubernetes.io/ko/docs/tasks/inject-data-application/define-environment-variable-container/

๋‘๋ฒˆ์งธ Deployment.yaml ํŒŒ์ผ..!

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jpapractice-deployment
spec:
  replicas: 3  # Set the desired number of replicas
  selector:
    matchLabels:
      app: jpapractice
  template:
    metadata:
      labels:
        app: jpapractice
    spec:
      containers:
        - name: jpapractice
          image: adultkim/jpapractice:latest  # Your Spring Boot application image
          env:  # ๋ฌธ์ œ์˜€๋˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ถ”๊ฐ€
            - name: active
              value: "prod"
          ports:
            - containerPort: 8081  # Port your Spring Boot application is running on

๋ฌธ์ œ์˜€๋˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‹ค์‹œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๋‹ˆ status ๊ฐ€ Running ์ƒํƒœ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‹คํ–‰๋˜์—ˆ๋‹ค..!

์‹คํ–‰ ์™„๋ฃŒ

์ž‘์„ฑํ•ด๋‘” Ingress์™€ GKE์—์„œ ์ง€์›ํ•˜๋Š” ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์˜ ๋™์ž‘์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ External Ip๋ฅผ ํ†ตํ•ด์„œ WAS์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๋‹ค ใ… 

rule์— ์ž‘์„ฑํ•ด๋‘” host๋„ DNS์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•ด External IP์— ์—ฐ๊ฒฐํ•ด๋†“์•„์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋„๋ฉ”์ธ์ฃผ์†Œ๋กœ๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค..!
์ „์—๋Š” nginx๋ฅผ ํ†ตํ•ด์„œ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์›น ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ–ˆ์—ˆ๋Š”๋ฐ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋‹ˆ ๋„ˆ๋ฌด๋‚˜ ํŽธ์•ˆํ•จ...

์ข€ ๋” ์™„๋ฒฝํ•˜๊ฒŒ ๊ณต๋ถ€ํ•ด์„œ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๋„๋ก CI/CDํ™˜๊ฒฝ์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์„ ํ‚ค์›Œ์•ผ๊ฒ ๋‹ค


MySQL ์—ฐ๊ฒฐ

https://velog.io/@99_insung/GKE-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EB%B3%BC%EB%A5%A8PV-PVC%EB%A1%9C-MySQL-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-%ED%8A%B8%EB%9F%AC%EB%B8%94-%EC%8A%88%ED%8C%85#springboot-%EC%9B%B9-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98--%EC%9D%B4%EC%A0%84-%ED%8F%AC%EC%8A%A4%ED%8C%85

0๊ฐœ์˜ ๋Œ“๊ธ€