[스프링] 스프링 클라우드 데이터 플로우와 스프링 배치

개요

스프링 클라우드 데이터 플로우(Spring Cloud Data Flow, SCDF)란 클라우드 파운드리(Cloud Foundry) 및 쿠버네티스(Kubernetes)를 위한 마이크로서비스 기반 스트림 및 배치 데이터 처리 서비스 플랫폼이다.

데이터 플로우를 사용한 시스템은 크게 데이터 플로우 서버와 서버가 스트림 및 배치 작업을 위해 배포할 수 있는 애플리케이션 두 가지 컴포넌트로 구성된다.

서버 컴포넌트는 크게 두 가지가 있다.

  • 데이터 플로우 서버
  • 스키퍼(skipper) 서버


데이터 플로우 서비스에 접근하기 위한 주요 엔트리포인트는 서버의 웹 API(RESTful API)를 사용하는 것이다. 웹 대시보드는 서버에 의해 제공된다.

서버는 클라우드 파운드리, 쿠버네티스 또는 로컬 컴퓨터와 같은 여러 플랫폼에서 실행 가능하다. 각 서버는 관계형 데이터베이스에 스트림 및 배치 처리와 관련된 상태를 저장하고 이를 관리 및 사용한다.


데이터 플로우 및 스키퍼 서버의 역할

데이터 플로우 서버의 역할은 다음과 같다.

  • 도메인 특정 언어(DSL)를 기반으로 스트림 및 배치 잡 애플리케이션 정의를 파싱
  • 스트림, 태스크 및 배치 잡 애플리케이션 정의의 유효성 검사 및 영속화
  • jar 및 도커 이미지와 같은 아티팩트를 DSL에서 사용되는 이름으로 등록
  • 디플로이어 (deployer): 하나 이상의 플랫폼에 배치 잡 애플리케이션을 배포
  • 잡 스케줄링을 플랫폼에 위임
  • 태스크 및 배치 잡 실행의 세부적인 기록 쿼리
  • 메시징 입력 및 출력을 구성하는 스트림에 구성 속성을 추가하고 배포 속성을 전달
    • 배포 속성의 예: 초기 인스턴스 수, 메모리 요구 사항 및 데이터 파티셔닝
  • 스트림 배포를 스키퍼 서버에게 위임
  • 감사(audit) 작업
    • 예: 스트림의 생성, 배포, 배포 취소 및 배치 잡의 생성, 실행, 삭제)
  • 스트림 및 배치 잡 정의 DSL 탭 완성 기능 제공


스키퍼 서버의 역할은 다음과 같다.

  • 하나 이상의 플랫폼에 스트림을 배포
  • 블루/그린 배포 전략을 사용하여 하나 이상의 플랫폼에서 스트림을 업그레이드하고 롤백
  • 각 스트림의 매니페스트 파일(어떤 애플리케이션이 배포되었는지에 대한 최종 설명을 나타내는 파일)의 기록을 저장


아키텍처

https://dataflow.spring.io/static/19e89c2894aa4586aec3336ac4e6954b/5105f/arch-overview.webp


데이터베이스

데이터 플로우 및 스키퍼 서버는 동작을 위해 RDBMS를 필요로 한다. 기본적으로 서버는 내장된 H2 데이터베이스를 사용하도록 되어 있다. 이외에 지원되는 외부 데이터베이스는 HSQLDB, MariaDB, Oracle, Postgresql, DB2, SqlServer이다. 서버가 구동되면 자동으로 관련 데이터베이스 스키마가 생성된다.

SCDF는 데이터베이스 스키마를 초기화하기 위한 관련 DDL 스크립트를 제공한다. apps/skipper/schemasapps/data-flow/schemas 경로에서 다양한 데이터베이스 별 스크립트를 확인할 수 있다. 스키마 파일이 여러 개인 경우 이를 적용하려면 순서대로 적용해야 한다(V1-파일, V2- 파일, V3-파일 순으로).

버전 업그레이드 시 데이터베이스에 대한 스키마 업데이트가 필요할 수 있으며 특정 데이터베이스 유형에 대한 마이그레이션 스크립트가 존재하므로 이를 사용하면 된다링크.


애플리케이션의 종류

데이터 플로우 서버가 다루는 애플리케이션의 종류는 크게 두 가지로 나눌 수 있다.

  1. 장기 실행(long-lived) 애플리케이션
  2. 단기 실행(short-lived) 애플리케이션


