전체 글

276

오늘도 상쾌한기분

Kotlin·Java K8s CronJob 기반 Spring Batch, Argo Workflows로 전환하기 - 4편: 전환 후 6개월간 운영해본 회고 앞서 3편의 글에서 K8s CronJob 기반으로 실행하던 Spring Batch를 Argo Workflwos로 전환하는 과정에 대해 정리했고 실제 서비스도 전환한 지 약 반년 정도 지났다.이번 글에서는 6개월 정도 실제로 운영해보며 예측하지 못해 문제가 있었는지, 어떤 장점이 있었는지, 아쉬운 부분등이 있었는지에 대해 정리해보려고 한다.1. 가장 걱정했던 부분으로 OOM에 취약한 구조Batch는 기능상 다른 Application들에 비해서 정확하게 수행해야하는 중요한 기능들이 많고 또 정해둔 스케줄에 맞춰서 동작하는게 중요하다.전환 당시 걱정했던 부분 중 하나로 Batch Job들이 Pod이나 Application OOM에 취약하게 열려 있는 점이였고 실제로 운영하면서 OOM이 발생한 적이 있었다. 그..
보안 타이밍 어택, 어디까지 막아야 할까? == 비교부터 프레임워크 CVE까지 타이밍 어택, 어디까지 막아야 할까? == 비교부터 프레임워크 CVE까지아래는 어디서나 볼 법한 비교 코드다.if request_value != secret_value: raise ...if user: user.check_password(raw_password)별 문제 없어 보인다. 그런데 이 코드는 응답 시간만으로 정보를 제공해 줄 수 있다. 어떻게 그럴수 있는지 알아보자.1. 타이밍 어택(Timing attack)이란?타이밍 어택은 이름 그대로 어플리케이션이 어떤 일을 처리하는 데 걸리는 시간을 관찰해 취약점을 알아내는 공격이다. 사이드 채널 어택 중 하나다. 핵심은 입력에 따라 처리 시간이 달라진다는 데 있다. 서버의 시크릿 값이나 로직을 잘 몰라도, 응답 시간에 따라 결과를 유추하다는 ..
코드 품질/테스트 AI 코딩 에이전트 git worktree 병렬 개발의 테스트 인프라, Testcontainers로 전환하기 - 2편 AI 코딩 에이전트 git worktree 병렬 개발의 테스트 인프라, Testcontainers로 전환하기 - 2편이전 1편은 worktree 병렬 에이전트 개발이 공유 테스트 인프라에서 격리가 안되고 있다는 문제점을 정의하고, 컨테이너 라벨에 worktree 식별자를 넣어 reuse의 해시 매칭을 격리 수단으로 뒤집는 설계까지 정리했다. 이제는 구현이다.1. Gradle 라이브러리 추가현재 프로젝트는 별도 테스트 모듈을 두고 있어서, 테스트 모듈에서 implementation으로 선언한 뒤필요한 모듈에 testImplementation(project())를 선언하는 방식으로 진행했다.현재 프로젝트에 맞춰서 필요한대로 선언해서 사용하면 될 것 같다.implementation("org.springfram..
코드 품질/테스트 AI 코딩 에이전트 git worktree 병렬 개발의 테스트 인프라, Testcontainers로 전환하기 - 1편 AI 코딩 에이전트 git worktree 병렬 개발의 테스트 인프라, Testcontainers로 전환하기 - 1편git worktree, Testcontainers, 멀티모듈 프로젝트에 대해 기본적으로 알고 있는 조건을 전제로 하고 있습니다. git worktree 혹은 Testcontainers 등에 대해 잘 모른다면 공식 문서나 검색해서 먼저 개념을 알기를 권합니다.업무를 점차 코딩 에이전트 중심으로 옮기고 있고, 개발은 git worktree 기반 하네스로 돌아간다. 현재 방식은 기능별 브랜치마다 worktree를 만들고, 각 worktree 안에서 구현 이후 테스트 에이전트가 테스트로 검증하는 구조다. 여러개의 클로드 코드를 동시에 실행하고 있는데 테스트 에이전트들이 동시에 돌기 시작하면 코드..
코드 품질/테스트 Chrome Local Overrides로 API 응답을 변경하고 UI를 테스트하는 방법 Chrome Local Overrides로 API 응답을 변경하고 UI를 테스트하는 방법백엔드 API와 프론트엔드 UI 연동 작업이 완료되면 개발 환경에서 연동 결과를 확인하는 과정이 필요하다. 요구사항을 기준으로 개발을 진행하더라도, 요구사항 문서 작성자와 백엔드, 프론트엔드 개발자가 모두 다르기 때문에 같은 내용을 서로 다르게 해석할 가능성이 있다. 특히 조건이 복잡한 요구사항일수록 이러한 차이가 발생하기 쉽고, 그 결과 화면에서는 예상하지 못한 UI 차이가 발생할 수 있다.문제는 API 응답 값에 따라 화면이 다양한 형태로 변경되는 경우다. 예를 들어 데이터가 없는 경우, 개인화, 오류 처리, UI 분기에 사용되는 필드 값 등 여러 상황을 최소 한번씩은 확인해야 한다.이러한 케이스를 확인하기 위해서..
기록 맛있는 치킨스톡 티비나 유튜브에 종종 나오곤 했던 치킨스톡. 항상 치킨스톡을 보면 실제로 먹어보지 못했기 때문에 무슨 맛인지 궁금 했었다. `도대체 어떤 맛이길래 저렇게 호들갑을 떠는거지??` 생각을 해오곤 했는데, 겨울 즈음 어쩌다 생각이나서 치킨스톡을 직접 구매해보았다. 인터넷 검색ㅎ 배뇌 `이금기 치킨스톡`이 제일 유명하길래 이 제품으로 구매했다.처음에는 `어디에 치킨스톡을 넣어서 먹는거지?` 했는데 라면이나 파스타에 넣어도 맛있다는 글을 보고 조금씩 넣어서 해먹어봤는데 이제 치킨스톡 안 넣고 먹지 못하는 몸이 되버렸다.치킨스톡 궁금해서 사봄라면이나 파스타에 치킨스톡 넣어서 먹어봄이제 치킨스톡 없이 라면 못먹는 몸이 됨
기록 출근길, 직우차로 한대의 경찰차 그냥 살면서 인상 깊었던 일 등 이모저모 기록처럼 적어보려고 한다. 오늘은 출근길에 목격한 상황이다.우선 직우차로 맨 앞에 경찰차 한 대가 정차해 있었고 차량 신호등은 초록불이었다. 좌회전, 직진, 우회전 모두 갈 수 있는 신호였다.경찰차는 움직이지 않고 계속 서 있었었고 갓길에 비켜서 세운 것도 아니고, 주행선 한가운데에 서 있었다.경찰차 뒤에 있는 차들은 가지 못하는 상황이었다.평소 였으면 뒤에서 클락션 울리면서 진짜 쌩개지랄을 했을텐데 누구도 클락션 누르지 않더라.경찰차가 안 가고 멈춰 서 있으니, 결국 뒤차들이 옆 차선 차량들이 초록불로 빠진 틈을 타서 차선을 넘어간채로 우회전 주행을 하기 시작했다.그렇게 2대가 2차선으로 넘어가서 2차선에서 우회전을 하고 빠져나갔다.이어 3번째 차량이 차선을 넘..
보안 유출된 AWS AccessKey 무중단 교체하기: 출근길에마주한 IAM 유저 생성 시도 알림 유출된 AWS AccessKey 무중단 교체하기: 출근길에마주한 IAM 유저 생성 시도 알림오늘도 어김없이 집에 가고 싶은 평범한 출근길 중 슬랙 메시지가 왔다. 보통 출근 시간에 슬랙 메시지가 오는 일은 정말 드문데... "잉? 뭐지?" 라는 생각과 함께 메시지를 열어보았고, 메시지는 "심상치 않은데?" 내용이 있었다.(자세히 보면 로그에 opencode 가 있다. 뭔가 에이전트 돌린걸까나?)누군가 나만의 소중한 AWS IAM 계정의 AccessKey를 가지고 유저 생성을 시도했다는 알림이었다!사무실에 출근하자마자 상황 파악부터 시작했고, 당연히 회사 사람은 아무도 아니었다. 어디선가 유출된 AccessKey로 누군가 IAM 유저 생성을 시도했고 거부당한 상태였다. 다행히 해당 IAM 계정은 오직 S3..
Kotlin·Java K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 3편: HikariCP 설정으로인한 Socket 메모리 누수 K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 3편: HikariCP 설정으로인한 Socket 메모리 누수2편 글 마지막 부분에서 'HikariCP 설정 문제로 인해 메모리 누수가 발생하는 것 같다'고 작성했었고, 이 예상이 맞다면 다음 글을 이어 쓰겠다고 했었다. 슬프게도 그 불길한 예감은 틀리지 않았다. 결국 이렇게 3편 글을 작성한다. 미래의 나, 혹은 이 글을 읽는 사람들은 같은 실수를 반복하지 않았으면 좋겠다.힙 덤프 비교 분석 결과를 공유 하지만 이게 기존 OOMKilled의 주요 원인은 아닐 것 이라 생각하고는 있다. (보조 원인 정도는 되려나?) 발생 초창기에 논힙 문제로 추측 했었고 논힙 메모리 여유를 주는 초동 조치를 진행했었다. 발견한 객체로 메모리..
Kotlin·Java K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 2편: K8s 팟 힙 덤프 추출과 논힙 메모리 추적 K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 2편: K8s 팟 힙 덤프 추출과 논힙 메모리 추적지난 1편에서 K8s 환경에서 운영 중인 Spring Boot 애플리케이션 컨테이너에 발생한 OOMKilled 초동 조치 작업에 대한 글을 작성 했었다.https://sanggi-jayg.tistory.com/entry/K8s-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EB%B0%9C%EC%83%9D%ED%95%9C-Spring-Boot-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-OOMKilled-%EC%B6%94%EC%A0%81%EA%B8%B0-1 K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기..
Kotlin·Java K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 1편: OOM 레벨 구분과 QoS 확인 K8s 환경에서 발생한 Spring Boot 컨테이너 OOMKilled 추적기 - 1편: OOM 레벨 구분과 QoS 확인 서비스 운영 중 모니터링 알람이 울려 확인해 보니, K8s 환경에서 구동 중인 Spring Boot 애플리케이션 컨테이너에서 OOM이 발생했다.처음에는 단순히 '메모리가 부족한가?' 생각했지만, 원인을 파악하는 과정은 역시나 복잡했다. 이번에는 OOM 현상의 원인을 추적해 나갔던 과정을 정리해 보고자 한다. 미래의 나, 혹은 비슷한 문제를 겪고 있을 누군가에게 도움이 되길 바란다.OOM 발생 레벨 확인하기 문제 해결을 위해 가장 먼저 확인한 것은 OOM이 발생한 영역의 레벨이었다. Spring Boot 애플리케이션이 컨테이너 환경에서 OOM이 발생했다면 크게 두 가지 경우로 나누..
Kotlin·Java K8s CronJob 기반 Spring Batch, Argo Workflows로 전환하기 - 3편: Argo Workflows로 스케줄링하기 K8s CronJob 기반 Spring Batch, Argo Workflows로 전환하기 - 3편: Argo Workflows로 스케줄링하기전체 데모 소스 코드는 https://github.com/sanggi-wjg/kotlin-spring-boot-demos/tree/main/spring-batch-argo-workflows 에서 확인할 수 있습니다.1. Argo Workflows 간단 소개Argo Workflows는 K8s native 워크플로우 엔진이며 CRD(Custom Resource Definition) 기반으로 동작하기 때문에 별도 인프라 없이 K8s 클러스터 안에서 바로 사용할 수 있다. 이 부분은 K8s를 사용하는 환경에서 정말 편하게 사용할 수 있다.이 글에서 사용하는 핵심 개념을 간단..