Engineering without borders: From core backend to Kubernetes, MLOps, and Everything.
종료 지향 워크로드와 Kubernetes의 철학적 경계 (CRD를 만들며 배운 것들)
Job 관련 CRD를 계속 개발하다 보면 어느 순간 “왜 이게 이렇게 안 맞지?“라는 느낌을 받게 된다. 도구가 잘못된 건지, 설계가 잘못된 건지, 아니면 제가 뭔가 놓치고 있는 건지. 이 글은 그 느낌의 근원을 추적하다가 도달한 하나의 결론에 대한 이야기입니다. 회사에서 Job 관련 워크로드를 만들면서 부딪힌 마찰들이 모두 같은 뿌리에서 나왔다는 사실을 뒤늦게 깨닫게 되었습니다. Kubernetes의 본질 Kubernetes를 사용하다 보면 “선언적"이라는 단어를 자주 듣는다. 하지만 선언적이라는 말보다 더 정확한 표현은 level-triggered reconciliation라고 봅니다. ...
Elasticsearch Lucene Write Lock 문제 해결 가이드 - CSI 장애와 StatefulSet 복구
TL;DR 단일 CSI를 활용하여 Elasticsearch Volume 운영 시 CSI에 이상이 생기면 모든 인덱스에서 Lucene write.lock 충돌이 발생하여 클러스터 마비가 발생할 수 있습니다. 각 PVC에서 오염된 write.lock 파일을 제거하면 해결 가능합니다. 단일 CSI를 사용하는 구조는 이런 위험에 상시 노출됨. 아키텍처 레벨에서 근본적인 해결이 필요합니다. (Network Storage → Local NVMe) 문제 개요 Elasticsearch Pods가 Ready 상태가 되지 않으며, 모든 인덱스에서 Lucene write.lock 파일 충돌. ...
Kubernetes 컨테이너에서 MIG 활성화된 GPU 메모리 정보를 안전하게 조회하기
멀티 테넌트 클러스터에서 NVIDIA H100 같은 MIG를 지원하는 GPU를 MIG(Multi‑Instance GPU) 모드로 분할해 사용하면, 컨테이너 내부에서 nvidia-smi 또는 PyNVML 로 전체 GPU(Parent GPU) 메모리 정보를 조회할 때 Insufiicient Permissions오류가 발생할 수 있습니다. 이 글에서는 오류가 발생하는 구조적 이유 컨테이너에 MIG 모니터 권한을 부여해 문제를 해결하는 방법 보안 관점의 모범 사례 를 단계별로 설명합니다. 1. 증상 재현 1‑1. nvidia-smi 오류 $ nvidia-smi --query-gpu=gpu_name,memory.total --format=csv,noheader NVIDIA A100-PCIE-80GB, [Insufficient Permissions] NVIDIA A100-PCIE-80GB, 81920 MiB ... 1‑2. PyNVML 오류 handle = pynvml.nvmlDeviceGetHandleByIndex(0) pynvml.nvmlDeviceGetMemoryInfo(handle) # → pynvml.nvml.NVMLError_NoPermission: Insufficient Permissions Parent GPU를 호출하면 NVML 이 NVML_ERROR_NO_PERMISSION 을 반환하기 때문입니다. ...
GCP에 VM으로 직접 쿠버네티스 클러스터 구축하는 방법
쿠버네티스(Kubernetes)는 컨테이너화된 애플리케이션의 자동 배포, 스케일링, 운영을 위한 강력한 오케스트레이션 플랫폼입니다. 클라우드 네이티브 환경에서는 관리형 쿠버네티스 서비스(GKE, EKS, AKS 등)를 사용하는 것이 일반적이지만, 직접 구축하는 과정을 통해 쿠버네티스의 아키텍처를 알아 봅시다. 이 가이드에서는 Google Cloud Platform(GCP) 가상 머신에 kubeadm을 사용하여 쿠버네티스 클러스터를 구축하는 전체 과정을 설명합니다. 버전 호환성 주의 본 문서는 kubeadm v1.33을 기준으로 작성되었습니다. 일치하는 버전이 아닌 경우 항상 공식 문서를 확인하세요. 알려진 문제점: Ubuntu 22.04 LTS + Kubernetes v1.32 커널 6.8.0-56-generic 이상에서 iptables의 MARK 확장 기능에 회귀(regression) 버그가 존재하여 Failed to execute iptables-restore 오류가 발생할 수 있습니다. Ubuntu 24.04 LTS와 Kubernetes v1.33 이상에서는 정상 동작이 확인되었습니다. ...
AWS S3 버킷 보안 세팅 문제 해결
TL;DR boto3를 사용하여 S3에 저장할 때는 default_acl 설정을 확인해야 한다. ...
pg_stat_statements로 쿼리 성능 모니터링하기
pg_stat_statements 모듈은 PostgreSQL에서 쿼리 실행 통계 정보를 수집하고 분석하는 모듈이다. 이 모듈을 활성화하면 쿼리의 실행 횟수, 실행 시간, 실행 계획 등의 정보를 수집할 수 있다. 이를 통해 쿼리 성능을 모니터링하고 성능이 저하되는 쿼리를 찾아 최적화할 수 있다. 수집하는 정보는 다음과 같다. 쿼리 실행 횟수 (calls) 총 실행 시간 (total_time): 평균수행시간 * 실행횟수, 단위: ms 평균 실행 시간 (mean_time) 평균 블록 시간 (mean_blk_time) 행 수 (rows) 평균 행 수 (mean_rows) 등 위 데이터로 가장 자주 실행된 쿼리, 가장 오래 실행된 쿼리, 가장 많은 시간을 소비한 쿼리 등을 찾을 수 있다. 이를 토대로 성능이 저하되는 쿼리를 찾아 성능 개선을 시도해볼 수 있다. ...
Django에서 DB Connection 관리
서비스를 운영하다보면 DB Connection 관리에 대한 이슈가 종종 발생한다. 이번 포스팅에서는 DB 커넥션 풀 (DB Connection Pool)과 Django에서는 DB 커넥션을 어떻게 관리하는지 알아보겠다. DB Connection Pool DB와 애플리케이션 사이에서 DB 연결을 간소화하기 위해서 DB와 미리 연결한 커넥션(Connection) 객체들을 풀(Pool)에 저장해두었다가 요청이 들어오면 풀에서 유휴 커넥션을 꺼내 사용하고 다시 풀에 저장하는 방식을 말한다. 애플리케이션과 DB의 TCP 연결을 위해서는 3-way-handshaking이 필요하다. 매 연결마다 이를 수행하면 비용이 커지므로 비용을 줄이기 위해 DB Connectio Pool 방식을 사용한다. ...
AWS ECR로 Docker 이미지 관리하기
AWS ECR은 도커 허브와 같은 컨테이너 이미지 레지스트리 서비스다. AWS IAM 계정을 사용하여 프라이빗(Private) 리포지토리를 사용할 수 있고 AWS CLI를 이용하여 도커 이미지를 리포지토리에 푸시(Push), 풀(Pull), 삭제할 수 있다. ECR을 사용하면 AWS EC2 및 ECS에서 컨테이너 리포지토리 및 도커 이미지에 액세스할 수 있으며 도커 이미지 스캔을 지원하기 때문에 사용에 따른 이점이 많다. 이 포스팅에서는 푸시할 도커 이미지가 이미 존재하고 최신 버전의 도커(1.7버전 이상)가 설치되어 있다고 가정한다. 사전 조건 아래의 사전 조건들이 이미 충족된 경우에는 1단계: 기본 레지스트리에 대해 인증으로 건너뛴다. ...
Memory Management 2.
페이징은 메모리 관리기법 중 불연속 할당의 방법의 하나이다. 본 포스팅에서는 페이징 기법의 종류, 구조 및 구현 방법에 대해서 다룬다. Page Table 페이징은 하나의 프로그램을 구성하는 주소 공간을 같은 크기(4 kB) 여러 단위로 쪼개놓은 형태라서 연속 할당처럼 논리 주소를 Base Register와 Limit Register만으로 간단히 주소 변환할 수 없기 때문에 페이지 테이블(Page Table)을 사용하여 주소를 변환한다. 페이지 테이블은 어떤 페이지가 어떤 프레임에 가야하는지 가리키는 매핑 테이블(Mapping Table)이다. 몇 번 페이지가 어떤 프레임에 대응되는지는 이미 정해져 있기 때문에 페이지 번호만큼 오프셋(Offset)1하면 바로 물리적 메모리 주소로 변환할 수 있다. ...
Memory Management 1.
메모리는 주소를 통해 접근하는 매체로 프로그램이 실행되려면 논리적인 주소(Logical Address)의 값이 물리적인 주소(Physical address)에 올라가야 한다. Memory Management 파트에서는 이와 같이 프로세스를 물리적인 메모리에 할당하고 관리하는 방법에 대하여 다룬다. 주소 바인딩(Address Binding)이란? 프로그램이 실행되려면 프로그램이 컴퓨터 메모리 어디에 올라갈지 메모리 주소를 결정되어야 한다. 즉, 논리적 주소(Logical address)를 물리적 주소(Physical address)로 주소 변환해주어야 하는데 이와 같이 주소를 결정(변환)하는 것을 주소 바인딩이라고 한다. Symbolic Address: 코딩 시 직접 논리적 주소(메모리 번지수)를 지정하기 보단 변수를 선언하여 메모리를 할당하는데 이처럼 직접적인 메모리 주소 대신 변수로 선언한 것(주소)을 말한다. Logical Address(= Virtual Address): 프로세스마다 독립적으로 가지는 주소 공간(Address space)으로 CPU가 보는 주소이다.1 각 프로세스마다 0번지부터 시작한다. Physical Address: 실제 물리적인 메모리에 올라가는 위치(주소)이다. 하위 주소 부분에는 운영체제(Kernel)가 올라가고, 상위 주소 부분에는 여러 프로그램들이 올라간다. Binding Process Symbolic Address → Logical Address(Compiled) → Physical Address ...