장기 실행 애플리케이션은 중단 없이 지속적으로 실행되는 애플리케이션을 말한다. 장기 실행 애플리케이션의 예로는 단일 또는 다중 입력 및 출력을 통해 무한한 데이터가 실시간으로 생성 및 소비되는 메시지 기반(message-driven) 애플리케이션이 있다. 장기 실행 애플리케이션은 지속적으로 실행될 것으로 기대되며 애플리케이션이 중단되면 플랫폼은 이를 재시작할 책임이 있다. 메시지 기반 마이크로서비스 애플리케이션은 카프카, 카프카 스트림즈, RabbitMQ와 같은 메시징 시스템(미들웨어)과 연결된다. 스프링 클라우드 스트림(Spring Cloud Stream) 프레임워크는 다양한 메시징 시스템의 종류에 관계 없이 메시지 기반 애플리테이션을 쉽게 작성할 수 있도록 도와준다. 따라서 특정 미들웨어에 독립적인 핵심 비즈니스 로직을 작성할 수 있다.

단기 실행 애플리케이션은 유한한 데이터를 처리한 다음 종료되는 애플리케이션을 말한다. 데이터 플로우가 다루는 단기 실행 애플리케이션의 예는 다음과 같다.

  1. 코드를 실행하고 데이터 플로우 데이터베이스에 실행 상태를 기록하는 태스크 애플리케이션이 있다. 태스크 애플리케이션을 만들기 위해 선택적으로 스프링 클라우드 태스크(Spring Cloud Task) 프레임워크를 사용할 수 있지만 자바 애플리케이션일 필요는 없다. 그러나 애플리케이션은 데이터 플로우 데이터베이스에 실행 상태를 기록해야 한다.
  2. 위의 태스크 애플리케이션을 확장하여 스프링 배치 프레임워크를 통해 배치 처리를 수행하는 애플리케이션도 단기 실행 애플리케이션에 해당한다.


단기 실행 애플리케이션은 일정 기간(보통 몇 분에서 몇 시간) 동안 실행된 다음 종료된다. 애플리케이션의 실행은 정해진 시간으로 스케줄링되거나 이벤트에 대한 응답을 기반으로 수행될 수 있다.

스프링 클라우드 스트림 프레임워크를 기반으로 장기 애플리케이션을 생성하고, 스프링 클라우드 태스크 또는 스프링 배치 프레임워크를 기반으로 단기 애플리케이션을 생성하는 것이 일반적이며 스프링을 사용하지 않거나 다른 프로그래밍 언어로 만들어진 애플리케이션도 해당된다.

스프링 클라우드 태스크 프레임워크를 사용하면 애플리케이션의 수명 주기 이벤트(예: 시작 시간, 종료 시간 및 종료 코드)를 기록하는 단기 실행 마이크로서비스를 개발할 수 있다. 스프링 배치 프레임워크는 스프링 클라우드 태스크 보다 훨씬 더 많은 기능을 제공하며 대량의 데이터를 처리할 때 권장된다. 스프링 배치는 배치 잡 실행에 대한 정보와 자체 데이터베이스 스키마를 제공한다. 스프링 클라우드 태스크는 스프링 배치와 통합할 수 있다. 스프링 클라우드 태스크 애플리케이션에 스프링 배치 잡을 정의하면 스프링 클라우드 태스크와 스프링 배치 실행 테이블이 연결된다.

위와 같은 애플리케이션을 런타임에 따라 두 가지 방법으로 패키징(아티팩트화)할 수 있다.

  1. 메이븐 저장소, 파일 저장소 또는 HTTP를 통해 액세스할 수 있는 스프링 부트 uber-jar
  2. 도커 레지스트리에 호스팅되는 도커 이미지


스프링 클라우드 데이터 플로우의 마이크로서비스 아키텍처

데이터 플로우와 스키퍼 서버는 스트림 애플리케이션과 배치 작업을 위한 태스크 애플리케이션을 플랫폼에 배포하며, 각각 자체 프로세스 내에서 실행된다. 각 마이크로서비스 애플리케이션을 서로 독립적으로 스케일 업(확장) 또는 스케일 다운(축소)할 수 있으며 각각 버저닝되는 자체 수명 주기가 있다. 스키퍼를 사용하면 런타임 시 스트림 애플리케이션을 독립적으로 업그레이드하거나 롤백할 수 있다.


