본문 바로가기
Kubernetes

[Kubernetes] Kubernetes에서 NodePort를 활용한 Spring Boot 애플리케이션의 모든 노드 포트 개방 및 서비스 배포

by sum_mit45 2024. 10. 29.
728x90
반응형
10월 29일(화) 실습 중

Spring Boot 애플리케이션을 Kubernetes에서 NodePort를 사용하여 모든 노드에서 포트를 개방하고 서비스를 제공하는 실습을 진행했다. 

1) 애플리케이션 생성

1-1) Spring Boot 애플리케이션 생성

Spring Boot를 사용하여 애플리케이션을 생성한다. NameGroup 정도를 수정해주면 된다.

또한 Dependencies 도 아래와 같이 Lombok, Spring Web, Spring Boot DevTools 로 3개로만 진행했다.

스프링부트 기본 설정
스프링부트 dependency 추가

1-2) FrontController 작성

아래와 같이 컨트롤러를 작성해주었습니다.

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> list = new ArrayList<>();
        Map<String, String> map1 = new HashMap<>();
        map1.put("id", "itstudy");
        map1.put("name", "아담");
        list.add(map1);

        data.put("list", list);

        return data;
    }
}

1-3) 실행 후 브라우저에서 8080포트로 접속

애플리케이션을 실행한 후 브라우저에서 http://localhost:8080으로 접속하여 잘 실행되고 있는지 확인한다.

localhost:8080/

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

2-1) 터미널에서 애플리케이션 빌드

./gradlew clean build

 

해당 명령어를 이용해서 실행 가능한 자바 파일을 생성한다.

./gradlew clean build 명령어

2-2) Dockerfile 생성 및 작성

FROM amazoncorretto:17
CMD ["./mvnw", "clean", "package"]
ARG JAR_FILE=target/*.jar
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]


프로젝트 루트 디렉토리에 Dockerfile을 생성하고 해당 내용을 작성한다.

2-3) Docker 빌드

docker build -f Dockerfile -t apiserver:0.0.1 .

2-4) Docker 이미지 확인

docker images

 

아래 이미지와 같이 방금 생성한 apiserver 이미지가 있는지 확인한다.

docker images 확인

2-5) 컨테이너 실행

docker run -d --name apiserver -p 80:8080 apiserver:0.0.1

docker container 수행 되고 있는지 확인

3) GitHub Action을 이용해서 DockerHub에 배포

3-1) 깃허브에서 레포지토리 생성 후 모든 파일 push

git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin [깃허브 주소]
git push -u origin main

 

3-2) Docker hub 에서 레포지토리 생성

docker hub에서 레포지토리 생성

3-3) Github actions 파일 작성

name: Java CI with Gradle

on:
  push:
    branches: ["main"]

jobs:
  build-docker-image:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      # JDK 17버전 설치
      - name: Set Up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      # gradlew 파일 실행 권한 부여
      - name: Run chmod to make gradlew executable
        run: chmod +x ./gradlew

      # 빌드
      - 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 $NAME/$REPO .
          docker push $NAME/$REPO:latest

 

파일을 작성하고 secrets 키도 업데이트 해준다. 

github 에서 [Settings] > [Secrets and variables] > [Actions] 부문에서 추가면 된다.

 

이후에 다시 actions 들을 실행시켜 보면 다음과 같이 잘 동작하고, Docker hub에도 업로드 된 걸 확인할 수 있다.

workflow 동작

 

4) Kubernetes Deployment 이용해서 파드 생성

4-1) Pod를 생성할 YAML 파일 생성

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: summit45/apiserver
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: 500m
            memory: 1000Mi

4-2) Pod 생성

kubectl apply -f springbootdeployment.yml

5) Kubernetes Service 이용해서 NodePort 설정

5-1) NodePort를 이용할 서비스 파일 생성

apiVersion: v1
kind: Service
metadata:
  name: devops-spring-service
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: devops-spring-app

5-2) 서비스 생성

kubectl apply -f service.yml

5-3) 서비스 확인

kubectl get svc
kubectl get svc -o wide

5-4) EndPoint 확인

kubectl get ep

직접 curl 명령어로 확인해보기

  • 서비스 상태: devops-spring-service가 NodePort로 설정되어 있고, 31583 포트를 통해 접근할 수 있다. 클러스터 IP(10.103.119.82)가 있으며, 외부에서 접근할 수 있는 IP는 없다.
  • 엔드포인트 상태: devops-spring-service와 연결된 두 개의 Pod(10.244.0.4, 10.244.0.5)가 있으며, 포트 8080으로 서비스된다.

이렇게 NodePort를 활용하여 Spring Boot 애플리케이션을 Kubernetes 클러스터에서 서비스하는 것은 외부에서 접근 가능한 환경을 구축할 수 있다. 이를 통해 클러스터 내의 모든 노드에서 애플리케이션에 접근할 수 있으며, 서비스와 엔드포인트 상태를 확인함으로써 문제를 사전에 진단하고 해결할 수 있다.

728x90
반응형