본문 바로가기
CICD/AWS

msa구조 k8s 통해 백엔드 배포해보기 (2) Spring Cloud Kubernetes

by windy7271 2024. 5. 6.
728x90
반응형
2024-05-06 10:50:26.162  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [After]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Before]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Between]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Cookie]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Header]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Host]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Method]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Path]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Query]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [ReadBody]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [RemoteAddr]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [XForwardedRemoteAddr]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Weight]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [CloudFoundryRouteService]

Spring Cloud 프로젝트에서 제공하던 기능들을 가진 Kubernetes의 대표적인 리소스는 다음과 같다.

  • 서비스 디스커버리 : Kubernetes Service / Ingress
  • 로드 밸런싱 : Kubernetes Service (LoadBalancer)
  • API 게이트웨이 : Kubernetes Service / Ingress
  • 설정 관리 : Kubernetes ConfigMap / Secrets

 

Spring Cloud Kubernetes는 개발자가 Kubernetes에서 Spring Cloud 애플리케이션을 구축하고 실행할 수 있도록 잘 알려진 Spring Cloud 인터페이스의 구현을 제공한다.

 

공식 문서에서 소개하는 주요 기능은 다음과 같습니다.

  • Kubernetes awareness
    • Spring Cloud 어플리케이션이 Kubernetes 환경에서 동작하는지 여부를 감지
  • DiscoveryClient implementation
    • Kubernetes의 Service를 활용, Spring Cloud의 서비스 디스커버리를 지원
  • PropertySoruce objects configured via ConfigMaps
    • Kubernetes의 ConfigMaps를 활용, Spring Cloud의 설정 서버/클라이언트를 지원
  • Client side loadbalancing via Netflix Ribbon
    • Netflix Ribbon + Kubernetes Service를 통해 클라이언트 사이드 로드 밸런싱 지원

출처 : https://velog.io/@mrcocoball2/Spring-Cloud-Spring-Cloud-Kubernetes-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EB%B0%8F-%ED%99%9C%EC%9A%A9

 

[Spring Cloud] Spring Cloud Kubernetes - 기본 개념 및 활용

Spring Cloud Kubernetes는 개발자가 Kubernetes에서 Spring Cloud 어플리케이션을 빌드 / 실행할 수 있도록 Spring Cloud 인터페이스 구현을 제공하는 프로젝트입니다.

velog.io

 

 

사용하기 전에 쿠버네티스의 대해 잘 모를 수도 있다고 생각하여

주요 자원, 동작 방식의 대해 설명해보도록 하겠다. 필요없으면 쭈욱 내려도 된다.

 

쿠버네티스 클러스터

쿠버네티스 클러스터에는 크게 두 가지로 나뉜다.

마스터노드, 워커노드

간단하게 줄이면 마스터 노드는 명령어를 날리는곳, 워커노드는 명령어를 실행하는 곳이라고 생각하면 된다.

마스터 노드 

  • 클러스터 관리, API 서버, 스케줄링 역할 등을 담당한다.
  • 사용자, 클러스터 내부 구성 요소 및 외부 도구가 쿠버네티스 API를 통해 통신할 수 있는 진입점을 제공한다.
  • 개발자의 명령어는 쿠버네티스 API 서버(kube-apiserver)로 전송
  • aws의 eks를 사용하게 되면, 마스터노드는 클러스터 생성시 aws차원에서 지원이되고, 개발자가 마스터노드에 대해 신경쓸일은 없다.

워커 노드 

  • 애플리케이션의 실제 실행을 담당하는 노드로서 각 워커 노드에는 Kubelet이라는 에이전트를 실행되어 마스터 노드와 통신한다
  • aws 기준으로는 ec2에 인스턴스가 실행되고, 해당 워커노드에서 서비스 pod가 실행된다

주요 요소는 다음과 같다.

  • kubelet
    • API 서버와 통신하여 파드를 시작, 중지, 관리하는 등의 작업을 수행
    • 스케줄러가 파드를 실행할 노드를 결정하면, 해당 노드의 kubelet에 파드를 생성하라는 명령이 전달
    • kubelet은 파드의 스펙에 따라 컨테이너 런타임을 사용하여 컨테이너를 시작
    • kubelet은 파드가 성공적으로 시작되었는지 확인하고, 파드의 상태를 주기적으로 API 서버에 보고
  • kube-proxy
    • 네트워크 프록시 및 로드 밸런서 역할을 하는 노드 수준 구성 요소
    • kube-proxy는 네트워크 트래픽을 적절히 포워딩하도록 네트워크 규칙을 설정하여 파드 간의 통신이나 외부에서 파드로의 접근을 가능
  • 컨테이너 런타임
    • 실제로 컨테이너를 실행하는 소프트웨어(예: Docker).
    • 이미지를 가져오고, 컨테이너를 패키지화된 애플리케이션과 함께 실행하고, 컨테이너의 생명주기를 관리
    • docker등의 주요 소프트웨어는 eks등을 사용하여 클러스터 구성시 자동 설치
  • 컨테이너 네트워크 인터페이스 (CNI) 플러그인
    • 다양한 CNI 플러그인을 통해, 노드 간 및 파드 간 네트워킹을 구성
    • 네트워크 연결을 설정하고, IP 주소를 파드에 할당하며, 네트워크 격리를 관리