배치 처리 서비스 관련 기능

  • 스프링 배치 잡 관리: 대시보드를 통해 배치 잡 실행 관리
    • 세부 상태 리포트 조회, 실패 잡 재시작 기능 제공
  • 연결된 그래프로 배치 잡 관리: 대시보드를 사용하여 규모가 크고 높은 연산을 요하는 배치 데이터 파이프라인 설계 가능
  • 배치 잡 스케줄링: 클라우드 파운드리 및 쿠버네티스의 스케줄러 컴포넌트와 통합 가능


쿠버네티스 상에서 SCDF 설정

기능 선택적 활성화

SCDF를 사용하여 다음 기능들을 선택적으로 활성화 및 비활성화할 수 있다.

  • 스트림 (Stream)
  • 태스크 (Task)
  • 스케줄 (Schedule)


각각의 기능 활성 또는 비활성화를 위해 다음 속성을 사용한다. 모든 기능들은 기본적으로 활성화되어 있다.

  • SPRING_CLOUD_DATAFLOW_FEATURES_STREAMS_ENABLED
  • SPRING_CLOUD_DATAFLOW_FEATURES_TASKS_ENABLED
  • SPRING_CLOUD_DATAFLOW_FEATURES_SCHEDULES_ENABLED


배치 모드를 위한 SCDF 구성

SCDF의 태스크 기능을 사용하고 스프링 클라우드 태스크를 스프링 배치와 통합하여 클라우드 플랫폼 상에서 단기 실행 배치 애플리케이션을 배포 및 실행하고 실행 이력을 관리할 수 있다. 이 경우 스프링 배치 애플리케이션이 태스크 애플리케이션이 되고 SCDF는 이 태스크를 클라우드 플랫폼 상에서 실행 및 관리한다.

스트림 처리 없이 배치 처리 기능만 사용할 경우 데이터 플로우 서버만 필요하며 SCDF 쉘(Shell), 스키퍼 서버는 필요하지 않다. 배치 모드를 위한 SCDF 구성을 위해서는 메타데이터 테이블 조회를 위해 관련 애플리케이션 내 데이터베이스 정보 설정이 필요하다. 스프링 배치 애플리케이션은 배치 처리 수행 결과를 메타데이터 테이블에 저장하며 SCDF 서버는 이 메타데이터 테이블에서 배치 처리 결과를 조회한다.

SCDF 서버의 디플로이먼트 환경 변수 설정도 필요하다. 태스크 기능 외의 기능을 비활성화하기 위해 다음과 같이 설정한다.

SPRING_CLOUD_DATAFLOW_FEATURES_STREAMS_ENABLED=false
SPRING_CLOUD_DATAFLOW_FEATURES_SCHEDULES_ENABLED=false
SPRING_CLOUD_DATAFLOW_FEATURES_TASKS_ENABLED=true


애플리케이션 배포 및 실행을 위한 SCDF 서버 구성 속성

애플리케이션 배포를 사용자화하여 애플리케이션 별로 서로 다른 속성 설정을 하거나 모든 배포 애플리케이션에 대한 적절한 서버 구성 속성 설정을 할 수 있다. 애플리케이션 별로 설정된 속성은 항상 서버 구성으로 설정된 속성보다 우선한다. 애플리케이션 별로 실행 시 전역 서버 수준 속성을 재정의할 수 있다.

모든 배포 대상 애플리케이션에 적용되는 속성은 태스크 기능의 경우 src/kubernetes/server/server-config-[binder].yaml 파일에, 스트림 기능의 경우 src/kubernetes/skipper/skipper-config-[binder].yaml에 정의한다. [binder]는 래빗이나 카프카와 같은 메시징 미들웨어로 지정한다.

애플리케이션 실행 시 다음 두 구성 속성들을 설정할 수 있다.

  1. 쿠버네티스 디플로이어 속성 (deployer properties)
  2. 애플리케이션 속성 (application properties)


1. 쿠버네티스 디플로이어 속성

디플로이어 속성(deployer properties)은 SCDF 서버의 디플로이어(deployer)가 애플리케이션을 어떻게 배포 및 실행할 것인지에 관한 속성이다. 이 속성은 쿠버네티스에 단기 실행 태스크 애플리케이션을 배포하는 역할을 하는 스프링 클라우드 디플로이어(Spring Cloud Deployer)링크의 속성 설정이다. 속성 형식은 다음과 같다.

