본문 바로가기

분류 전체보기

(35)
[Jenkins] 파이프라인 나누기(Upstream / Downstream) 지금까지 우리는 하나의 거대한 Jenkinsfile 안에 빌드, 테스트, 소나큐브 검사, 도커 이미지 푸시, K8s 배포까지 모든 로직을 한곳에 집중시키는 단일 파이프라인(Monolithic Pipeline) 방식을 배웠습니다. 프로젝트 규모가 작을 때는 이것이 편합니다. 하지만 회사가 성장하여 수십 개의 마이크로서비스(MSA)가 얽히고, "A 서비스와 B 서비스가 모두 성공적으로 빌드된 후에야 C라는 통합 결제 서버를 빌드하고 배포하라"는 극악의 워크플로우(Workflow) 요구사항이 떨어지면 어떻게 될까요? 이 모든 것을 파일 하나에 욱여넣으면 코드는 2천 줄이 넘어가고, 중간에 작은 에러 하나만 터져도 2천 줄짜리 거대 공장이 통째로 멈춰버리는 끔찍한 사태가 발생합니다.이번 글에서는 "크고 뚱뚱한 ..
[Jenkins] Node.js 다중 버전 환경 완벽 통제 가이드 엔터프라이즈 환경에서 젠킨스(Jenkins) 서버 단 1대로 수십 개의 파이프라인을 운영하다 보면 필연적으로 '버전 충돌(Version Conflict)'이라는 거대한 장벽에 부딪히게 됩니다. 가장 대표적인 생태계가 바로 프론트엔드의 Node.js 입니다. 5년 전에 만들어진 구형 레거시 어드민 프로젝트는 반드시 Node.js v14 환경에서만 빌드되며, 오늘 새로 런칭한 최신 React 프로젝트는 Node.js v20 환경을 요구합니다. 만약 젠킨스 호스트 서버 리눅스에 apt-get install nodejs로 14 버전을 깔아버리면 새 프로젝트가 빌드 에러를 뿜고, 20 버전으로 올려버리면 레거시 프로젝트가 죽어버립니다. 이번엔 인프라 엔지니어를 골머리 앓게 만드는 "하나의 젠킨스 서버에서 수십 가..
[Jenkins] Trivy로 컨테이너 보안 취약점 차단하기 우리는 에서 코드를 도커 이미지(Docker Image)로 굽는 화려한 기술을 배웠습니다. FROM node:14-alpine 같은 베이스 이미지를 가져와서 무심코 컨테이너를 말아 올렸죠. 그런데 만약 그 베이스 이미지 안에 해커가 악용할 수 있는 치명적인 OpenSSL 해킹 취약점(예: Heartbleed)이나 탈취 가능한 루트 권한 버그가 심어져 있다면 어떨까요? 젠킨스가 아무리 배포를 잘해도, 결과적으로는 '보안 폭탄'을 운영 서버 한가운데에 아주 빠르고 정확하게 배달해 주는 꼴이 됩니다. 바야흐로 배포 파이프라인 내부에 보안(Security)을 욱여넣어 강제화하는 DevSecOps(개발-보안-운영)의 시대입니다. 이번에는 전 세계에서 가장 사랑받는 초경량 오픈소스 컨테이너 보안 스캐너인 'Triv..
[Jenkins] Retry 블록 네트워크 장애를 극복하는 파이프라인 CI/CD 자동화를 구축해 놓으면 퇴근 후에도 마음이 편할 줄 알았습니다. 하지만 밤 11시에 슬랙으로 [빌드 실패] 빨간 알람이 울려 부랴부랴 랩탑을 열어보면, 내 코드의 버그가 원인이 아닙니다. "Github에서 소스코드를 다운로드하다가 DNS를 못 찾음", "NPM Registry 서버가 잠시 응답하지 않음", "Docker Hub Rate Limit(속도 제한)에 걸려 이미지 pull 실패" 인프라 엔지니어가 통제할 수 없는 '외부 요인(네트워크 지연 및 타임아웃)' 때문에 파이프라인이 터지는 억울한 경우가 실무 빌드 실패의 절반 이상을 차지합니다. 억울하게 실패한 빌드를 데브옵스 담당자가 젠킨스 화면에 접속해 수동으로 'Rebuild' 버튼을 눌러주면 언제 그랬냐는 듯 쌩쌩하게 잘 돌아갑니다. ..
[Spring Boot] Apache Kafka 연동 MSA의 이벤트 주도 비동기 통신 배달 앱에서 고객이 치킨을 '결제'했다고 상상해 봅시다. 백엔드 시스템 내부에서는 어마어마한 일들이 순차적으로 벌어집니다.1. 주문 시스템에 접수2. 라이더 배차 시스템 호출3. 고객에게 카카오톡 알림 발송4. 쿠폰 소진 처리만약 결제 서버가 이 4개의 서버에게 일일이 HTTP(REST API)로 전화를 걸어 "야, 결제됐어! 일해!"라고 동기식(Synchronous)으로 통신하면 어떻게 될까요? 만약 카카오톡 알림 서버가 장애로 3초간 멈춰있다면, 결제 서버도 그 3초 동안 응답을 기다리며 멈춰있게 되고 결국 사용자의 화면은 하얗게 굳어버립니다. 하나의 서버 장애가 전체 시스템의 장애로 퍼지는 '도미노 붕괴(강한 결합)' 현상입니다. 이 끔찍한 의존성을 칼같이 끊어내기 위해 도입된 구원자가 바로 아파치..
[Spring Boot] 액추에이터 실시간 모니터링(Actuator) 열심히 개발한 스프링 부트(Spring Boot) 서버를 무사히 라이브(Live) 환경에 배포했습니다. 그런데 배포 후 3일째 되는 날, 유저 한 명이 "홈페이지가 엄청 느려요!"라고 게시판에 불평을 남겼습니다. 이 말을 들은 개발자는 등골이 오싹해집니다. "서버 메모리가 다 차서 느려진 건가? 아니면 DB 커넥션이 부족한가? 혹시 특정 API가 유독 늦게 응답하는 건가?" 원인을 찾기 위해 리눅스 서버에 SSH로 접속해서 top 명령어를 치거나, 끝도 없이 올라가는 로그 텍스트를 눈알이 빠지도록 쳐다보는 것은 원시 시대의 방식입니다. 서버 스스로가 자신의 건강 상태(Health), 메모리, CPU 사용량, DB 연결 상태, 최근 100개의 HTTP 요청 내역 등을 완벽한 JSON 데이터로 뱉어내 주면 ..
[Spring Boot] 파일 업로드와 AWS S3 클라우드 사용하기 게시판에 사용자가 10MB짜리 고화질 사진을 첨부하여 글을 작성합니다. 초보 시절에는 MultipartFile 객체를 받아 스프링 부트(Spring Boot)가 구동되고 있는 로컬 서버의 C:\upload 디렉토리나 리눅스 /var/www/images 폴더에 file.transferTo() 코드로 저장(Save)하는 방식을 썼습니다. 서버가 딱 1대일 때는 이 방식이 기가 막히게 잘 돌아갑니다. 하지만 대박이 터져서 서버를 3대(A, B, C)로 스케일 아웃(Scale-out)하는 순간 지옥문이 열립니다. 사용자가 A서버에 접속해 프로필 사진을 올렸는데, 내일 다시 접속할 땐 로드밸런서가 B서버로 연결해 주면? B서버 디스크에는 사진이 없으므로 화면에 끔찍한 '엑스박스(이미지 깨짐)'가 뜹니다. 게다가 ..
[Spring Boot] 트랜잭션 롤백과 전파 속성 은행 앱에서 A가 B에게 10만 원을 송금하는 상황을 상상해 봅시다. 서버는 두 가지 쿼리를 실행합니다.1. A의 통장에서 10만 원 차감 (UPDATE)2. B의 통장에 10만 원 증가 (UPDATE)그런데 1번 쿼리가 성공한 직후, 갑자기 데이터베이스 서버의 전원이 나갔습니다! A의 돈은 10만 원이 증발했는데, B는 돈을 받지 못했습니다. 뉴스에 대서특필될 만한 엄청난 사고입니다. 이런 대형 사고를 막기 위해 데이터베이스는 "1번과 2번 쿼리를 하나로 묶어라. 둘 다 성공할 때만 최종 반영(Commit)하고, 하나라도 실패하면 1번 쿼리도 아예 없었던 일로 롤백(Rollback) 시켜라!"라는 논리적 작업 단위를 제공하는데, 이것이 바로 트랜잭션(Transaction)입니다. 스프링 부트(Sprin..
[Spring Boot] OAuth 2.0 소셜 로그인 구현(카카오 네이버 구글 로그인) 인터넷 쇼핑몰이나 새로운 서비스에 접속했을 때, 여러분은 긴 회원가입 폼을 성실하게 채우시나요, 아니면 "카카오로 1초 만에 시작하기" 버튼을 누르시나요? 바쁘고 귀찮은 것을 극도로 싫어하는 현대의 유저들에게 자사몰의 독자적인 회원가입(ID/PW)을 강요하는 것은 곧 '고객 이탈'을 의미합니다. 이러한 이탈을 막기 위해 구글, 카카오, 네이버 같은 거대 IT 기업들이 유저의 신원을 대신 확인해 주고 우리 서버에 "이 사람 진짜 맞아!"라고 보증을 서주는 기술이 등장했습니다.바로 OAuth 2.0 (Open Authorization) 프로토콜입니다. 그리고 스프링 부트(Spring Boot) 진영에는 이 복잡한 프로토콜 통신을 아주 우아하게 캡슐화해 놓은 spring-boot-starter-oauth2-c..
[Spring Boot] Spring Security - JSON Web Token 구현 앞선 에서 우리는 스프링 시큐리티(Spring Security)의 위대한 필터 체인(Filter Chain)과 전통적인 폼 로그인(Session/Cookie 방식)을 마스터했습니다. 세션 기반 로그인은 보안성이 높고 구현이 편하지만, 현대의 트렌드인 '모바일 앱(iOS/Android) 통신'과 서버 수십 대를 띄우는 '마이크로서비스(MSA) 스케일 아웃' 환경을 만나면 치명적인 약점을 드러냅니다. 사용자가 서버 A에 로그인하여 세션을 만들었는데, 다음 요청이 서버 B로 향하면 서버 B는 "너 누구야?" 라며 로그아웃 시켜버리기 때문입니다(세션 불일치).이 골치 아픈 '상태 유지(Stateful)'의 사슬을 끊어내고, 서버가 사용자 정보를 기억할 필요 없이 "네가 가진 암호화된 방문증(Token)만 보여주..