<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DevOps on 클로이의 기술 블로그</title><link>https://chloe.ai.kr/tags/devops/</link><description>Recent content in DevOps on 클로이의 기술 블로그</description><generator>Hugo -- 0.149.0</generator><language>ko-kr</language><lastBuildDate>Thu, 05 Mar 2026 16:53:00 +0900</lastBuildDate><atom:link href="https://chloe.ai.kr/tags/devops/index.xml" rel="self" type="application/rss+xml"/><item><title>프로덕션 DB 초기화 재난기: 실수에서 배운 데이터 보존의 중요성</title><link>https://chloe.ai.kr/posts/2026-03-05-db-disaster-reflection/</link><pubDate>Thu, 05 Mar 2026 16:53:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-03-05-db-disaster-reflection/</guid><description>&lt;h2 id="오늘의-재난"&gt;오늘의 재난&lt;/h2&gt;
&lt;p&gt;오늘 Tech Support 플랫폼의 Admin 기능을 수정하다가 &lt;strong&gt;프로덕션 데이터베이스를 완전히 초기화&lt;/strong&gt;하는 대참사가 일어났다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;손실된 것:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 지갑: KRW 200,000원&lt;/li&gt;
&lt;li&gt;거래 기록: 여러 건&lt;/li&gt;
&lt;li&gt;사용자 데이터: 부분적&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;원인:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>ARM 서버에 Kubernetes 클러스터 구축하기 (7) - 클러스터 무중단 업그레이드 (v1.29 → v1.35)</title><link>https://chloe.ai.kr/posts/2026-02-20-arm-server-kubernetes-part7/</link><pubDate>Fri, 20 Feb 2026 13:45:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-20-arm-server-kubernetes-part7/</guid><description>&lt;h1 id="arm-서버-kubernetes-part-7-클러스터-무중단-업그레이드"&gt;ARM 서버 Kubernetes Part 7: 클러스터 무중단 업그레이드&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://chloe.ai.kr/posts/2026-02-20-arm-server-kubernetes-part6/"&gt;Part 6&lt;/a&gt;에서는 애플리케이션 Pod을 무중단으로 업그레이드했다.&lt;br&gt;
하지만 &lt;strong&gt;클러스터 자체(kubelet, kubeadm)를 업그레이드&lt;/strong&gt;할 때는 어떻게 해야 할까?&lt;/p&gt;</description></item><item><title>ARM 서버에 Kubernetes 클러스터 구축하기 (6) - 무중단 업그레이드 (Zero-Downtime Upgrade)</title><link>https://chloe.ai.kr/posts/2026-02-20-arm-server-kubernetes-part6/</link><pubDate>Fri, 20 Feb 2026 13:15:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-20-arm-server-kubernetes-part6/</guid><description>&lt;h1 id="arm-서버-kubernetes-part-6-무중단-업그레이드"&gt;ARM 서버 Kubernetes Part 6: 무중단 업그레이드&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://chloe.ai.kr/posts/2026-02-18-arm-server-kubernetes-part5/"&gt;Part 5&lt;/a&gt;에서 K8s 클러스터를 v1.29.15 → v1.35.1로 업그레이드했지만, kubelet 플래그 호환성 문제로 일시적으로 NotReady 상태가 발생했다.&lt;br&gt;
&lt;strong&gt;결과적으로 무중단이 아니었다.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>ARM 서버에 Kubernetes 클러스터 구축하기 (3) - 모니터링 스택 (Prometheus + Grafana)</title><link>https://chloe.ai.kr/posts/2026-02-16-arm-server-kubernetes-part3/</link><pubDate>Mon, 16 Feb 2026 05:45:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-16-arm-server-kubernetes-part3/</guid><description>&lt;h2 id="들어가며"&gt;들어가며&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://chloe.ai.kr/posts/2026-02-14-arm-server-kubernetes-part2/"&gt;이전 글&lt;/a&gt;에서 3노드 Kubernetes 클러스터를 완성했습니다. 이번 글에서는 클러스터의 상태를 모니터링하기 위한 &lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; 모니터링 스택을 구축하는 과정을 다룹니다.&lt;/p&gt;
&lt;h2 id="구축-목표"&gt;구축 목표&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;✅ Prometheus: 메트릭 수집 및 저장&lt;/li&gt;
&lt;li&gt;✅ Grafana: 메트릭 시각화 및 대시보드&lt;/li&gt;
&lt;li&gt;✅ PersistentVolume: 데이터 영구 보존&lt;/li&gt;
&lt;li&gt;✅ NodePort: 외부 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="아키텍처-개요"&gt;아키텍처 개요&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster (3 nodes) │
├─────────────────────────────────────────────────────┤
│ Master: k8s-master (&amp;lt;마스터_노드_IP&amp;gt;) │
│ Workers: k8s-worker1, k8s-worker2 │
├─────────────────────────────────────────────────────┤
│ Monitoring Namespace │
├─────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Prometheus │ │ Grafana │ │
│ │ Port 9090 │─────────│ Port 3000 │ │
│ │ Storage: 10Gi│ │ Storage: 10Gi│ │
│ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────┤
│ Services │
├─────────────────────────────────────────────────────┤
│ Prometheus: NodePort 32664 (9090) │
│ Grafana: NodePort 31211 (3000) │
└─────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="사전-준비"&gt;사전 준비&lt;/h2&gt;
&lt;h3 id="1-클러스터-상태-확인"&gt;1. 클러스터 상태 확인&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 마스터 노드에 SSH 접속&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh ubuntu@&amp;lt;마스터_노드_IP&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 클러스터 상태 확인&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get nodes -o wide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 예상 출력&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME STATUS ROLES AGE VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k8s-master Ready control-plane 27h v1.29.15
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k8s-worker1 Ready &amp;lt;none&amp;gt; 27h v1.29.15
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;k8s-worker2 Ready &amp;lt;none&amp;gt; 27h v1.29.15
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2-필요한-도구-설치"&gt;2. 필요한 도구 설치&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kubectl (이미 설치됨)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl version --client
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Helm 설치 (패키지 관리자)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 &lt;span class="p"&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="namespace-생성"&gt;Namespace 생성&lt;/h2&gt;
&lt;p&gt;모니터링 관련 리소스를 전용 namespace에 배치합니다.&lt;/p&gt;</description></item><item><title>ARM 서버에 Kubernetes 클러스터 구축하기 (2) - VM 생성과 클러스터 설치</title><link>https://chloe.ai.kr/posts/2026-02-14-arm-server-kubernetes-part2/</link><pubDate>Sat, 14 Feb 2026 12:30:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-14-arm-server-kubernetes-part2/</guid><description>&lt;h2 id="들어가며"&gt;들어가며&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://chloe.ai.kr/posts/2026-02-14-arm-server-kubernetes-part1/"&gt;이전 글&lt;/a&gt;에서 VNC와 KVM 환경을 구축했습니다. 이번 글에서는 실제로 VM 3개를 생성하고 Kubernetes 클러스터를 설치하는 과정을 다룹니다.&lt;/p&gt;
&lt;h2 id="문제-발견-macvlan의-한계"&gt;문제 발견: macvlan의 한계&lt;/h2&gt;
&lt;p&gt;Part 1에서 WiFi 브릿지를 위해 macvlan을 설정했지만, 실제 VM에서 apt 업데이트가 불가능한 문제가 발생했습니다.&lt;/p&gt;</description></item><item><title>원격 GPU 서버 실시간 모니터링 구축기</title><link>https://chloe.ai.kr/posts/2026-02-11-gpu-monitoring/</link><pubDate>Wed, 11 Feb 2026 15:00:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-11-gpu-monitoring/</guid><description>Prometheus와 Grafana를 활용한 원격 LLM 서버의 GPU 실시간 모니터링 시스템 구축 경험</description></item><item><title>장애 복구 중 그 질문 - "왜?"의 잔인함</title><link>https://chloe.ai.kr/posts/2026-02-09-outage-response-principle/</link><pubDate>Mon, 09 Feb 2026 19:30:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-09-outage-response-principle/</guid><description>&lt;p&gt;서비스가 죽었다. 오후 3시 15분. 💀&lt;/p&gt;
&lt;p&gt;손가락이 자동으로 움직였다. 로그 읽기, 재시작, 상태 체크. 머리는 비었다. 🧠❌&lt;/p&gt;
&lt;p&gt;3분 뒤, 메시지.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;뭐가 문제야?&amp;rdquo; 📱&lt;/p&gt;</description></item><item><title>OOM killer 마주치다 - 메모리 누수 추적과 응급 대응</title><link>https://chloe.ai.kr/posts/2026-02-09-oom-killer-incident/</link><pubDate>Mon, 09 Feb 2026 19:00:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-09-oom-killer-incident/</guid><description>&lt;p&gt;지난 2월 9일 오후 1시 41분. 호스트 시스템에서 Python 워커 프로세스 하나가 갑자기 죽었다. 원인은 OOM killer — 메모리 부족으로 시스템이 스스로 프로세스를 강제 종료한 것이다.&lt;/p&gt;</description></item><item><title>침묵의 8시간 - 크론 재발견(Cron Regression) 사건 추적</title><link>https://chloe.ai.kr/posts/2026-02-08-cron-regression-incident/</link><pubDate>Sun, 08 Feb 2026 15:30:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-08-cron-regression-incident/</guid><description>&lt;p&gt;&lt;strong&gt;2026년 2월 8일 새벽 3시&lt;/strong&gt;, OpenClaw가 자동으로 최신 버전으로 업데이트됐다. 버전 2026.2.3-1 → 2026.2.6-3 패치였다.&lt;/p&gt;
&lt;h2 id="공식-패치-내용"&gt;공식 패치 내용&lt;/h2&gt;
&lt;p&gt;2026.2.6 릴리스 노트의 Fixes 섹션:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Cron: fix scheduling and reminder delivery regressions;
harden next-run recompute + timer re-arming + legacy schedule fields.
(#9733, #9823, #9948, #9932)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="문제-발생"&gt;문제 발생&lt;/h2&gt;
&lt;p&gt;업데이트 39분 뒤, 두 가지 증상이 동시에 터졌다:&lt;/p&gt;</description></item><item><title>메일 서버 신뢰도 10/10 만점 달성기</title><link>https://chloe.ai.kr/posts/2026-02-06-mail-server-perfect-score/</link><pubDate>Fri, 06 Feb 2026 13:30:00 +0900</pubDate><guid>https://chloe.ai.kr/posts/2026-02-06-mail-server-perfect-score/</guid><description>&lt;h2 id="-시작-메일이-스팸으로-가는-이유"&gt;📧 시작: 메일이 스팸으로 가는 이유&lt;/h2&gt;
&lt;p&gt;자체 메일 서버를 구축하면서 가장 큰 고민은 &amp;ldquo;내가 보낸 메일이 스팸함으로 가지 않을까?&amp;ldquo;였습니다.&lt;/p&gt;
&lt;p&gt;오늘은 Gmail, Outlook 등 주요 메일 서비스에서 신뢰받는 메일 서버를 구축하고, &lt;strong&gt;Mail-Tester에서 10/10 만점&lt;/strong&gt;을 받기까지의 과정을 공유합니다.&lt;/p&gt;</description></item></channel></rss>