deployer.애플리케이션명.property


사용할 네임스페이스 설정, 이미지 풀 시크릿 및 컨피그 맵 지정, liveness probe 및 readiness probe, 파드 리소스 설정 등 쿠버네티스 애플리케이션 배포와 관련된 속성을 설정한다. 해당 설정은 SCDF 서비스의 환경 변수에 계정 별 속성 설정을 통해 기본 설정이 가능하다. 디플로이먼트 컨트롤러(deployment controller)의 컨테이너 환경 변수(spec.containers.env) 설정에 배포 속성을 설정하면 된다. 또다른 방법으로 SCDF 대시보드에서 태스크 애플리케이션 및 태스크 생성 후 실행 시 Deployment Platform 항목에 디플로이어 속성(deployer property)을 지정하여 배포 속성을 지정하할 수 있다.


2. 애플리케이션 속성

애플리케이션 속성(application properties)은 태스크 애플리케이션의 동작을 지정하기 위해 애플리케이션 개발자가 생성한 속성이다. 애플리케이션의 구성 설정을 설정 파일 내에 직접하지 않은 경우나 동적으로 실행 시 설정하고자 하는 경우 이 속성을 설정할 수 있다. 특정 인자값이나 속성값을 전달 받아 애플리케이션에서 사용하는 경우 해당 값을 설정함으로써 애플리케이션이 실행에 필요한 값을 받아 서비스 시작 및 런타임 시 처리할 수 있도록 한다.

SCDF 대시보드에서 태스크 애플리케이션 및 태스크 생성 후 태스크 실행 시 Application Properties 항목에 애플리케이션 속성을 지정할 수 있다.


태스크 실행 플랫폼 설정

태스크의 배포와 실행은 SCDF 서버에 의해 수행된다. 태스크는 자신의 상태와 관련된 데이터를 데이터베이스에 저장하며 SCDF 서버는 해당 데이터베이스에서 태스크의 상태를 조회하여 사용한다. SCDF 서버에 의해 배포되는 태스크가 스프링 배치 애플리케이션일 경우 서로 다른 태스크 각각의 실행 상태와 관련된 데이터 뿐만 아니라 잡 실행, 스텝 실행 등의 데이터가 데이터베이스에 저장된다.

태스크의 실행 위치(플랫폼)를 지정하여 여러 플랫폼 상에서 태스크를 실행할 수 있다. 플랫폼은 쿠버네티스의 클러스터와 네임스페이스, 클라우드 파운드리의 조직 및 공간, 물리 서버가 될 수 있다. 태스크를 실행하기 위해서는 특정 태스크 플랫폼을 정의해야 한다. 각각의 플랫폼 당 여러 계정을 구성할 수 있으며 계정명은 모든 플랫폼에서 전역적으로 고유해야 한다. 일반적으로 서로 다른 계정은 클라우드 파운드리의 경우 서로 다른 조직 또는 공간에 해당하고, 단일 쿠버네티스 클러스터의 경우 서로 다른 네임스페이스에 해당한다. 여러 플랫폼 상에서 태스크를 배포할 경우에도 태스크는 동일한 데이터베이스와 연결되도록 구성되어야 한다.

쿠버네티스 경우 계정을 설정하기 위해 SCDF 서버의 애플리케이션 설정 파일인 application.yaml에서spring.cloud.dataflow.task.platform.kubernetes 속성에 쿠버네티스 플랫폼 계정을 설정한다. SCDF 서버는 태스크 애플리케이션 실행 시 플랫폼 계정명을 --platformName 태스크 실행 옵션의 인자로 전달하며 기본값은 default가 사용된다.

쿠버네티스 상에서 여러 네임스페이스에 걸쳐 태스크를 실행할 수 있다. SCDF 서비스가 있는 default 네임스페이스가 존재하는 경우 동일한 default 네임스페이스에서 태스크 애플리케이션 파드를 실행할 수 있으며 다른 네임스페이스에서도 태스크 애플리케이션 파드를 실행할 수 있다. 새로운 네임스페이스를 생성한 후 spring.cloud.dataflow.task.platform.kubernetes.accounts.계정명 속성을 추가하고 spring.cloud.dataflow.task.platform.kubernetes.accounts.namespace.네임스페이스명 속성을 추가한다.


