MSA 14일차 : 쿠버네티스 - Probe, 흐름 정리

parang·2025년 6월 16일

LG CNS AM Inspire Camp 2기

목록 보기
47/50
post-thumbnail

yaml 정리

backend-post 서비스를 만들면서 쿠버네티스 흐름을 정리해보자.


application.yml : 프로젝트 이름, 카프카 설정
application-dev.yml : 쿠버네티스로 전달, 경로만
application-local.yml : jdbc 설정, 카프카


도커파일, 젠킨스 파일 추가


커밋, 푸시, 젠킨스 파이프라인 생성


mysql service.yaml 작성
Service, Endpoints


configMap.yaml 작성

apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-post-config
data:
  application-dev.yml: |
    server:
      port: 8080

    spring:
      datasource:
        url: jdbc:mysql://k8s-external-post-mysql-service:3306/post?serverTimezone=UTC&useSSL=true&autoReconnect=true&useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
        hikari:
          connection-test-query: SELECT 1  # HikariCP 유효성 검사 추가
          validation-timeout: 5000

      jpa:
        hibernate:
          ddl-auto: create  # 오직 테스트 환경에서만
        generate-ddl: true   # 오직 테스트 환경에서만 (spring.jpa.generate-ddl)
        show-sql: true
        open-in-view: false

      kafka:
        bootstrap-servers: k8s-external-kafka-service:9092

secret.yaml 작성

apiVersion: v1
kind: Secret
metadata:
  name: backend-post-secret
stringData:
  application-secret.yml: |
    spring:
      datasource:
        username: 유저 아이디
        password: 유저 비밀번호

Deployment.yaml 작성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-backend-post-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-backend-post
  template:
    metadata:
      labels:
        app: k8s-backend-post
    spec:
      volumes:
        - name: backend-post-config-volume
          configMap:
            name: backend-post-config
            items:
              - key: application-dev.yml
                path: application-dev.yml
        - name: backend-post-secret-volume
          secret:
            secretName: backend-post-secret
            items:
              - key: application-secret.yml
                path: application-secret.yml
      containers:
        - name: k8s-backend-post
          image: parangg/k8s-backend-post:0.0.1
          imagePullPolicy: Always
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: dev
          ports:
            - containerPort: 8080
          livenessProbe:
            httpGet:
              path: /backend/post/v1/k8s/liveness  # 스프링 부트 생존 상태 엔드포인트
              port: 8080
            initialDelaySeconds: 30   # 컨테이너 시작 후 첫 검사까지 대기
            periodSeconds: 5          # 5초마다 체크
            failureThreshold: 3       # 3회 연속 실패 시 컨테이너 재시작
            timeoutSeconds: 3         # 3초 내 응답 필요

            # Readiness Probe 추가 (트래픽 유입 제어용)
          readinessProbe:
            httpGet:
              path: /backend/post/v1/k8s/readiness  # 스프링 부트 준비 상태 엔드포인트
              port: 8080
            initialDelaySeconds: 30   # 컨테이너 시작 후 첫 검사까지 대기
            periodSeconds: 5          # 5초마다 체크
            failureThreshold: 3       # 3회 연속 실패 시 서비스 트래픽 중지
            timeoutSeconds: 3  # 3초 내 응답 필요

          volumeMounts:
            - mountPath: /etc/config
              name: backend-post-config-volume
              readOnly: true
            - mountPath: /etc/secret
              name: backend-post-secret-volume
              readOnly: true

-> 볼륨, 볼륨 마운트, probe까지 추가되어 있음.

service.yaml 작성

apiVersion: v1
kind: Service
metadata:
  name: k8s-backend-post-service
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: k8s-backend-post
    

트러블슈팅

  1. post mysql 서버 문제
    도커에 띄운 것을 잊어버려 자꾸 중지를 누르다 보니 db를 수동으로 실행시켜주고 있다. db 서버가 꼭 띄어져 있어야 한다.

  2. 띄어쓰기, 사소한 오타 문제
    늘 같은 문제인데 이번에는 // -> ///로 적어서 오류가 나고 있었다. 처음 작성할때 주의해서 작성!

🌡️ Kubernetes Probe란?

probe는 Kubernetes가 컨테이너의 상태를 주기적으로 확인하기 위한 진단 기능.

kubelet이 주기적으로 실행해서 컨테이너의 상태를 체크하고, 자동으로 재시작 또는 제외.

libenessProbe (생존성 검사)

  • 컨테이너가 살아 있는지 진단

readinessProbe (준비상태 검사)

  • 트래픽을 받을 준비가 되어 있는지 진단
  • 준비되지 않은 파드를 Service 로드 밸런싱에서 제외

실습

목적

백엔드에서 쿠버네티스가 접근할 수 있는 체크용 api 만들기

코드


probeService.java


@Slf4j
@Service
public class ProbeService {
    public void validateLiveness() {
        // TODO: 만일 서비스를 재시작 해야 하는 상황이면 exception발생
    }
    public void validateReadiness() {
        // TODO: 만일 서비스를 재시작 해야 하는 상황이면 exception발생
    }
}

---

BackendK8sController.java

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/backend/user/v1/k8s", produces = MediaType.APPLICATION_JSON_VALUE)
public class BackendK8sController {
    private final ProbeService probeService;

    @GetMapping(value = "/liveness")
    public ApiResponseDto<String> liveness() {
        probeService.validateLiveness();

        return ApiResponseDto.defaultOk();
    }

    @GetMapping(value = "/readiness")
    public ApiResponseDto<String> readiness() {
        probeService.validateReadiness();

        return ApiResponseDto.defaultOk();
    }
}

-> 컨트롤러에서 각 서비스 로직을 호출한 후 응답 보내고, 예외가 발생하면 500번 에러. -> 쿠버네티스가 파트를 재시작 또는 제외.

deployment.yaml 수정

        livenessProbe:
          httpGet:
            path: /backend/user/v1/k8s/liveness  # 스프링 부트 생존 상태 엔드포인트
            port: 8080
          initialDelaySeconds: 30   # 컨테이너 시작 후 첫 검사까지 대기
          periodSeconds: 5          # 5초마다 체크
          failureThreshold: 3       # 3회 연속 실패 시 컨테이너 재시작
          timeoutSeconds: 3         # 3초 내 응답 필요

          # Readiness Probe 추가 (트래픽 유입 제어용)
        readinessProbe:
          httpGet:
            path: /backend/user/v1/k8s/readiness  # 스프링 부트 준비 상태 엔드포인트
            port: 8080
          initialDelaySeconds: 30   # 컨테이너 시작 후 첫 검사까지 대기
          periodSeconds: 5          # 5초마다 체크
          failureThreshold: 3       # 3회 연속 실패 시 서비스 트래픽 중지
          timeoutSeconds: 3         # 3초 내 응답 필요

주의 : livenessProbe와 readinessProbe의 뎁스는 ports와 같다.

profile
파랑입니다.

0개의 댓글