Spring Boot Application 을 Kubernetes 를 활용하여 배포

최병훈·2024년 10월 30일
post-thumbnail

1)애플리케이션 생성

  • Intellij에서 Spring Boot Application 생성(Lombok 과 Web 에 대한 의존성만 추가)
    • Spring Boot DevTools
    • Lombok
    • Spring Web
  • 기본 패키지 안에 요청을 처리하는 클래스를 추가하고 작성(FrontController)

    package com.bh.apiserver;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    public class FrontController {
        @GetMapping
        public Map<String, Object> index() {
            Map<String, Object> data = new HashMap<>();
            data.put("result", "success");
    
            List<Map<String, String>> list = new ArrayList<>();
            Map<String, String> map1 = new HashMap<>();
            map1.put("id", "yachae");
            map1.put("name", "bh");
            list.add(map1);
    
            data.put("list", list);
            return data;
        }
    }
    
  • 브라우저에서 실행 확인 : http://localhost:8080

2)Dockerfile 파일 만들어서 이미지 생성

  • 터미널을 실행 시켜서 애플리케이션 빌드: 실행 가능한 자바 파일을 생성
    ./gradlew clean build

    실행 가능한 jar 파일이 생성되었다.
  • 프로젝트의 루트 디렉토리에 Dokcerfile 생성하고 작성

    FROM amazoncorretto:23
    CMD ["./mvnw", "clean", "package"]
    ARG JAR_FILE=target/*.jar
    COPY ./build/libs/*.jar app.jar
    ENTRYPOINT ["java", "-jar", "app.jar"]
  • 터미널에서 이미지 생성

    docker build -f Dockerfile -t apiserver:0.0.1 .
  • 이미지 확인
    docker images
  • 컨테이너로 실행
    docker run -d --name apiserver -p 80:8080 apiserver:0.0.1

3)GitHub이용해서 DockerHub에 배포

  • GitHub에 레포지토리 생성 : apiserver
  • GitHub에 push

    git init
    git add .
    git commit -m "message"
    
    # 브랜치 확인(현재 git hub는 main이 기본 브랜치)
    git branch
    
    # 브랜치 이름 변경
    git branch -M main
    
    # 원격 저장소 등록: git remote add 저장소이름 url
    git remote add origin https://github.com/yachae1101/apiserver.git
    
    # push
    git push origin main

  • push가 발생할 때 DockerHub에 이미지 배포

    • Docker Hub에서 토큰 발급

    • Docker Hub에 Repository를 생성: apiserver

    • 프로젝트 안에 .github/workflows/upload.yml 생성하고 작성

      name: Java CI with Gradle
      
      on:
       push:
         branches: ["main"]
      
      jobs:
       build-docker-image:
         runs-on: ubuntu-latest
         steps:
           - uses: actions/checkout@v3
           #JDK 23버전 설치
           - name: Set Up JDK 23
             uses: actions/setup-java@v3
             with:
               java-version: '23'
               distribution: 'temurin'
           #빌드
           - name: Build and Gradle
             uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
             with:
               arguments: clean bootJar
           #도커 허브 로그인
           - name: Login To DockerHub
             uses: docker/login-action@v1
             with:
               username: ${{secrets.DOCKERHUB_USERNAME}}
               password: ${{secrets.DOCKERHUB_TOKEN}}
           #이미지 빌드 및 업로드
           - name: Image Build and Release to DockerHub
             env:
               NAME: ${{secrets.DOCKERHUB_USERNAME}}
               REPO: ${{secrets.DOCKERHUB_REPOSITORY}}
             run: |
               docker build -t $REPO .
               docker tag $REPO:latest $NAME/$REPO:latest
               docker push $NAME/$REPO:latest
    • GitHub 의 repository 에 variable 을 등록

      • DOCKERHUB_USERNAME
      • DOCKERHUB_TOKEN
      • DOCKERHUB_REPOSITORY
    • 생성한 .github/workflows/upload.yml 파일을 push 하여 GitHub Action 동작

      git add .
      git commit -m ".github/workflows/upload.yml added"
      git push origin main
    • GitHub Actions 동작 확인

    • 배포가 제대로 되었는지 도커 허브에서 확인

    • 이미지가 제대로 동작하는지 확인

      docker pull yachae1101/apiserver
      docker images

      docker run -d --name apiserver-container -p 80:8080 yachae1101/apiserver
      docker ps

4)쿠버네티스 Deployment 이용해서 파드 생성

  • pod를 생성을 위한 springboot-deployment.yml 파일을 생성

    apiVersion: apps/v1
    
    kind: Deployment
    
    metadata:
      name: devops-spring-deployment
    
    spec:
      selector:
        matchLabels:
          app: devops-spring-app
    spec:
      selector:
        matchLabels:
          app: devops-spring-app
    
      replicas: 2
      template:
        metadata:
          labels:
            app: devops-spring-app
        spec:
          containers:
          - name: core
            image: yachae1101/apiserver
            imagePullPolicy: Always
            ports:
            - containerPort: 8080
              protocol: TCP
            resources:
              requests:
                cpu: 500m
                memory: 1000Mi
  • 파드 생성
    kubectl apply -f springboot-deployment.yml
    kubectl get pods

5)쿠버네티스 Service 이용해서 NodePort 설정

  • nodeport를 이용할 서비스 파일을 생성: service.yml
    apiVersion: v1
    kind: Service
    metadata:
      name: devops-spring-service
    spec:
      type: NodePort
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: devops-spring-app
  • 서비스 생성
    kubectl apply -f service.yml
  • 서비스 생성 확인
    kubectl get svc
    kubectl get svc -o wide
  • endpoint 확인
    kubectl get ep
  • 서비스와 동일한 이름의 endpoint가 있으면 service에 요청을 하면 endpoint에 요청을 한다는 의미입니다.

0개의 댓글