기타 플랫폼 구성

SCDF 서비스와 데이터 저장소는 쿠버네티스 클러스터 외부에 위치시키고 태스크 애플리케이션 파드는 쿠버네티스 클러스터의 기본 및 특정 네임스페이스 상에서 실행할 수 있다. 또는 특정 태스크 애플리케이션 파드는 쿠버네티스 클러스터의 네임스페이스에서, 다른 태스크 애플리케이션 파드는 클라우드 파운드리 조직 상의 공간 상에서 실행하는 방법도 있다.


데이터베이스 설정

SCDF는 H2, HSH2, HSQLDB, MySQL, Oracle, PostgreSQL, DB2, SQL Server 데이터베이스를 위한 스키마를 제공하며 해당 스키마링크를 사용하여 서버 시작 시 클래스패스에 제공된 데이터베이스 드라이버와 인증 정보를 통해 적절한 스키마가 자동 생성된다. 데이터베이스 스키마는 Flyway에 의해 관리되며 데이터베이스 사용자가 충분한 권한을 갖고 있는 경우 스키마를 통한 데이터베이스 초기 구성을 편리하게 할 수 있다. Flyway를 통한 자동 구성을 비활성화하고 수동으로 DDL 스키마를 사용하려면 다음 애플리케이션 속성을 설정한다.

spring.flyway.enabled=false


데이터플로우 서버에 자동으로 포함된 JDBC 드라이버는 MariaDB, MySQL, PostgreSQL, SQL Serve, Oracle이다. Oracle 드라이버는 2.10.x 버전 부터 추가 되었지만 의존성 스코프가 test이므로 운영 환경에서 사용하기 위해서는 커스텀 빌드가 필요하다링크.


SCDF 서버 커스텀 빌드

SCDF 서버의 커스텀 빌드가 필요할 수 있다. SCDF 서버는 spring-cloud-dataflow-server, spring-cloud-dataflow-server-core 등 여러 서브 모듈로 구성되어 있다. 서브 모듈들은 서로를 의존성으로 포함한다. 예를 들어, spring-cloud-dataflow-server는 다음과 같이 의존성을 갖는다.

spring-cloud-starter-dataflow-server
- spring-cloud-starter-dataflow-server
  - spring-cloud-dataflow-server-core
    - spring-cloud-dataflow-core


Oracle 드라이버를 추가하기 위해서는 spring-cloud-dataflow-server 루트 모듈의 pom.xml 파일을 수정하면 되며, 데이터베이스 접근과 관련된 JPA 기능의 수정이 필요하다면 spring-cloud-dataflow-server-core 서브 모듈을, JPA 엔티티의 수정이 필요하다면 spring-cloud-dataflow-core 서브 모듈을 수정하여 빌드하면 된다. 수정된 사항으로 SCDF 애플리케이션 빌드 시 최상위 모듈인 spring-cloud-dafaflow 모듈에 대해 메이븐의 ./maven clean install 명령어를 실행한다. SCDF 서버 애플리케이션 빌드 시 spring-cloud-dataflow-server 서브 모듈을 빌드한다.


시크릿 및 컨피그맵 설정

쿠버네티스 상에서 동작하는 SCDF 서버는 spring-cloud-kubernetes 모듈을 사용하여 /etc/secrets 경로에 마운트되어 있는 크레덴셜 데이터인 시크릿(Secret)을 처리한다. 논크레덴셜 데이터인 컨피그맵(ConfigMap)은 /config 경로에 application.yaml로 마운트되어야 하며, 해당 파일은 스프링 부트에 의해 처리된다.

쿠버네티스 API 서버에 대한 액세스를 방지하기 위해 SPRING_CLOUD_KUBERNETES_CONFIG_ENABLE_APISPRING_CLOUD_KUBERNETES_SECRETS_ENABLE_API 속성은 기본적으로 false로 설정되어 있다.

쿠버네티스의 시크릿과 컨피그맵을 사용하여 구성을 위한 속성값들을 SCDF 서버로 전달할 수 있다. 이를 통해 쿠버네티스가 서비스를 배포할 때 관련 속성들을 환경 변수로 설정할 수 있다. 예를 들어 데이터베이스의 연결 정보 중 호스트명과 포트를 컨피그맵에 설정하고 로그인 패스워드를 시크릿에 설정함으로써 속성값을 관리한다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: scdf-server
  labels:
    app: scdf-server
