전체 글 (33) # GPU 컨테이너, 요청과 주입은 다른 주체다 - gpus all 7월 중순에 CUDA 컨테이너를 띄웠을 때 뜨는 NVIDIA Driver was not detected 경고가 정확히 어느 계층의 부재를 뜻하는지 스택을 그려가며 정리했다. 결론은 "커널 드라이버 모듈은 호스트에 남고, 사용자 공간 드라이버 라이브러리와 /dev/nvidia*는 NVIDIA Container Toolkit이 컨테이너에 연결해준다"는 것이었다. 그런데 그 정리에는 구멍이 하나 있었다 — "언제" 연결되는지, 즉 docker run --gpus all을 치는 순간부터 컨테이너 안에서 nvidia-smi가 뜨는 순간까지 실제로 어떤 순서로 일이 벌어지는지가 빠져 있었다. 이번 글은 그 빈칸을 채운 기록이다. 그리고 그 사이에 있었던, 조금 민망하지만 솔직하게 남겨야 할 이야기도 하나 있다. 그.. EKS 알람을 AI가 대신 조사하게 만들기 — HolmesGPT + Robusta 자동조사 파이프라인 구축기 운영 중인 EKS 클러스터에서 Prometheus alert가 울릴 때마다 하는 일은 늘 비슷했다. 파드 상태 확인하고, 로그 뒤지고, 이벤트 보고, 메트릭 그래프 열고. alert 하나에 10~20분씩 쓰는 이 반복 작업을 AI에게 맡길 수 없을까 싶어서 HolmesGPT를 도입했다.목표는 alert가 울리면 사람이 보기 전에 AI가 먼저 클러스터를 조사하고, 보고서를 Slack으로 전달하는것 결과적으로 파이프라인은 완성됐지만, 그 과정에서 버그를 연달아 밟으며 수습하는 데 시간을 더 써버렸다....이 글은 그 아키텍처와 삽질의 기록이다.HolmesGPT란?HolmesGPT는 Robusta에서 만든 오픈소스 AI SRE 조사 엔진이다. LLM에게 kubectl, Prometheus 질의 같은 도구를 쥐.. 단일 스테이지를 멀티스테이지로 지난 글에서는 CUDA 베이스 이미지 위에 train_mnist.py를 얹는 Dockerfile을 완성했다. 빌드 에러 4개를 순서대로 잡고 나니 이미지는 잘 도는데, 문제는 크기였다. docker images로 확인한 크기가 3.22GB. 이번 글의 목표는 그 이미지를 멀티스테이지로 다이어트시키는 것이었는데, 실제로는 다이어트보다 사고를 치고 수습하는 데 시간을 더 썼다. 그 과정에서 venv COPY가 실제로 뭘 옮기고 뭘 못 옮기는지, 그리고 "빌드했다"와 "검증했다"가 왜 다른 말인지를 확인했다.멀티스테이지란 — venv를 통째로 옮기는 전략단일 스테이지 Dockerfile은 apt-get install로 빌드 도구를 깔고, pip install로 torch를 설치하고, 그 상태 그대로 실행까지 .. Dockerfile 빌드 레이어 캐시를 직접 돌려보기 지난 글에서 이미지·컨테이너·볼륨을 자료 없이 기억으로만 정리해봤고, 그러다 스스로도 확신이 안 서는 지점 세 개를 남겼다. 그중 두 번째가 레이어 캐시였다. "변경된 부분이 기존 레이어에 쌓인다"고 적어놓긴 했는데, 이게 레이어 하나가 계속 수정되는 건지, 아니면 그때그때 새 레이어가 생기는 건지 말로는 설명이 안 됐다. 이번 글은 그 확신 없는 지점을 실제로 Dockerfile을 쓰고 docker build를 여러 번 돌려가며 확인한 기록이다. 나머지 두 개 — 컨테이너 실행이 정말 이미지를 "복사"하는 것인지, 볼륨이라고 알고 있던 것이 정확히 무엇을 가리키는지 — 는 아직 손을 못 댔고, 이 글 끝에 다음 확인 목록으로 남겨둔다.목표는 단순했다. 앞서 만든 MNIST 학습 스크립트(train_mn.. 도커 이미지·컨테이너·레이어 캐시·볼륨 — 기억으로 먼저 정리해본 날 저번 글 마지막에 "다음은 도커 이미지와 컨테이너의 차이, 레이어 캐시, 볼륨 개념을 정리할 차례"라고 적어놨다. 이번엔 Dockerfile을 쓰기 전에, 자료를 펼쳐놓지 않고 아는 것만으로 이미지·컨테이너·레이어 캐시·볼륨을 먼저 정리해봤다. 코드를 하나도 안 쓴 날이라 실습 로그는 없지만, 대신 글로 옮기다 보니 스스로도 확신이 안 서는 지점이 눈에 보였다. 이번 글에서는 오늘 정리한 개념과, 정리하면서 드러난 애매한 지점 세 가지를 정직하게 남긴다.이미지란?애플리케이션을 실행하는 데 필요한 종속성·라이브러리까지 다 포함한, 독립적으로 실행 가능한 환경의 스냅샷이다.이미지 자체는 실행되는 게 아니다. 실행되는 건 그 이미지를 바탕으로 뜨는 컨테이너다.이미지는 레이어 여러 장이 겹겹이 쌓인 구조다. 뭔.. PyTorch로 MNIST 학습 스크립트를 밑바닥부터 짜보며 이해한 Dataset, DataLoader, batch size 요즘 AI 인프라 공부를 시작하면서 PyTorch 기초를 다지고 있습니다. 예제를 복붙하는 대신 MNIST 손글씨 숫자를 분류하는 학습 스크립트를 처음부터 직접 작성해봤습니다. 함수 뼈대만 있는 파일을 채워나가다 두 번 스스로 버그를 냈는데, 고치는 과정에서 Dataset과 DataLoader가 왜 분리돼 있는지, batch size가 실제로 뭘 바꾸는지가 훨씬 선명해졌습니다.Dataset과 DataLoader란?MNIST는 손글씨 숫자 이미지 7만 장짜리 데이터셋이다. torchvision.datasets.MNIST로 내려받으면 나오는 Dataset 객체는 "전체 데이터 묶음 + 인덱스로 하나씩 꺼내는 방법"만 정의한 것이다. 실제 학습 루프가 쓰는 건 이걸 감싼 DataLoader다. 쉽게 말해 Da.. 컨테이너 안에서 리눅스 기본기 다시 익히기 — load average부터 journalctl까지 최근 AI 인프라 공부를 시작하면서 모델 학습 코드를 짜는 것보다 그 코드가 실제로 돌아가는 서버 환경을 이해하는 게 더 급하다는 걸 느꼈다. 요즘 운영 환경은 대부분 컨테이너 위에서 돌아가는데, 나는 컨테이너를 "가벼운 서버" 정도로만 알고 있었지 안에 뭐가 있고 뭐가 없는지는 제대로 만져본 적이 없었다. 그래서 하루는 코드를 하나도 안 쓰고 docker run -it ubuntu로 컨테이너 하나만 띄워놓고, 그 안에서 서버 상태를 확인하는 기본 명령어들을 하나씩 돌려봤다. 이번 글에서는 그 과정에서 확인한 컨테이너와 서버의 차이, load average 읽는 법, 퍼미션 비트를 정리한다.컨테이너란 무엇인가컨테이너를 VM(가상머신)과 헷갈리기 쉬운데, 둘은 격리 단위가 다르다.VM: 하드웨어까지 가상화.. exit code와 예외 재포장 — PyTorch 학습 스크립트에 장애를 직접 주입해본 기록 최근 AI 인프라 공부를 시작하면서 PyTorch로 MNIST 숫자 분류기를 학습시키는 CLI 스크립트를 만들었다. 데이터 로드부터 학습, 모델 저장까지 한 번에 돌아가서 "다 됐다"고 생각했는데, 리뷰에서 예외 처리는 코드만 읽어서 검증되는 게 아니라는 피드백을 받았다. 네트워크를 끊거나 디렉토리 권한을 없애는 식으로 실제 장애를 만들어보고, 그때 스크립트가 어떤 exit code로 끝나는지 확인해보라는 것이었다. 이 글에서는 그 과정에서 확인한 exit code의 의미, 라이브러리의 예외 재포장, silent fallback과 fail-fast의 차이를 정리한다.exit code란?프로세스가 종료될 때 OS에 돌려주는 정수값이다. 관례상 0은 성공, 0이 아닌 값은 실패다. 쉘의 $?, CI 파이프라.. 1 2 3 4 5