내용이 많다.

 

 

동작 방식은 아래와 같다

동작방식

 

주요 리소스 종류에 대해 알아보겠다.

Service:

Service는 클러스터 외부로부터 요청을 받을 수 있게 IP를 노출하는 역할을 하는 리소스다. 그리고 Deployment로 Pod를 수평확장하는 상황에, 트래픽을 적절히 분산시키기는 역할을 할 수 있는 리소스이다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: my-nginx # 위에 label과 싱크가 같다.
  • port
    • Service가 클러스터 내부에서 리슨(listen)하는 포트
    • 즉, 클러스터 내부의 다른 컴포넌트나 Pod들이 이 Service와 통신하기 위해 사용하는 포트
  • targetPort
    • Service가 포워딩(forward)하는 대상 Pod의 포트
    • targetPort는 Pod의 컨테이너 포트와 직접 매핑
    • NodePort
      • 클러스터 외부에서 Service에 접근하기 위해 노드(node)가 리슨하는 포트
      • NodePort 서비스를 사용하면, 클러스터 외부에서 특정 노드의 IP 주소와 이 NodePort를 통해 Service에 접근
  • 네임스페이스 내에서 파드와 서비스를 함께 사용할 때, 서비스는 해당 네임스페이스 내에서만 파드를 찾아 트래픽을 전달할 수 있음에 유의
    • 메타데이터에 namespace: test-namespace 추가 필요

deployment:

Deployment는 파드와 레플리카셋의 선언적 업데이트를 관리하고 스케일링, 롤아웃, 롤백 등을 포함한 파드의 배포 과정을 자동화 할 수 있다. pod매니저라고 생각하면 편하다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector: # 참조하겠다.
    matchLabels:
      app: my-nginx 
  template: # 파트의 정보
    metadata:
      labels:
        app: my-nginx # 이름을 맞춰 줘야함
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

 

  • 선택자의 라벨 (spec.selector.matchLabels)
    • 이 라벨은 Deployment가 관리해야 할 파드를 결정하는 데 사용
    • spec.selector.matchLabels는 Deployment에 의해 관리되어야 하는 파드가 어떤 라벨을 가지고 있어야 하는지 정의
    • 즉, 이 라벨은 Deployment가 "내가 관리해야 할 파드는 이러한 라벨을 가진 것들이다"라고 식별하는 기준

간단하게 말하면 위에서 만든 service에 이름과 , labels의 app 이름을 맞춰주면 된다.

  • kubectl
    • kubectl은 Kubernetes 클러스터를 제어하기 위한 커맨드 라인 인터페이스(CLI) 도구
    • kubectl을 사용하여 사용자는 클러스터에 있는 리소스를 생성, 조회, 업데이트 및 삭제
  • pod
    • Pod는 쿠버네티스에서 배포할 수 있는 가장 작은 단위이며, 1개 이상의 컨테이너로 구성된 배포 단위이다
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: mypod
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
  - name: redis-container
    image: redis
    ports:
    - containerPort: 6379

 

보통 파드를 이렇게 만든다.

 

그 외로 namespace, secret, replica 등이 있다.

 

 

다시 Spring Cloud Kubernetes 를 사용해 보겠다.

 

1.  의존성 추가

Gateway . build.gradle

	implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-client'
	implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-client-all'
	implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-client-loadbalancer'
	implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'
   
   중복제거하면
    
implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-client'
implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'

 

 

이렇게 사용할 수 있다.

 

위에 꺼인 client를 사용하면 Kubernetes의 Service 엔드포인트를 검색할 수 있다. 

 

그러면 서비스로 검색을 할 수 있게 yml파일을 수정해주자

server:
  port: 8080
  error:
    include-binding-errors: always
    include-message: always