data:
  application.yaml:
    spring:
      cloud:
        dataflow:
          task:
            platform:
              kubernetes:
                accounts:
                  default:
                    limits:
                      memory: 1024Mi
      datasource:
        url: jdbc:mariadb://${MARIADB_SERVICE_HOST}:${MARIADB_SERVICE_PORT}/database
        username: root
        password: ${database-password}
        driverClassName: org.mariadb.jdbc.Driver
        testOnBorrow: true
        validationQuery: "SELECT 1"


롤, 롤 바인딩, 서비스 어카운트 설정

쿠버네티스 환경에서 SCDF 서버가 태스크 애플리케이션을 배포하는 작업을 수행하는 서비스 어카운트(ServiceAccount)를 설정할 수 있다. SCDF 서버는 태스크 애플케이션의 배포를 위해 쿠버네티스 클러스터 내 리소스에 대한 접근이 필요하다. 서비스 어카운트를 사용하여 SCDF 서버 애플리케이션이 필요로 하는 최소한의 권한만 부여함으로써 서버의 동작을 제한하여 보안 위협을 최소화하는 것이 좋다.

기존 서비스 어카운트를 사용하거나 새 어카운트를 생성한 후 설정할 수 있다. 다음과 같이 태스크 애플리케이션 마다 디플로이먼트 서비스 어카운트 프로퍼티를 설정한다.

deployer.<애플리케이션명>.kubernetes.deploymentServiceAccountName=서비스어카운트명


전역적으로 서비스 어카운트 명을 설정하려면 다음과 같이 SCDF 서버의 애플리테이션 프로퍼티를 설정한다.

data:
  application.yaml: |-
    spring:
      cloud:
        dataflow:
          server:
            platform:
              kubernetes:
                accounts:
                  default:
                    deploymentServiceAccountName: 서비스어카운트명

쿠버네티스 클러스터 내에 SCDF 서버 애플리케이션과 태스크 애플리케이션이 서로 다른 네임스페이스에 위치하고 클러스터 롤(ClusterRole)에 의한 리소스 접근이 불가능한 경우 이미지 풀, 파드 디플로이 등을 통한 리소스 제어 시 권한 문제가 발생할 수 있다. 예를 들어, SCDF 서버 애플리케이션이 네임스페이스 A에 위치하고 태스크 애플리케이션의 컨테이너 이미지 풀, 파드 디플로이가 네임스페이스 A에서 수행되지만 태스크 애플리케이션의 컨테이너 이미지 빌드가 네임스페이스 B에서 수행되는 경우 SCDF 서버 애플리케이션이 태스크 애플리케이션의 컨테이너 이미지 풀을 수행하기 위해 위해서 서비스 어카운트에 대한 롤 바인딩(RoleBinding) 설정이 필요하다. 네임스페이스 B에서 이미지 풀과 관련된 롤에 대해 롤 바인딩을 추가한다. 이미지 풀과 관련된 롤 정보는 플랫폼 마다 다를 수 있다.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: image-pull-role-binding
subjects:
  - kind: ServiceAccount
    name: default
    namespace: namespace-a
roleRef:
  kind: ClusterRole
  name: image-pull-role
  apiGroup: rbac.authorization.k8s.io


이미지 풀 정책 설정

디플로이어가 도커 이미지를 내려받고 태스크 애플리케이션을 배포하는 경우 배포 관련 여러 속성 중 도커 이미지 풀 관련 정책을 설정할 수 있다. 다음 세 정책이 존재한다.

  • IfNotPresent: 이미지가 이미 존재하는 경우 이미지를 내려받지 않는다. 기본 설정값이다.
  • Always: 이미지가 이미 존재하는지 여부에 관계없이 항상 이미지를 내려받는다.
  • Never: 이미지를 내려받지 않고 이미 존재하는 이미지만 사용한다.


애플리케이션 별로 이미지 풀 정책을 설정하기 위해 다음과 같이 애플리케이션 속성 파일에 속성을 설정함으로써 애플리케이션 수준에서 구성할 수 있다.

deployer.<애플리케이션명>.kubernetes.imagePullPolicy=이미지풀정책명


또는 디플로이먼트 YAML 파일에서 container.env에 이미지 풀 정책명을 설정하여 서버 수준에서 구성할 수도 있다.

apiVersion: v1
kind: Deployment
metadata:
  name: scdf-server
  labels:
    app: scdf-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: scdf-server
  template:
    metadata:
      labels:
        app: scdf-server
    spec:
      containers:
      - name: task-app
        image: task-app:latest
        env:
        - name: SPRING_CLOUD_DEPLOYER_KUBERNETES_IMAGE_PULL_POLICY
          value: Always


스케줄링

스케줄(Schedule) 생성 시 플랫폼을 지정함으로써 서로 다른 플랫폼 상에서 실행되는 태스크의 스케줄링이 가능하다. 크론 표현식을 설정하여 태스크의 실행을 스케줄링할 수 있다.

RESTful API를 사용하거나 SCDF 대시보드 상에서 직접 스케줄 생성이 가능하다. SCDF는 클라우드 플랫폼에서 사용 가능한 스케줄링 에이전트를 통해 태스크 실행을 스케줄링한다. 쿠버네티스 플랫폼의 경우 크론잡(CronJob)을, 클라우드 파운드리 플랫폼의 경우 PCF 스케줄러를 스케줄링 에이전트로 사용한다.

SCDF 서버에서 태스크 스케줄링은 기본적으로 활성화되어 있다. 스케줄 별로 속성 설정이 가능하며, 이 경우 태스크 애플리케이션의 개별 속성이 전역 서버 수준 속성 설정보다 우선한다.


모니터링

프로메테우스(Prometheus)와 그라파나(Grafana)를 사용하여 SCDF 서버와 태스크 애플리케이션의 모니터링이 가능하다. 프로메테우스를 통해 모니터링 메트릭을 수집하기 위해서는 메트릭에 대해 구성된 엔드포인트를 자동으로 조사하기 위한 서비스 디스커버리 구성 요소가 필요하다. 서비스 디스커버리(service discovery)란 서비스 레지스트리에 등록된 서비스(또는 서비스와 관련된 정보)를 검색 또는 탐색하는 과정이다. SCDF 서버는 서비스 디스커버리 메커니즘을 위해 프로메테우스 R소켓 프록시를 사용한다. R소켓(RScoket)은 TCP, 웹소켓(WebSocket) 및 에어론(Aeron)과 같은 바이트 스트림 전송을 위한 바이너리 프로토콜이다. R소켓 프록시를 사용하여 SCDF 서버 뿐만 아니라 SCDF 서버가 배포하는 태스크 애플리케이션에 대한 모니터링도 가능하다.

애플리케이션(클라이언트)과 프록시 인스턴스 간 지속적인 양방향 R소켓 연결을 설정하여 메트릭을 수집할 수 있다. 지속적인 메트릭 수집이 필요한 상시 가동 중인 애플리케이션과 달리 단기 애플리케이션에 대한 메트릭 수집을 위해 프록시의 역할이 필요하다.

프로메테우스는 각각의 프록시 인스턴스를 스크랩하도록 구성되며, 프록시는 R소켓 연결을 사용하여 각 애플리케이션으로부터 메트릭 정보를 가져온다. 따라서 데이터 플로우 서버와 태스크 애플리케이션들의 메트릭 데이터를 프록시로부터 프로메테우스가 가져가게 하기 위해서는 애플리케이션 상에 프로메테우스 R소켓 구현이 필요하다.

프로메테우스 R소켓 프록시 동작 방식 및 구현은 다음과 같다. 프로메테우스는 애플리케이션 인스턴스가 아닌 프록시 인스턴스의 /metrics/connected, /metrics/proxy 엔드포인트를 스크랩하도록 구성한다. 하나 이상의 프로메테우스 R소켓 프록시 인스턴스와 애플리케이션 간 지속적인 양방향 R소켓 연결 설정을 하고 프로메테우스는 각 프록시 인스턴스를 스크랩하도록 구성하면 프록시는 차례로 연결을 사용하여 각 애플리케이션 메트릭 정보를 가져오게 되고 이를 그라파나 대시보드를 통해 시각화할 수 있다. 프록시가 프로메테우스로부터 스크랩 요청을 받으면 요청/응답 시퀀스를 사용하여 각각의 R소켓 연결에서 메트릭을 가져오며 각 연결 결과는 하나의 응답으로 이어져 프로메테우스에 나타난다.