spring:
  application:
    name: gateway
  cloud:
    kubernetes:
      discovery:
        all-namespaces: true
      loadbalancer:
        mode: service
    gateway:
      routes:
        - id: batch-service
          predicates:
            - Path=/batch/**
          filters:
            - StripPrefix=1
          uri: lb://batch-service # k8s 에 등록된거로 감.
        - id: employee-service
          predicates:
            - Path=/employee/**
          filters:
            - StripPrefix=1
          uri: lb://employee-service
        - id: login-service
          predicates:
            - Path=/login/**
          filters:
            - StripPrefix=1
          uri: lb://login-service
        - id: salary-service
          predicates:
            - Path=/salary/**
          filters:
            - StripPrefix=1
          uri: lb://salary-service
        - id: total-service
          predicates:
            - Path=/total/**
          filters:
            - StripPrefix=1
          uri: lb://total-service

 

spring.cloud.kubernetes.discovery  디스커버리 설정을 할 수 있다.

all-namespace 이 값이 true로 설정되어 있으면 애플리케이션은 클러스터 내의 모든 네임스페이스에서 서비스를 검색할 수 있다.

 

제일 중요한 부분인데 Spring Cloud Kubernetes의 로드 밸런서 모드를 설정한다. 이 경우에는 "service"로 설정되어 있다. 이것은 Kubernetes 서비스를 통한 로드 밸런싱을 활성화한다.

 

즉 각각의 k8s 폴더안에 service를 보고 로드밸런싱을 한다.

 

그리고 gatway를 제외하고

@EnableDiscoveryClient

 

어노테이션을 달아줘야한다.

애플리케이션이 서비스 디스커버리를 활성화하고 이를 통해 서비스 레지스트리에 등록할 수 있도록 지원한다. 이 애노테이션을 사용하면 Spring Boot 애플리케이션이 서비스 디스커버리 클라이언트로 등록되어, 서비스 디스커버리 시스템(예: Netflix Eureka, Consul, Kubernetes 등)과 통합된다.

 

그럼 각 Service로 매칭된다

 

예를들어 windy7271.shop/admin/signup을 호출하면

gateway -> 게이트웨이에서 서비스를 매칭해서 admin/signup 을 해준다.

 

 

 

현재 나는 globalfilter 와 ,predicate가 구현되어있어서

 

predicate는 gateway web handler 이후로 들어가게 된다. 즉 서비스 이전

 

배포가 다 된 상태에서 실행해보면

2024-05-06 10:50:26.162  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [After]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Before]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Between]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Cookie]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Header]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Host]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Method]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Path]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Query]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [ReadBody]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [RemoteAddr]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [XForwardedRemoteAddr]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [Weight]
2024-05-06 10:50:26.163  INFO 1 --- [           main] o.s.c.g.r.RouteDefinitionRouteLocator    : Loaded RoutePredicateFactory [CloudFoundryRouteService]

 

마지막에 이런 로그가 나온다

 

이 로그는 Spring Cloud Gateway에서 Route Predicate Factory를 로드하는 과정을 보여준다. Spring Cloud Gateway는 요청을 받아 특정한 서비스로 전달하기 전에 이러한 라우트 프리디케이트를 사용하여 요청을 필터링하거나 조작할 수 있다.

여기서 로그에 나열된 각각의 RoutePredicateFactory는 다양한 요청 필터 및 조건을 나타낸다. 예를 들어, Path 프리디케이트는 요청의 경로를 기준으로 라우팅을 수행하고, Header 프리디케이트는 요청 헤더를 기반으로 라우팅을 수행한다. 이러한 다양한 프리디케이트를 조합하여 특정 요청을 특정 서비스로 라우팅하거나 필터링할 수 있다. 이 로그는 Spring Cloud Gateway가 시작될 때 이러한 라우트 프리디케이트를 로드하고 사용할 수 있도록 하는 초기화 과정을 보여준다. 이를 통해 Gateway가 요청을 적절히 라우팅하고 필터링할 수 있게 된다.

 

https://link.coupang.com/a/ctyBWL

 

베리픽스 고급 멀티 샤프너 4in1 가정용 가위 칼갈이 - 칼갈이/숫돌 | 쿠팡

쿠팡에서 베리픽스 고급 멀티 샤프너 4in1 가정용 가위 칼갈이 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 칼갈이/숫돌 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

 

 

일단 그럼 배포할 준비가 완료 되었고. 유레카는 떼고 올라간다.

그럼 작성해야 하는 도커 파일은 유레카랑 프론트엔드빼고 6개다

 

다음은

Spring Cloud Kubernetes 자세히보기, ecr, 노드그룹 생성, 도커작성 ,depl, service 작성까지 해보겠다.

 

 

반응형

댓글