스프링 부트 애플리케이션에서 자동 구성을 통해 클라이언트와 프록시 간 통신을 수행하기 위해 다음 의존성을 추가한다.

implementation ‘io.micrometer.prometheus:prometheus-rsocket-spring:VERSION’


모니터링 구성 과정

  1. 쿠버네티스에서 프록시, 프로메테우스, 그라파나 서비스 실행
  2. 프로메테우스의 스크랩 설정: https://github.com/micrometer-metrics/prometheus-rsocket-proxy/blob/main/scripts/kubernetes/prometheus/01-prometheus-configmap.yaml
  3. 모니터링을 위한 환경 변수 설정
    • 스프링 클라우드 데이터 플로우 서버
      • 필수 속성
        • MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true
        • MANAGEMENT_METRICS_EXPORT_PROMETHEUS_RSOCKET_ENABLED=true
        • MANAGEMENT_METRICS_EXPORT_PROMETHEUS_RSOCKET_HOST=프로메테우스프록시애플리케이션
        • SPRING_CLOUD_DATAFLOW_METRICS_DASHBOARD_URL=그라파나URL
          • 동일한 클러스터 내 통신일 경우 포트 제외
      • 선택 속성
        • MANAGEMENT_METRICS_EXPORT_PROMETHEUS_RSOCKET_PORT=7001
    • 배치 애플리케이션
      • 필수
        • management.metrics.export.prometheus.rsocket.host=프로메테우스프록시애플리케이션
        • management.metrics.export.prometheus.rsocket.port=7001
  4. 그라파나 대시보드 설정: https://github.com/spring-cloud/spring-cloud-dataflow/tree/b6d094924d86fff3530cf83aefe6530f8ce10a55/src/grafana/prometheus/docker/grafana/dashboards


연속 배포

애플리케이션 실행 시 지정된 리소스 URL로부터 이미지를 받아 애플리케이션(파드)을 실행한다.


SCDF 서버 디플로이먼트 환경 변수

  • 속성 바인딩: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding
    • -는 제거
    • ._
    • 스네이크 케이스는 단어 사이에 _
  • JVM 인자
    • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_JAVA_OPTS
  • 계정 설정 및 배포(쿠버네티스 디플로이어) 구성 설정
    • 계정 설정: SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명)
      • 하위 설정
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_NAMESPACE
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_TASK_SERVICE_ACCOUNT_NAME
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_IMAGE_PULL_POLICY
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_IMAGE_PULL_SECRET
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_ENTRY_POINT_STYLE
    • 배포 설정: SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_DEPLOYMENT
      • 하위 설정
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_DEPLOYMENT_JAVA_OPTS
        • SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_KUBERNETES_ACCOUNTS_계정명_DEPLOYMENT_SERVICE_ACCOUNT_NAME
  • 데이터베이스 설정
    • SPRING_DATASOURCE_URL
    • SPRING_DATASOURCE_USERNAME
    • SPRING_DATASOURCE_DRIVER_CLASS_NAME
    • SPRING_DATASOURCE_INITIALIZATION_MODE
    • SPRING_DATASOURCE_PASSWORD
  • 레지스트리 설정 (Harbor)
    • SPRING_CLOUD_DATAFLOW_CONTAINER_REGISTRY-CONFIGURATIONS_HARBOR_REGISTRY_HOST
    • SPRING_CLOUD_DATAFLOW_CONTAINER_REGISTRY-CONFIGURATIONS_HARBOR_USER
    • SPRING_CLOUD_DATAFLOW_CONTAINER_REGISTRY-CONFIGURATIONS_HARBOR_AUTHORIZATION_TYPE
    • SPRING_CLOUD_DATAFLOW_CONTAINER_REGISTRY-CONFIGURATIONS_HARBOR_SECRET


Troubleshooting

  1. management.metrics.tags.application: ${spring.cloud.task.name:unknown}-${spring.cloud.task.executionid:unknown}
    
  2. 그라파나 Tasks 대시보드 상에 일부 메트릭 정보가 출력되지 않음
    • 원인: active 메트릭 변수만 수집되고 있음
    • spring_batch_job_active_seconds_active_count
    • spring_batch_job_active_seconds_duration_sum
    • spring_batch_job_active_seconds_max
    • spring_cloud_task_active_seconds_active_count
    • spring_cloud_task_active_seconds_duration_sum
    • spring_cloud_task_active_seconds_max


참고

Comments