<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>han_s.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 09 Apr 2026 07:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>han_s.log</title>
            <url>https://velog.velcdn.com/images/han_s/profile/48f48aed-b226-46bd-af25-6044bb8bba42/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. han_s.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/han_s" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Observability 플랫폼 구축]]></title>
            <link>https://velog.io/@han_s/Observability-%ED%94%8C%EB%9E%AB%ED%8F%BC-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@han_s/Observability-%ED%94%8C%EB%9E%AB%ED%8F%BC-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Thu, 09 Apr 2026 07:00:00 GMT</pubDate>
            <description><![CDATA[<h2 id="observability-플랫폼-구축">Observability 플랫폼 구축</h2>
<p>  4주차에서 Metrics / Logs / Traces 개념을 배웠다. 이번엔 그걸 실제로 어떻게 구축하는지다.</p>
<hr>
<h2 id="표준-스택">표준 스택</h2>
<table>
<thead>
<tr>
<th>역할</th>
<th>도구</th>
</tr>
</thead>
<tbody><tr>
<td>메트릭 수집</td>
<td>Prometheus</td>
</tr>
<tr>
<td>메트릭 시각화</td>
<td>Grafana</td>
</tr>
<tr>
<td>로그 수집</td>
<td>Fluentd / Fluent Bit</td>
</tr>
<tr>
<td>로그 저장</td>
<td>Loki / Elasticsearch</td>
</tr>
<tr>
<td>트레이싱</td>
<td>Jaeger / Tempo</td>
</tr>
<tr>
<td>알림</td>
<td>Alertmanager</td>
</tr>
</tbody></table>
<hr>
<h2 id="prometheus-구조">Prometheus 구조</h2>
<p>  Prometheus는 <strong>Pull 방식</strong>으로 메트릭을 수집한다. 서비스가 메트릭을 보내는 게 아니라 Prometheus가
   주기적으로 가져간다.</p>
<p>  [서비스] → /metrics 엔드포인트 노출
  [Prometheus] → 주기적으로 /metrics 호출해서 수집
  [Grafana] → Prometheus에서 데이터 조회해서 시각화</p>
<p>  서비스가 죽어도 Prometheus가 감지할 수 있다는 게 Pull 방식의 장점이다.</p>
<hr>
<h2 id="메트릭-타입">메트릭 타입</h2>
<table>
<thead>
<tr>
<th>타입</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>Counter</td>
<td>누적 카운트, 감소하지 않음</td>
<td>총 요청 수, 에러 수</td>
</tr>
<tr>
<td>Gauge</td>
<td>현재 값, 오르내림</td>
<td>CPU 사용률, 메모리</td>
</tr>
<tr>
<td>Histogram</td>
<td>구간별 분포 측정</td>
<td>응답 시간 분포</td>
</tr>
<tr>
<td>Summary</td>
<td>분위수 측정</td>
<td>p99 응답 시간</td>
</tr>
</tbody></table>
<p>  SLI를 측정할 때 응답 시간은 Histogram, 에러율은 Counter로 계산한다.</p>
<hr>
<h2 id="로그-파이프라인">로그 파이프라인</h2>
<p>  [서비스] → [Fluent Bit] → [Loki / Elasticsearch] → [Grafana]</p>
<p>  Fluent Bit은 각 노드에 DaemonSet으로 배포해서 모든 컨테이너 로그를 빠짐없이 수집한다.</p>
<table>
<thead>
<tr>
<th>도구</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td>Loki</td>
<td>레이블 기반 저장, Grafana와 연동이 자연스럽다</td>
</tr>
<tr>
<td>Elasticsearch</td>
<td>전문 검색이 강력하다, 복잡한 검색이 필요할 때 적합하다</td>
</tr>
</tbody></table>
<hr>
<h2 id="분산-트레이싱">분산 트레이싱</h2>
<p>  각 서비스가 Span을 생성하고 같은 Trace ID로 묶인다. 요청이 어디서 느려졌는지 한눈에 볼 수 있다.</p>
<p>  [서비스 A] → [서비스 B] → [서비스 C]
       ↓              ↓              ↓
    Span 생성      Span 생성      Span 생성
                      ↓
               [Jaeger / Tempo] → [Grafana]</p>
<hr>
<h2 id="grafana로-연결하기">Grafana로 연결하기</h2>
<p>  Grafana는 여러 데이터 소스를 연결해서 한 화면에서 보는 도구다. Prometheus는 데이터를 모으는 역할,
   Grafana는 모인 데이터를 보여주는 역할이다.</p>
<ul>
<li><p>Prometheus → 메트릭 대시보드</p>
</li>
<li><p>Loki → 로그 검색</p>
</li>
<li><p>Jaeger / Tempo → 트레이스 조회</p>
<p>하나의 장애 상황에서 메트릭, 로그, 트레이스를 Grafana 한 화면에서 전환하며 볼 수 있다.</p>
</li>
</ul>
<hr>
<h2 id="구축-시-흔한-실수">구축 시 흔한 실수</h2>
<table>
<thead>
<tr>
<th>실수</th>
<th>문제</th>
</tr>
</thead>
<tbody><tr>
<td>메트릭만 수집하고 로그 없음</td>
<td>수치는 보이는데 원인을 모른다</td>
</tr>
<tr>
<td>로그에 컨텍스트 없음</td>
<td>어떤 요청에서 난 에러인지 모른다</td>
</tr>
<tr>
<td>트레이스 ID 미연동</td>
<td>로그와 트레이스를 연결 못 한다</td>
</tr>
<tr>
<td>대시보드만 있고 알림 없음</td>
<td>사람이 직접 보고 있어야 한다</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Service Mesh]]></title>
            <link>https://velog.io/@han_s/Service-Mesh</link>
            <guid>https://velog.io/@han_s/Service-Mesh</guid>
            <pubDate>Wed, 01 Apr 2026 06:57:17 GMT</pubDate>
            <description><![CDATA[<h2 id="service-mesh가-뭔데">Service Mesh가 뭔데</h2>
<p>  마이크로서비스 환경에서 서비스가 수십 개가 되면 서비스 간 통신이 복잡해진다. 각 서비스가 직접 다른 서비스를 호출하는데, 이때 문제가 생긴다.</p>
<ul>
<li><p>어떤 서비스가 어디로 트래픽을 보내는지 보이지 않는다</p>
</li>
<li><p>서킷 브레이커, 재시도 로직을 서비스마다 따로 구현해야 한다</p>
</li>
<li><p>서비스 간 통신 암호화를 각자 처리해야 한다</p>
<p>Service Mesh는 <strong>서비스 간 통신을 인프라 레벨에서 관리하는 것</strong>이다. 애플리케이션 코드를 건드리지 않고 트래픽 제어, 보안, 관찰을 한 곳에서 처리한다.</p>
</li>
</ul>
<hr>
<h2 id="sidecar-패턴">Sidecar 패턴</h2>
<p>  Service Mesh의 핵심 구조다. 각 서비스 옆에 Proxy(사이드카)를 붙여서 모든 네트워크 트래픽이 Proxy를 통하게 만든다.</p>
<p>  [서비스 A] → [Proxy A] → [Proxy B] → [서비스 B]</p>
<p>  서비스는 직접 통신하지 않는다. Proxy끼리 통신한다. 트래픽 제어, 로깅, 암호화가 전부 Proxy에서 처리된다.</p>
<hr>
<h2 id="control-plane--data-plane">Control Plane / Data Plane</h2>
<table>
<thead>
<tr>
<th>구분</th>
<th>역할</th>
<th>도구</th>
</tr>
</thead>
<tbody><tr>
<td>Control Plane</td>
<td>정책을 전달하고 Proxy를 관리</td>
<td>Istio</td>
</tr>
<tr>
<td>Data Plane</td>
<td>실제 트래픽을 처리하는 Proxy</td>
<td>Envoy</td>
</tr>
</tbody></table>
<p>  Istio(Control Plane)가 Envoy(Data Plane)에게 지시하고, Envoy가 실제 트래픽을 처리한다. 지휘관과 병사 관계로 기억하면 편하다.</p>
<hr>
<h2 id="service-mesh가-제공하는-것">Service Mesh가 제공하는 것</h2>
<p>  <strong>트래픽 제어</strong></p>
<ul>
<li><p>Canary 배포를 코드 없이 설정으로 처리한다</p>
</li>
<li><p>특정 헤더가 있는 요청만 새 버전으로 보낼 수 있다</p>
</li>
<li><p>요청 비율 기반으로 A/B 테스트가 가능하다</p>
</li>
<li><p><em>Observability*</em></p>
</li>
<li><p>서비스 간 모든 트래픽의 메트릭이 자동으로 수집된다</p>
</li>
<li><p>분산 트레이싱이 자동으로 적용된다</p>
</li>
<li><p>서비스 맵을 시각화한다</p>
</li>
<li><p><em>보안 (mTLS)*</em></p>
</li>
<li><p>서비스 간 통신을 자동으로 암호화한다</p>
</li>
<li><p>서비스 인증을 자동으로 처리한다</p>
</li>
<li><p>특정 서비스만 특정 서비스를 호출하도록 정책을 설정한다</p>
</li>
<li><p><em>Resilience*</em></p>
</li>
<li><p>서킷 브레이커를 코드 없이 설정으로 적용한다</p>
</li>
<li><p>재시도, Timeout을 인프라 레벨에서 처리한다</p>
</li>
</ul>
<hr>
<h2 id="대표-도구">대표 도구</h2>
<table>
<thead>
<tr>
<th>도구</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Istio</td>
<td>가장 널리 쓰이는 Service Mesh, Control Plane</td>
</tr>
<tr>
<td>Envoy</td>
<td>Istio의 Data Plane으로 쓰이는 고성능 Proxy</td>
</tr>
<tr>
<td>Linkerd</td>
<td>경량 Service Mesh, 설정이 간단하다</td>
</tr>
<tr>
<td>Consul Connect</td>
<td>HashiCorp의 Service Mesh</td>
</tr>
</tbody></table>
<hr>
<h2 id="sre-관점에서-service-mesh">SRE 관점에서 Service Mesh</h2>
<p>  12주차에서 배운 Reliability Patterns (Circuit Breaker, Retry, Timeout)을 애플리케이션 코드 없이 인프라 레벨에서 적용할 수 있다. 각 서비스 개발자가 직접 구현하던 것을 플랫폼이
  처리해준다.</p>
<p>  결국 Service Mesh는 Platform Engineering과 연결된다. 개발자가 Reliability 코드를 직접 짜지 않아도 신뢰성 있는 서비스를 만들 수 있는 환경을 만드는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Production Readiness Review]]></title>
            <link>https://velog.io/@han_s/Production-Readiness-Review</link>
            <guid>https://velog.io/@han_s/Production-Readiness-Review</guid>
            <pubDate>Tue, 31 Mar 2026 06:05:38 GMT</pubDate>
            <description><![CDATA[<h2 id="production-readiness-review가-뭔데">Production Readiness Review가 뭔데</h2>
<p>  기능이 완성됐다고 바로 프로덕션에 올리면 안 된다. 모니터링이 없거나, On-call 담당자가 없거나, 장애 대응 절차가 없는 상태로 나가면 첫 장애 때 아무것도 못 한다.</p>
<p>  PRR은 <strong>서비스가 프로덕션에 나갈 준비가 됐는지 체계적으로 검토하는 프로세스</strong>다.</p>
<hr>
<h2 id="prr이-필요한-이유">PRR이 필요한 이유</h2>
<table>
<thead>
<tr>
<th>상황</th>
<th>문제</th>
</tr>
</thead>
<tbody><tr>
<td>모니터링 없이 배포</td>
<td>장애가 나도 모른다</td>
</tr>
<tr>
<td>Runbook 없이 배포</td>
<td>장애가 나도 대응을 못 한다</td>
</tr>
<tr>
<td>SLO 없이 배포</td>
<td>서비스가 잘 되는지 판단 기준이 없다</td>
</tr>
<tr>
<td>On-call 없이 배포</td>
<td>야간 장애 때 아무도 안 받는다</td>
</tr>
</tbody></table>
<hr>
<h2 id="prr-체크리스트">PRR 체크리스트</h2>
<p>  <strong>Observability</strong></p>
<ul>
<li><p><input disabled="" type="checkbox">  메트릭이 수집되고 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  로그가 중앙에 수집되고 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  대시보드가 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  핵심 트레이스가 설정되어 있는가</p>
</li>
<li><p><em>Alerting*</em></p>
</li>
<li><p><input disabled="" type="checkbox">  SLO 기반 알림이 설정되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  알림 티어가 Page / Ticket으로 구분되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  알림이 적절한 채널로 전달되는가</p>
</li>
<li><p><em>On-call*</em></p>
</li>
<li><p><input disabled="" type="checkbox">  On-call 담당자가 지정되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  Escalation Policy가 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  Runbook이 작성되어 있는가</p>
</li>
<li><p><em>Reliability*</em></p>
</li>
<li><p><input disabled="" type="checkbox">  SLI / SLO가 정의되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  Error Budget이 설정되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  장애 시 롤백 절차가 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  Graceful Degradation이 고려되어 있는가</p>
</li>
<li><p><em>Change Management*</em></p>
</li>
<li><p><input disabled="" type="checkbox">  배포 전략이 정의되어 있는가 (Canary / Blue-Green)</p>
</li>
<li><p><input disabled="" type="checkbox">  Feature Flag가 적용되어 있는가</p>
</li>
<li><p><input disabled="" type="checkbox">  DB 스키마 변경 시 하위 호환이 유지되는가</p>
</li>
</ul>
<hr>
<h2 id="launch-criteria">Launch Criteria</h2>
<p>  체크리스트를 다 채웠다고 바로 나가는 게 아니다. 프로덕션 출시를 허용하는 최소 기준이다.</p>
<table>
<thead>
<tr>
<th>등급</th>
<th>기준</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>Must (필수)</td>
<td>이게 없으면 출시 불가</td>
<td>SLO 정의, 기본 알림, Runbook</td>
</tr>
<tr>
<td>Should (권장)</td>
<td>없으면 리스크가 있지만 출시는 가능</td>
<td>완전한 대시보드</td>
</tr>
<tr>
<td>Nice to have</td>
<td>있으면 좋지만 없어도 됨</td>
<td>고급 트레이싱</td>
</tr>
</tbody></table>
<hr>
<h2 id="prr-프로세스">PRR 프로세스</h2>
<ol>
<li><strong>개발팀이 PRR 문서 작성</strong> - 체크리스트 항목을 직접 채운다</li>
<li><strong>SRE팀 검토</strong> - 누락된 항목, 리스크 파악</li>
<li><strong>피드백 반영</strong> - Must 항목 미충족 시 출시 보류</li>
<li><strong>출시 승인</strong> - Launch Criteria 충족 시 승인</li>
<li><strong>출시 후 모니터링</strong> - 초기 트래픽 유입 시 집중 모니터링</li>
</ol>
<hr>
<h2 id="prr과-지금까지-배운-것의-연결">PRR과 지금까지 배운 것의 연결</h2>
<p>  PRR은 지금까지 배운 모든 개념의 종합이다.</p>
<table>
<thead>
<tr>
<th>PRR 항목</th>
<th>관련 주차</th>
</tr>
</thead>
<tbody><tr>
<td>SLI / SLO</td>
<td>1주차</td>
</tr>
<tr>
<td>Error Budget</td>
<td>2주차</td>
</tr>
<tr>
<td>Observability</td>
<td>4주차</td>
</tr>
<tr>
<td>Alerting</td>
<td>5주차</td>
</tr>
<tr>
<td>On-call / Runbook</td>
<td>8주차</td>
</tr>
<tr>
<td>Change Management</td>
<td>11주차</td>
</tr>
<tr>
<td>Reliability Patterns</td>
<td>12주차</td>
</tr>
</tbody></table>
<hr>
<h2 id="정리">정리</h2>
<p>  PRR은 지금까지 배운 SRE 개념 전체의 종합 점검표다. 기능 완성이 출시 기준이 아니라, 모니터링/알림/On-call/SLO/롤백이 모두 갖춰진 상태가 출시 기준이다. Must 항목이 하나라도 빠져
  있으면 출시를 보류하는 것이 맞다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SRE 조직 문화]]></title>
            <link>https://velog.io/@han_s/SRE-%EC%A1%B0%EC%A7%81-%EB%AC%B8%ED%99%94</link>
            <guid>https://velog.io/@han_s/SRE-%EC%A1%B0%EC%A7%81-%EB%AC%B8%ED%99%94</guid>
            <pubDate>Sun, 29 Mar 2026 08:08:36 GMT</pubDate>
            <description><![CDATA[<h2 id="sre-조직-문화">SRE 조직 문화</h2>
<hr>
<h2 id="devops-vs-sre">DevOps vs SRE</h2>
<p>  둘 다 개발과 운영의 간극을 줄이는 게 목적이지만 접근 방식이 다르다.</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>DevOps</th>
<th>SRE</th>
</tr>
</thead>
<tbody><tr>
<td>개념</td>
<td>문화와 철학</td>
<td>구체적인 구현 방법</td>
</tr>
<tr>
<td>목표</td>
<td>협업과 자동화</td>
<td>신뢰성 정량화</td>
</tr>
<tr>
<td>측정</td>
<td>명확한 지표 없음</td>
<td>SLI/SLO/Error Budget</td>
</tr>
<tr>
<td>기원</td>
<td>커뮤니티</td>
<td>Google</td>
</tr>
</tbody></table>
<p>  DevOps가 &quot;무엇을 해야 한다&quot;라면 SRE는 &quot;어떻게 한다&quot;다. Google이 DevOps를 구체적으로 실현하기 위해 만든 것이 SRE다.</p>
<hr>
<h2 id="sre-팀-구성">SRE 팀 구성</h2>
<table>
<thead>
<tr>
<th>방식</th>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td>임베디드 SRE</td>
<td>서비스를 깊이 알 수 있다</td>
<td>SRE 관점이 희석될 수 있다</td>
</tr>
<tr>
<td>중앙 SRE팀</td>
<td>일관된 기준을 유지하기 쉽다</td>
<td>서비스별 컨텍스트가 부족할 수 있다</td>
</tr>
</tbody></table>
<hr>
<h2 id="toil-줄이는-자동화-전략">Toil 줄이는 자동화 전략</h2>
<p>  Toil은 수동적이고 반복적이고 자동화 가능한 작업이다.</p>
<ul>
<li>빈도 × 소요 시간으로 우선순위를 정한다. 자주 하고 오래 걸리는 것부터 자동화한다</li>
<li>Runbook이 잘 정비되면 자동화하기 쉽다</li>
<li>SRE 업무의 50% 이상이 Toil이 되면 안 된다. 넘어가면 팀이 운영에만 매몰되고 개선이 멈춘다</li>
</ul>
<hr>
<h2 id="blameless-culture">Blameless Culture</h2>
<p>  장애가 났을 때 누구의 잘못인지 찾는 게 아니라 시스템의 문제를 찾는 문화다.</p>
<table>
<thead>
<tr>
<th>Blameless 없을 때</th>
<th>Blameless 있을 때</th>
</tr>
</thead>
<tbody><tr>
<td>장애를 숨기거나 축소 보고</td>
<td>장애를 투명하게 공유</td>
</tr>
<tr>
<td>Postmortem을 형식적으로 작성</td>
<td>근본 원인을 깊이 파고듦</td>
</tr>
<tr>
<td>같은 장애가 반복됨</td>
<td>시스템이 개선됨</td>
</tr>
</tbody></table>
<p>  개인을 처벌하는 문화에서는 아무도 솔직하게 말하지 않는다. 솔직하게 말할 수 있는 환경이 먼저다.</p>
<hr>
<h2 id="error-budget-policy">Error Budget Policy</h2>
<p>  Error Budget을 팀 문화로 만드는 것이다.</p>
<ul>
<li><p>Error Budget이 남아있으면 개발팀은 기능 개발에 집중한다</p>
</li>
<li><p>Error Budget이 소진되면 신규 기능 배포를 멈추고 신뢰성 개선에 집중한다</p>
</li>
<li><p>이 규칙을 개발팀과 SRE팀이 사전에 합의해둔다</p>
<p>SRE가 일방적으로 배포를 막으면 갈등이 생긴다. Error Budget Policy는 사전 합의로 갈등을 줄이는 도구다.</p>
</li>
</ul>
<hr>
<h2 id="sre-팀의-흔한-실패-패턴">SRE 팀의 흔한 실패 패턴</h2>
<table>
<thead>
<tr>
<th>패턴</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Ops팀 재명명</td>
<td>이름만 SRE로 바꾸고 아무것도 안 변함</td>
</tr>
<tr>
<td>Toil 50% 초과</td>
<td>SRE가 운영 업무에만 매몰됨</td>
</tr>
<tr>
<td>SLO 없는 SRE</td>
<td>측정 없이 감으로 운영</td>
</tr>
<tr>
<td>Blameless 없는 Postmortem</td>
<td>형식적인 사후 분석, 개선 없음</td>
</tr>
</tbody></table>
<hr>
<h2 id="정리">정리</h2>
<p>  SRE는 직함이 아니라 방식이다. 이름만 바꾼다고 SRE가 되는 게 아니다. SLO로 측정하고, Toil을 줄이고, Blameless Culture로 투명하게 공유하고, Error Budget Policy로 개발팀과 합의하는
   것이 SRE 조직 문화의 핵심이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[FinOps]]></title>
            <link>https://velog.io/@han_s/FinOps</link>
            <guid>https://velog.io/@han_s/FinOps</guid>
            <pubDate>Sat, 28 Mar 2026 13:40:33 GMT</pubDate>
            <description><![CDATA[<h2 id="finops">FinOps</h2>
<p>클라우드를 쓰면 비용이 눈에 안 보인다. 서버를 켜두고 잊어버리거나, 필요 이상으로 큰 인스턴스를 쓰거나, 아무도 안 쓰는 리소스가 돈을 먹고 있다.</p>
<p>  FinOps는 <strong>클라우드 비용을 최적화하고 비용 대비 가치를 높이는 것</strong>이다. 단순히 비용을 줄이는 게 아니라 SLO를 지키면서 가장 저렴한 구성을 찾는 것이 목표다.</p>
<hr>
<h2 id="finops의-3단계">FinOps의 3단계</h2>
<table>
<thead>
<tr>
<th>단계</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Inform (알기)</td>
<td>지금 뭐에 얼마 쓰고 있는지 파악한다</td>
</tr>
<tr>
<td>Optimize (최적화)</td>
<td>낭비를 줄이고 효율을 높인다</td>
</tr>
<tr>
<td>Operate (운영)</td>
<td>지속적으로 모니터링하고 개선한다</td>
</tr>
</tbody></table>
<p>  파악도 안 된 상태에서 최적화할 수 없다. Inform이 항상 먼저다. Operate가 마지막인 이유는 한 번 최적화하고 끝이 아니라 지속적으로 유지하고 반복하는 단계이기 때문이다.</p>
<hr>
<h2 id="비용-낭비-패턴">비용 낭비 패턴</h2>
<table>
<thead>
<tr>
<th>패턴</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>좀비 리소스</td>
<td>아무도 안 쓰는데 켜져 있는 서버, DB, IP</td>
</tr>
<tr>
<td>오버 프로비저닝</td>
<td>실제 사용량보다 훨씬 큰 인스턴스 사용</td>
</tr>
<tr>
<td>개발 환경 방치</td>
<td>퇴근 후에도 꺼지지 않는 개발 서버</td>
</tr>
<tr>
<td>미사용 예약 인스턴스</td>
<td>할인받으려고 예약했는데 안 씀</td>
</tr>
</tbody></table>
<hr>
<h2 id="비용-최적화-전략">비용 최적화 전략</h2>
<p>  <strong>Right-sizing</strong>
  실제 사용량에 맞게 인스턴스 크기를 조정한다. CPU 10%만 쓰는데 최고 사양 인스턴스를 쓰고 있다면 낭비다.</p>
<p>  <strong>인스턴스 종류별 비교</strong></p>
<table>
<thead>
<tr>
<th>종류</th>
<th>특징</th>
<th>적합한 상황</th>
</tr>
</thead>
<tbody><tr>
<td>On-demand</td>
<td>비싸지만 즉시 사용 가능</td>
<td>예측 불가능한 트래픽</td>
</tr>
<tr>
<td>Reserved Instance</td>
<td>1~3년 약정, 최대 70% 할인</td>
<td>사용량 예측 가능한 서비스</td>
</tr>
<tr>
<td>Spot Instance</td>
<td>저렴하지만 언제든 회수 가능</td>
<td>중단 가능한 배치 작업</td>
</tr>
</tbody></table>
<p>  <strong>Auto Scaling</strong>
  트래픽이 없을 때 자동으로 줄이고, 필요할 때 늘린다. 24시간 최대 용량으로 켜두는 것보다 훨씬 효율적이다.</p>
<hr>
<h2 id="비용과-reliability-트레이드오프">비용과 Reliability 트레이드오프</h2>
<p>  비용을 줄이면 Reliability가 낮아질 수 있다. 비용을 줄이면 항상 Reliability가 높아지는 게 아니다.</p>
<table>
<thead>
<tr>
<th>선택</th>
<th>비용</th>
<th>Reliability</th>
</tr>
</thead>
<tbody><tr>
<td>Spot Instance만 사용</td>
<td>낮음</td>
<td>낮음</td>
</tr>
<tr>
<td>단일 리전, 적정 용량</td>
<td>중간</td>
<td>중간</td>
</tr>
<tr>
<td>멀티 리전 배포</td>
<td>높음</td>
<td>높음</td>
</tr>
</tbody></table>
<p>  SRE 관점에서는 Error Budget 안에서 SLO를 지키면서 가장 저렴한 구성을 찾는 것이 목표다.</p>
<hr>
<h2 id="비용-지표">비용 지표</h2>
<table>
<thead>
<tr>
<th>지표</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Unit Economics</td>
<td>요청 1건, 사용자 1명당 비용</td>
</tr>
<tr>
<td>Cost per SLO</td>
<td>SLO 1% 개선에 드는 비용</td>
</tr>
<tr>
<td>Utilization Rate</td>
<td>프로비저닝 대비 실제 사용률</td>
</tr>
</tbody></table>
<p>  Unit Economics가 중요한 이유는 트래픽이 늘어도 1건당 비용이 유지되거나 줄어야 사업이 지속 가능하기 때문이다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>  FinOps는 비용을 무조건 줄이는 게 아니다. Inform → Optimize → Operate 순서로 파악하고, 낭비를 제거하고, 지속적으로 관리하는 것이다. SLO를 지키면서 가장 효율적인 구성을 찾는 것이
  SRE와 FinOps가 만나는 지점이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Platform Engineering]]></title>
            <link>https://velog.io/@han_s/Platform-Engineering</link>
            <guid>https://velog.io/@han_s/Platform-Engineering</guid>
            <pubDate>Fri, 27 Mar 2026 03:22:24 GMT</pubDate>
            <description><![CDATA[<h2 id="platform-engineering">Platform Engineering</h2>
<p>  개발자가 인프라를 직접 다루려면 배워야 할 게 너무 많다. K8s 설정, CI/CD 파이프라인, 모니터링 연동, 보안 정책... 이걸 개발자마다 각자 하면 비효율적이고 실수도 많다.</p>
<p>  Platform Engineering은 개발자가 인프라를 직접 몰라도 쉽게 쓸 수 있도록 내부 플랫폼을 만드는 것이다. 
  개발자는 플랫폼을 통해 Self-service로 필요한 것을 가져다 쓴다.</p>
<hr>
<h2 id="internal-developer-platform-idp">Internal Developer Platform (IDP)</h2>
<p>  개발자를 위한 내부 플랫폼이다. 외부 사용자를 위한 제품이 아니라, 내부 개발팀이 쓰는 도구다.</p>
<table>
<thead>
<tr>
<th>기능</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Self-service 환경 생성</td>
<td>개발/스테이징 환경을 버튼 하나로 만든다</td>
</tr>
<tr>
<td>CI/CD 파이프라인</td>
<td>표준화된 배포 파이프라인 제공</td>
</tr>
<tr>
<td>모니터링 연동</td>
<td>서비스 배포 시 자동으로 대시보드 생성</td>
</tr>
<tr>
<td>보안 정책</td>
<td>기본 보안 설정이 자동 적용됨</td>
</tr>
</tbody></table>
<hr>
<h2 id="golden-path">Golden Path</h2>
<p>  플랫폼 팀이 권장하는 표준 개발 방식이다. 검증된 경로를 미리 만들어두면 개발자가 가져다 쓴다.</p>
<p>  Golden Path를 쓰면:</p>
<ul>
<li><p>보안, 모니터링, 배포가 자동으로 따라온다</p>
</li>
<li><p>개발자가 인프라 지식 없이도 프로덕션 수준의 서비스를 만들 수 있다</p>
</li>
<li><p>팀마다 다르게 하던 걸 표준화할 수 있다</p>
<p>강제는 아니다. 벗어날 수도 있지만 벗어나면 직접 책임져야 한다.</p>
</li>
</ul>
<hr>
<h2 id="devops-vs-sre-vs-platform-engineering">DevOps vs SRE vs Platform Engineering</h2>
<table>
<thead>
<tr>
<th>개념</th>
<th>목적</th>
<th>대상</th>
</tr>
</thead>
<tbody><tr>
<td>DevOps</td>
<td>개발과 운영의 협업 문화</td>
<td>팀 전체</td>
</tr>
<tr>
<td>SRE</td>
<td>서비스 신뢰성 확보</td>
<td>프로덕션 서비스</td>
</tr>
<tr>
<td>Platform Engineering</td>
<td>개발자 생산성 향상</td>
<td>내부 개발자</td>
</tr>
</tbody></table>
<p>  SRE가 &quot;서비스가 안 죽게 한다&quot;라면, Platform Engineering은 &quot;개발자가 쉽게 서비스를 만들고 배포하게 한다&quot;다.</p>
<hr>
<h2 id="backstage">Backstage</h2>
<p>  Spotify가 만든 오픈소스 IDP 프레임워크다. 현재 가장 널리 쓰이는 Platform Engineering 도구다.</p>
<ul>
<li><strong>서비스 카탈로그</strong>: 내부 서비스 목록과 소유자 관리</li>
<li><strong>템플릿</strong>: 표준화된 서비스 생성 자동화</li>
<li><strong>플러그인</strong>: 모니터링, CI/CD, 문서 연동</li>
</ul>
<hr>
<h2 id="정리">정리</h2>
<p>  Platform Engineering의 핵심은 <strong>Self-service와 표준화</strong>다. 개발자가 &quot;서버 하나 만들어주세요&quot;라고 요청하는 대신 직접 버튼 하나로 해결하고, K8s yaml이나 CI/CD 설정 같은 걸 매번
  처음부터 짜는 게 아니라 검증된 템플릿을 가져다 쓰는 방식이다.</p>
<p>  결국 개발자가 인프라 걱정 없이 서비스 개발에만 집중할 수 있는 환경을 만드는 것이 목표다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kubernetes 환경에서 SRE차이]]></title>
            <link>https://velog.io/@han_s/Kubernetes-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-SRE%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@han_s/Kubernetes-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-SRE%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 23 Mar 2026 12:31:53 GMT</pubDate>
            <description><![CDATA[<h2 id="kubernetes-환경에서-sre차이">Kubernetes 환경에서 SRE차이</h2>
<p>  컨테이너 환경은 기존 서버 환경과 다르다. Pod가 언제든 죽고 다시 생기고, IP가 바뀌고, 스케일이 자동으로 오르내린다. 기존 방식으로 모니터링하면 놓치는 게 많다.</p>
<hr>
<h2 id="기존-서버-환경-vs-k8s-환경">기존 서버 환경 vs K8s 환경</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>기존 서버 환경</th>
<th>K8s 환경</th>
</tr>
</thead>
<tbody><tr>
<td>단위</td>
<td>서버(VM) 단위</td>
<td>Pod / 컨테이너 단위</td>
</tr>
<tr>
<td>IP</td>
<td>고정 IP</td>
<td>Pod마다 IP가 바뀜</td>
</tr>
<tr>
<td>수명</td>
<td>서버가 계속 유지됨</td>
<td>Pod는 언제든 죽고 새로 생김</td>
</tr>
<tr>
<td>로그</td>
<td>서버에 파일로 남음</td>
<td>Pod 죽으면 로그 사라짐</td>
</tr>
<tr>
<td>스케일</td>
<td>수동으로 서버 추가</td>
<td>HPA로 자동 증감</td>
</tr>
<tr>
<td>메트릭 수집</td>
<td>서버에 에이전트 설치</td>
<td>DaemonSet으로 모든 노드에 자동 배포</td>
</tr>
<tr>
<td>장애 단위</td>
<td>서버 1대 다운</td>
<td>Pod 재시작, 노드 NotReady 등 세분화</td>
</tr>
</tbody></table>
<p>  핵심 차이는 <strong>수명과 동적 변화</strong>다. 기존 환경은 &quot;이 서버의 CPU가 높다&quot;처럼 대상이 명확하다. K8s는 Pod가 계속 생겼다 사라지기 때문에 서비스 전체 상태를 기준으로 봐야 한다.</p>
<hr>
<h2 id="liveness--readiness-probe">Liveness / Readiness Probe</h2>
<p>  Pod가 정상인지 K8s가 판단하는 기준이다.</p>
<table>
<thead>
<tr>
<th>Probe</th>
<th>목적</th>
<th>실패 시</th>
</tr>
</thead>
<tbody><tr>
<td>Liveness Probe</td>
<td>Pod가 살아있는지 확인</td>
<td>Pod 재시작</td>
</tr>
<tr>
<td>Readiness Probe</td>
<td>트래픽을 받을 준비가 됐는지 확인</td>
<td>트래픽에서 제외</td>
</tr>
</tbody></table>
<p>  Readiness가 없으면 앱이 뜨는 중에 트래픽이 들어와서 배포 중 503이 쏟아진다.</p>
<hr>
<h2 id="hpa--vpa">HPA / VPA</h2>
<table>
<thead>
<tr>
<th>종류</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>HPA (Horizontal Pod Autoscaler)</td>
<td>Pod 수를 늘리거나 줄인다</td>
</tr>
<tr>
<td>VPA (Vertical Pod Autoscaler)</td>
<td>Pod의 CPU/메모리 할당량을 조정한다</td>
</tr>
</tbody></table>
<p>  SLO와 연결하려면 커스텀 메트릭 기반 HPA를 쓴다. 에러율이 올라가면 Pod를 늘리는 방식이다.</p>
<hr>
<h2 id="k8s-환경-observability">K8s 환경 Observability</h2>
<p>  <strong>로그</strong>
  Pod가 죽으면 로그도 사라진다. 중앙 로그 수집이 필수다. (Fluentd, Loki 등)</p>
<p>  <strong>메트릭</strong>
  노드뿐 아니라 Pod, 컨테이너 단위 메트릭이 필요하다. Prometheus + Grafana가 K8s 표준 스택이다.</p>
<p>  <strong>트레이싱</strong>
  마이크로서비스 환경에서 요청이 여러 Pod를 거치기 때문에 Trace가 더 중요하다.</p>
<hr>
<h2 id="k8s-slo-측정-대상">K8s SLO 측정 대상</h2>
<table>
<thead>
<tr>
<th>측정 대상</th>
<th>SLI 예시</th>
</tr>
</thead>
<tbody><tr>
<td>API 서버</td>
<td>요청 성공률, 응답 시간</td>
</tr>
<tr>
<td>Pod</td>
<td>재시작 횟수, CrashLoopBackOff 발생률</td>
</tr>
<tr>
<td>노드</td>
<td>가용성, 리소스 포화도</td>
</tr>
</tbody></table>
<hr>
<h2 id="주요-장애-패턴">주요 장애 패턴</h2>
<table>
<thead>
<tr>
<th>패턴</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>CrashLoopBackOff</td>
<td>Pod가 계속 재시작 반복</td>
</tr>
<tr>
<td>OOMKilled</td>
<td>메모리 초과로 Pod 강제 종료</td>
</tr>
<tr>
<td>Pending</td>
<td>노드 리소스 부족으로 Pod가 스케줄링 안 됨</td>
</tr>
<tr>
<td>ImagePullBackOff</td>
<td>컨테이너 이미지를 가져오지 못함</td>
</tr>
</tbody></table>
<hr>
<h2 id="정리">정리</h2>
<p>  K8s SRE의 핵심은 <strong>동적 환경에 맞는 관찰 방식</strong>이다. Pod가 언제든 사라질 수 있기 때문에 로그는 중앙에 수집하고, 메트릭은 서비스 전체 단위로 보고, Probe로 트래픽 유입 시점을 정확히 제어해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Reliability Patterns]]></title>
            <link>https://velog.io/@han_s/Reliability-Patterns</link>
            <guid>https://velog.io/@han_s/Reliability-Patterns</guid>
            <pubDate>Sat, 21 Mar 2026 04:18:14 GMT</pubDate>
            <description><![CDATA[<h2 id="reliability-patterns">Reliability Patterns</h2>
<p>  장애는 막을 수 없다. 대신 장애가 전파되지 않게 막거나, 부분적으로만 동작하거나, 빠르게 회복하도록 설계할 수 있다. 그게 Reliability Patterns의 목적이다.</p>
<hr>
<h2 id="circuit-breaker">Circuit Breaker</h2>
<p>  문제가 생긴 서비스로의 요청을 자동으로 차단해서 장애 전파를 막는 패턴이다.</p>
<table>
<thead>
<tr>
<th>상태</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Closed</td>
<td>정상. 요청이 통과된다</td>
</tr>
<tr>
<td>Open</td>
<td>차단. 요청을 바로 실패 처리한다</td>
</tr>
<tr>
<td>Half-Open</td>
<td>일부 요청만 통과시켜서 복구됐는지 확인한다</td>
</tr>
</tbody></table>
<p>  실패율이 임계값을 넘으면 Open 상태가 된다. 일정 시간 후 Half-Open으로 전환되고, 일부 요청이 성공하면 Closed로 복귀한다. 계속 재시도하다가 시스템 전체가 느려지는 걸 막는 게
  핵심이다.</p>
<hr>
<h2 id="retry--exponential-backoff">Retry + Exponential Backoff</h2>
<p>  일시적인 장애에서 재시도하는 패턴이다. 무작정 재시도하면 서버에 부하가 몰리기 때문에 재시도 간격을 점점 늘린다.</p>
<ul>
<li><p>1차 재시도: 1초 후</p>
</li>
<li><p>2차 재시도: 2초 후</p>
</li>
<li><p>3차 재시도: 4초 후</p>
<p>여기에 <strong>Jitter(무작위 편차)</strong>를 추가하면 여러 클라이언트가 동시에 재시도하는 Thundering Herd를 방지할 수 있다. Jitter가 없으면 1000개 클라이언트가 전부 동시에 재시도해서 서버
부하가 급등한다.</p>
</li>
</ul>
<hr>
<h2 id="bulkhead">Bulkhead</h2>
<p>  배의 격벽처럼 서비스 리소스를 격리해서 한 곳의 장애가 전체로 번지지 않게 막는 패턴이다.</p>
<p>  결제 API와 조회 API가 같은 스레드 풀을 쓰면 조회 요청이 폭발할 때 결제도 느려진다. Bulkhead를 적용하면 스레드 풀을 분리해서 서로 영향을 안 준다.</p>
<p>  Circuit Breaker와 헷갈리기 쉬운데 구분 기준은 이렇다.</p>
<ul>
<li><strong>Circuit Breaker</strong>: 문제 있는 서비스로 요청이 가는 걸 차단</li>
<li><strong>Bulkhead</strong>: 서비스 간 리소스를 격리해서 영향이 번지는 걸 차단</li>
</ul>
<hr>
<h2 id="timeout">Timeout</h2>
<p>  응답을 무한정 기다리지 않고 일정 시간 후 실패 처리하는 패턴이다. Timeout이 없으면 느린 서비스 하나가 전체 요청을 블로킹한다.</p>
<hr>
<h2 id="graceful-degradation">Graceful Degradation</h2>
<p>  일부 기능이 실패해도 핵심 기능은 동작하게 유지하는 패턴이다.</p>
<ul>
<li><p>추천 서비스가 죽어도 상품 목록은 보여준다</p>
</li>
<li><p>실시간 데이터를 못 가져오면 캐시된 데이터를 보여준다</p>
<p>전부 아니면 전무(All or Nothing)가 아니라, 부분적으로라도 동작하는 것이 목표다.</p>
</li>
</ul>
<hr>
<h2 id="정리">정리</h2>
<table>
<thead>
<tr>
<th>패턴</th>
<th>목적</th>
</tr>
</thead>
<tbody><tr>
<td>Circuit Breaker</td>
<td>장애 전파 차단</td>
</tr>
<tr>
<td>Retry + Backoff</td>
<td>일시적 장애 극복</td>
</tr>
<tr>
<td>Bulkhead</td>
<td>장애 격리</td>
</tr>
<tr>
<td>Timeout</td>
<td>블로킹 방지</td>
</tr>
<tr>
<td>Graceful Degradation</td>
<td>부분 동작 유지</td>
</tr>
</tbody></table>
<p>  이 패턴들은 하나만 쓰는 게 아니라 조합해서 쓴다. 실제 시스템에서는 Timeout + Circuit Breaker + Graceful Degradation이 같이 적용되는 경우가 많다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Change Management]]></title>
            <link>https://velog.io/@han_s/Change-Management</link>
            <guid>https://velog.io/@han_s/Change-Management</guid>
            <pubDate>Fri, 20 Mar 2026 06:43:11 GMT</pubDate>
            <description><![CDATA[<h2 id="change-management">Change Management</h2>
<p>  서비스 장애의 70% 이상은 변경(Change)에서 발생한다. 새 기능 배포, 설정 변경, 인프라 업그레이드 — 전부 변경이다.</p>
<p>  Change Management는 <strong>변경으로 인한 장애를 최소화하기 위한 프로세스</strong>다. 변경을 막는 게 아니라, 변경을 안전하게 하는 것이 목적이다.</p>
<hr>
<h2 id="변경의-종류">변경의 종류</h2>
<table>
<thead>
<tr>
<th>종류</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>Standard Change</td>
<td>반복적이고 검증된 변경</td>
<td>패치 배포, 설정 변경</td>
</tr>
<tr>
<td>Normal Change</td>
<td>사전 검토가 필요한 변경</td>
<td>신규 기능 배포, 아키텍처 변경</td>
</tr>
<tr>
<td>Emergency Change</td>
<td>장애 대응을 위한 긴급 변경</td>
<td>핫픽스, 롤백</td>
</tr>
</tbody></table>
<hr>
<h2 id="배포-전략">배포 전략</h2>
<p>  변경을 안전하게 하는 핵심은 점진적 배포다.</p>
<p>  <strong>Canary 배포</strong>
  전체 트래픽 중 일부(예: 1~5%)에만 먼저 배포한다. 문제가 없으면 점진적으로 확대하고, 문제가 생기면 해당 트래픽만 롤백하면 된다.</p>
<p>  <strong>Blue/Green 배포</strong>
  기존 환경(Blue)을 그대로 두고 새 환경(Green)을 별도로 구성한다. 준비되면 트래픽을 한 번에 전환하고, 문제 시 Blue로 즉시 롤백 가능하다.</p>
<p>  <strong>Feature Flag</strong>
  코드 배포와 기능 활성화를 분리한다. 코드는 배포됐지만 플래그를 끄면 사용자에게 노출되지 않는다. 특정 사용자 그룹에만 먼저 켤 수도 있다.</p>
<hr>
<h2 id="dora-지표">DORA 지표</h2>
<p>  Change Management 수준을 측정하는 4가지 지표다.</p>
<table>
<thead>
<tr>
<th>지표</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>Deployment Frequency</td>
<td>얼마나 자주 배포하는가</td>
</tr>
<tr>
<td>Lead Time for Changes</td>
<td>코드 커밋 → 프로덕션 배포까지 걸리는 시간</td>
</tr>
<tr>
<td>Change Failure Rate</td>
<td>배포 중 장애 발생 비율</td>
</tr>
<tr>
<td>Time to Restore</td>
<td>장애 발생 후 복구까지 걸리는 시간</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>등급</th>
<th>Change Failure Rate</th>
</tr>
</thead>
<tbody><tr>
<td>Elite</td>
<td>0~15%</td>
</tr>
<tr>
<td>High</td>
<td>16~30%</td>
</tr>
<tr>
<td>Medium/Low</td>
<td>46~60%</td>
</tr>
</tbody></table>
<p>  배포를 자주 하면서 Change Failure Rate가 낮은 팀이 잘하는 팀이다.</p>
<hr>
<h2 id="롤백-전략">롤백 전략</h2>
<p>  배포했는데 문제가 생기면 빠르게 롤백할 수 있어야 한다.</p>
<ul>
<li>롤백 절차가 미리 정의되어 있어야 한다</li>
<li>롤백 시간이 길면 그만큼 장애 시간이 늘어난다</li>
<li>DB 스키마 변경은 기존 데이터에 영향을 주고 하위 호환을 깨뜨릴 수 있어서 별도 전략이 필요하다</li>
</ul>
<hr>
<h2 id="정리">정리</h2>
<p>  변경을 줄이는 것이 답이 아니다. 오히려 자주 배포하되 안전하게 하는 것이 목표다. Canary, Blue/Green, Feature Flag로 점진적으로 배포하고, DORA 지표로 수준을 측정하고, 롤백 절차를
  미리 준비해두는 것이 Change Management의 핵심이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SLO 기반 알림]]></title>
            <link>https://velog.io/@han_s/SLO-%EA%B8%B0%EB%B0%98-%EC%95%8C%EB%A6%BC</link>
            <guid>https://velog.io/@han_s/SLO-%EA%B8%B0%EB%B0%98-%EC%95%8C%EB%A6%BC</guid>
            <pubDate>Thu, 19 Mar 2026 04:54:54 GMT</pubDate>
            <description><![CDATA[<h2 id="slo-기반-알림">SLO 기반 알림</h2>
<p>  알림 기준을 어떻게 정할 건지가 문제다. CPU 75%면 알림? 에러율 1%면 알림? 이 숫자들이 감으로 정해진 거라면 SLO 달성과 직접 연결이 안 된다.</p>
<p>  SLO 기반 알림은 <strong>SLO와 Error Budget을 기준으로 알림을 설계</strong>하는 방식이다.</p>
<hr>
<h2 id="burn-rate">Burn Rate</h2>
<p>  Error Budget이 얼마나 빠르게 소진되고 있는지를 나타내는 지표다.</p>
<ul>
<li><p>SLO: 월 99.9% 가용성 → Error Budget = 월 43.2분</p>
</li>
<li><p>Burn Rate 1 = 정상 속도로 소진 중</p>
</li>
<li><p>Burn Rate 10 = 10배 빠르게 소진 중</p>
</li>
<li><p>Burn Rate 720 = 1시간 안에 한 달치 Error Budget을 다 쓴다</p>
<p>Burn Rate가 높을수록 긴급하다.</p>
</li>
</ul>
<hr>
<h2 id="왜-burn-rate-기반으로-설계하나">왜 Burn Rate 기반으로 설계하나</h2>
<table>
<thead>
<tr>
<th>방식</th>
<th>문제</th>
</tr>
</thead>
<tbody><tr>
<td>단순 에러율 기반</td>
<td>에러율 1%가 1분인지 1시간인지 모른다</td>
</tr>
<tr>
<td>고정 임계값 기반</td>
<td>SLO와 연결이 없어서 실제 영향도를 모른다</td>
</tr>
<tr>
<td>Burn Rate 기반</td>
<td>SLO 달성 여부에 직접 연결되어 있다</td>
</tr>
</tbody></table>
<p>  에러율이 낮아도 오래 지속되면 Error Budget이 많이 소진된다. 반대로 에러율이 높아도 금방 회복되면 SLO에 영향이 없다. Burn Rate는 이 둘을 모두 반영한다.</p>
<hr>
<h2 id="멀티-윈도우-알림">멀티 윈도우 알림</h2>
<p>  Burn Rate만으로는 부족하다. 단기 급등인지 장기 지속인지 구분이 안 되기 때문이다.</p>
<table>
<thead>
<tr>
<th>윈도우</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td>1시간</td>
<td>지금 당장 빠르게 소진되고 있는지 감지</td>
</tr>
<tr>
<td>6시간</td>
<td>단기 급등이 아니라 실제 지속되는 문제인지 확인</td>
</tr>
</tbody></table>
<p>  두 윈도우 모두 Burn Rate가 높을 때만 알림을 낸다. 1시간만 높으면 노이즈일 가능성이 크다.</p>
<hr>
<h2 id="알림-티어-설계">알림 티어 설계</h2>
<table>
<thead>
<tr>
<th>티어</th>
<th>Burn Rate 기준</th>
<th>대응</th>
</tr>
</thead>
<tbody><tr>
<td>Page (즉시 대응)</td>
<td>14x 이상</td>
<td>1시간 안에 한 달 Error Budget 5% 소진</td>
</tr>
<tr>
<td>Ticket (업무 시간 대응)</td>
<td>1x ~ 3x</td>
<td>느리게 소진 중, 당장 급하진 않음</td>
</tr>
</tbody></table>
<p>  모든 알림을 Page로 설계하면 Alert Fatigue가 온다. 긴급도에 따라 티어를 나눠야 한다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>  SLO 기반 알림 설계 순서는 이렇다.</p>
<p>  <strong>SLO 정의 → Error Budget 계산 → Burn Rate 설계 → 알림 티어 설정</strong></p>
<p>  기존 임계값 방식보다 복잡하지만 사용자 영향도와 직접 연결되어 있고, Alert Fatigue를 줄일 수 있다. 긴급한 것과 그렇지 않은 것을 구분하는 게 핵심이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Chaos Engineering]]></title>
            <link>https://velog.io/@han_s/Chaos-Engineering</link>
            <guid>https://velog.io/@han_s/Chaos-Engineering</guid>
            <pubDate>Wed, 18 Mar 2026 04:12:05 GMT</pubDate>
            <description><![CDATA[<h2 id="chaos-engineering">Chaos Engineering</h2>
<p>  시스템이 &quot;잘 돌아가고 있다&quot;는 건 장애가 없는 게 아니라 <strong>장애가 와도 버틸 수 있다</strong>는 뜻이다. Chaos Engineering은 그걸 미리 검증하는 방법이다.</p>
<p>  한 줄 정의: <strong>의도적으로 장애를 만들어서 시스템의 약점을 먼저 찾는 것</strong></p>
<p>  Netflix가 처음 만든 개념이다. 프로덕션 서버를 무작위로 죽이는 &quot;Chaos Monkey&quot;를 실제로 운영했고, 거기서 발전했다.</p>
<hr>
<h2 id="왜-하는가">왜 하는가</h2>
<p>  테스트는 &quot;예상한 시나리오&quot;만 검증한다. 근데 실제 장애는 예상 밖에서 온다.</p>
<ul>
<li><p>특정 서버가 갑자기 죽으면?</p>
</li>
<li><p>DB 응답이 10배 느려지면?</p>
</li>
<li><p>네트워크 패킷이 30% 손실되면?</p>
<p>이런 상황을 미리 만들어보면 시스템이 어떻게 반응하는지 알 수 있다. 모르는 채로 있다가 실제 장애 때 처음 보는 것보다 훨씬 낫다.</p>
</li>
</ul>
<hr>
<h2 id="핵심-원칙">핵심 원칙</h2>
<table>
<thead>
<tr>
<th>원칙</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>가설 수립</td>
<td>&quot;이게 죽어도 서비스는 정상이어야 한다&quot;는 기대치를 먼저 정한다</td>
</tr>
<tr>
<td>최소 범위</td>
<td>영향 범위를 최대한 좁게 시작한다 (프로덕션 전체 X, 인스턴스 1개부터)</td>
</tr>
<tr>
<td>자동 중단</td>
<td>예상보다 피해가 커지면 즉시 중단할 수 있어야 한다</td>
</tr>
<tr>
<td>결과 분석</td>
<td>가설과 실제를 비교하고 약점을 문서화한다</td>
</tr>
</tbody></table>
<hr>
<h2 id="실험-절차">실험 절차</h2>
<ol>
<li><p><strong>정상 상태 정의</strong>: 지금 시스템의 정상 기준을 SLI로 정한다 (예: 에러율 &lt; 1%)</p>
</li>
<li><p><strong>가설 수립</strong>: &quot;서버 1대가 죽어도 에러율 1% 미만이어야 한다&quot;</p>
</li>
<li><p><strong>실험 설계</strong>: 어떤 장애를 어떤 범위에서 주입할지 결정</p>
</li>
<li><p><strong>실행</strong>: 장애 주입</p>
</li>
<li><p><strong>관찰</strong>: 시스템이 가설대로 동작하는지 확인</p>
</li>
<li><p><strong>복구 &amp; 분석</strong>: 결과 기록, 약점 발견 시 개선</p>
<p>정상 상태 정의가 가장 먼저다. 지금 정상이 뭔지 알아야 가설을 세울 수 있기 때문이다.</p>
</li>
</ol>
<hr>
<h2 id="대표-도구">대표 도구</h2>
<table>
<thead>
<tr>
<th>도구</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td>Chaos Monkey</td>
<td>Netflix 오픈소스, AWS EC2 인스턴스 랜덤 종료</td>
</tr>
<tr>
<td>Chaos Toolkit</td>
<td>오픈소스, 다양한 환경 지원</td>
</tr>
<tr>
<td>AWS Fault Injection Simulator</td>
<td>AWS 관리형 서비스</td>
</tr>
<tr>
<td>Litmus</td>
<td>Kubernetes 환경 특화</td>
</tr>
</tbody></table>
<hr>
<h2 id="game-day">Game Day</h2>
<p>  Chaos Engineering을 팀 훈련으로 만든 것이 <strong>Game Day</strong>다.</p>
<p>  정해진 날에 팀 전체가 모여서 의도적으로 장애를 내고, On-call 프로세스가 제대로 동작하는지 처음부터 끝까지 훈련한다. 알림이 제대로 오는지, Runbook대로 대응이 되는지, MTTA/MTTR이
  목표치 안에 드는지 전부 확인한다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>  Chaos Engineering은 &quot;장애가 안 나게 하는 것&quot;이 아니라 &quot;장애가 났을 때 시스템이 어떻게 반응하는지 미리 아는 것&quot;이다.</p>
<p>  일반 테스트가 예상한 시나리오를 검증한다면, Chaos Engineering은 예상 밖 상황을 검증한다. 둘은 대체 관계가 아니라 보완 관계다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[On-call 운영]]></title>
            <link>https://velog.io/@han_s/On-call-%EC%9A%B4%EC%98%81</link>
            <guid>https://velog.io/@han_s/On-call-%EC%9A%B4%EC%98%81</guid>
            <pubDate>Tue, 17 Mar 2026 08:40:59 GMT</pubDate>
            <description><![CDATA[<h2 id="on-call">On-call</h2>
<p>  On-call은 서비스 장애가 발생했을 때 즉시 대응할 수 있는 당직 체계다. 24시간 365일 서비스를
  운영하면 언제든 장애가 터질 수 있는데, 그때 &quot;누가 받을 건데?&quot;를 미리 정해두는 것이다.</p>
<p>  개발자 한 명이 항상 대기하는 게 아니라, 팀원들이 돌아가면서 담당하는 <strong>Rotation</strong> 구조로 운영한다.</p>
<hr>
<h2 id="핵심-구성-요소">핵심 구성 요소</h2>
<table>
<thead>
<tr>
<th>개념</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Rotation</td>
<td>팀원들이 순서대로 돌아가며 담당</td>
</tr>
<tr>
<td>Primary</td>
<td>1차 대응자. 알림을 가장 먼저 받는다</td>
</tr>
<tr>
<td>Secondary</td>
<td>Primary가 응답 없을 때 대신 받는 백업</td>
</tr>
<tr>
<td>Escalation Policy</td>
<td>Primary → Secondary → Manager 순서로 에스컬레이션하는 규칙</td>
</tr>
</tbody></table>
<p>  Escalation Policy가 없으면 Primary가 못 받았을 때 알림이 그냥 사라진다. 반드시 있어야 한다.</p>
<hr>
<h2 id="핵심-지표">핵심 지표</h2>
<p>  On-call 품질을 측정하는 지표가 두 가지 있다.</p>
<table>
<thead>
<tr>
<th>지표</th>
<th>풀네임</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>MTTA</td>
<td>Mean Time To Acknowledge</td>
<td>알림 발생 → 담당자가 인지할 때까지 평균 시간</td>
</tr>
<tr>
<td>MTTR</td>
<td>Mean Time To Resolve</td>
<td>알림 발생 → 완전히 해결될 때까지 평균 시간</td>
</tr>
</tbody></table>
<p>  MTTA가 길다는 건 알림을 못 받거나 늦게 확인한다는 뜻이다. MTTR이 길다는 건 인지는 했는데 해결이
  느리다는 뜻이다. 둘 다 추적해야 어디서 병목인지 보인다.</p>
<hr>
<h2 id="on-call-피로">On-call 피로</h2>
<p>  On-call 자체보다 <strong>On-call 피로(Fatigue)</strong>가 더 큰 문제다. 피로가 쌓이면 알림을 무시하거나,
  번아웃이 오거나, 팀 전체 사기가 떨어진다.</p>
<p>  주요 원인은 세 가지다.</p>
<p>  <strong>1. 노이즈 알림</strong>
  진짜 장애가 아닌데 울리는 알림. 알림이 자주 오면 &quot;또 오겠지&quot;라는 학습된 무기력이 생긴다. Alerting
   설계를 잘못하면 여기서 막힌다.</p>
<p>  <strong>2. 불공평한 로테이션</strong>
  특정 사람만 자꾸 당직을 서거나, 야간 당직이 한쪽에 몰리면 반드시 문제가 된다. 자동화된 스케줄링
  도구(PagerDuty, OpsGenie 등)를 쓰는 이유가 여기 있다.</p>
<p>  <strong>3. 보상 없음</strong>
  야간에 2시간 대응하고 아무 보상이 없으면 지속 불가능하다. 보상 체계가 없는 On-call은 팀 이탈로
  이어진다.</p>
<hr>
<h2 id="runbook">Runbook</h2>
<p>  Runbook은 장애 대응 절차서다. &quot;이 알림이 오면 이렇게 해라&quot;를 미리 적어두는 것이다.</p>
<p>  On-call 담당자가 해당 서비스를 잘 모르는 경우가 있다. 로테이션으로 돌아가다 보면 내 영역이 아닌
  서비스 당직을 서야 할 수도 있기 때문이다. Runbook이 잘 정비돼 있으면 모르는 서비스도 절차대로
  대응할 수 있다.</p>
<p>  좋은 Runbook의 조건:</p>
<ul>
<li>알림 이름과 1:1로 매핑되어 있다</li>
<li>진단 명령어가 복붙 가능한 형태로 있다</li>
<li>&quot;이 단계에서 모르겠으면 누구한테 연락해라&quot;가 명시되어 있다</li>
</ul>
<hr>
<h2 id="정리">정리</h2>
<p>  On-call은 그냥 폰 들고 대기하는 게 아니다. Rotation, Escalation Policy, Runbook이 제대로 갖춰져야
   지속 가능한 운영이 된다. MTTA/MTTR로 측정하고, 피로 원인을 주기적으로 점검하는 게 SRE의
  역할이다.</p>
<p>  결국 On-call을 잘한다는 건 &quot;장애를 빨리 끄는 것&quot;이 아니라 &quot;장애가 와도 팀이 지치지 않는 구조를
  만드는 것&quot;이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Capacity Planning]]></title>
            <link>https://velog.io/@han_s/Capacity-Planning</link>
            <guid>https://velog.io/@han_s/Capacity-Planning</guid>
            <pubDate>Thu, 12 Mar 2026 10:58:53 GMT</pubDate>
            <description><![CDATA[<p>Capacity Planning</p>
<p>  장애가 나고 나서 서버를 늘리는 게 아니라,
  미리 예측해서 준비하는 방법에 대한 내용이다.</p>
<hr>
<h2 id="capacity-planning이-뭔가">Capacity Planning이 뭔가</h2>
<p>  한 줄 정의는 이렇다.</p>
<blockquote>
<p>&quot;미래의 트래픽을 예측해서 서버 용량을 미리 준비하는 것&quot;</p>
</blockquote>
<p>  준비가 안 됐을 때와 됐을 때의 차이는 명확하다.</p>
<p>  ❌ 준비 안 했을 때
  트래픽 폭증 → 서버 다운 → Error Budget 소진</p>
<p>  ✅ 준비 했을 때
  성장률 예측 → 미리 확장 → 장애 없음</p>
<hr>
<h2 id="핵심-3가지">핵심 3가지</h2>
<p>  <strong>1. 현재 용량 파악</strong></p>
<p>  지금 시스템이 어느 정도를 버티는지 먼저 알아야 한다.
  TPS, CPU, 메모리, 응답시간이 SLO를 넘기 시작하는 지점을 측정한다.</p>
<p>  <strong>2. 트래픽 성장 예측</strong></p>
<p>  과거 데이터로 성장률을 계산한다.</p>
<p>  3개월 전: 1,000 TPS → 현재: 1,300 TPS → 월 성장률 약 10%
  6개월 후 예측: 약 2,300 TPS</p>
<p>  <strong>3. 여유분 (Headroom) 확보</strong></p>
<p>  예측은 항상 틀릴 수 있다.
  이벤트나 마케팅으로 갑자기 폭증할 수도 있다.
  그래서 예측값의 30% 정도 여유를 두고 준비한다.</p>
<hr>
<h2 id="use-method">USE Method</h2>
<p>  시스템 용량 상태를 판단하는 기준이다.</p>
<table>
<thead>
<tr>
<th>신호</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Utilization</td>
<td>현재 얼마나 쓰고 있는가</td>
</tr>
<tr>
<td>Saturation</td>
<td>처리 못하고 대기 중인 게 있는가</td>
</tr>
<tr>
<td>Errors</td>
<td>오류가 발생하고 있는가</td>
</tr>
</tbody></table>
<p>  Utilization이 높아도 Saturation이 없으면 아직 괜찮다.
  Saturation이 생기기 시작하면 용량 한계에 가까워진 신호다.</p>
<hr>
<h2 id="언제-확장해야-하는가">언제 확장해야 하는가</h2>
<p>  Utilization 70% 도달 → 확장 계획 시작
  Utilization 85% 도달 전 → 확장 완료</p>
<p>  월 10% 성장률 기준으로 계산하면 이렇다.</p>
<p>  현재 60% → 1개월 후 66% → 2개월 후 73% (70% 초과)
  → 지금부터 1개월 안에 계획 수립 필요</p>
<p>  너무 일찍 확장하면 비용 낭비고,
  너무 늦으면 장애로 이어진다.
  숫자로 계산해서 타이밍을 잡는 게 핵심이다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>  Capacity Planning은 결국 Error Budget과 연결된다.</p>
<p>  용량 초과로 장애가 나면 Error Budget이 소진된다.
  미리 준비해두면 예방 가능한 Budget 소진을 막을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SRE(1차정리)]]></title>
            <link>https://velog.io/@han_s/SRE1%EC%B0%A8%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@han_s/SRE1%EC%B0%A8%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 11 Mar 2026 09:49:01 GMT</pubDate>
            <description><![CDATA[<h2 id="sli--slo--sla">SLI / SLO / SLA</h2>
<p>  서비스를 수치로 정의하는 개념이다.</p>
<p>  SLI는 현재 서비스 상태를 측정한 수치고,
  SLO는 팀 내부에서 유지해야 하는 목표값이다.
  SLA는 그 목표를 고객과 계약으로 맺은 것으로, 위반하면 패널티가 생긴다.</p>
<p>  쉽게 기억하는 방법은 이렇다.</p>
<p>  SLI  →  지금 가용성이 99.7%다 (측정값)
  SLO  →  99.9% 이상 유지해야 한다 (내부 목표)
  SLA  →  99.5% 보장, 위반 시 환불 (고객 계약)</p>
<p>  SLA는 항상 SLO보다 낮게 설정한다.
  그 차이가 버퍼가 되어서 SLO를 약간 못 지켜도 고객 클레임이 발생하지 않는다.</p>
<hr>
<h2 id="error-budget">Error Budget</h2>
<p>  SLO를 기반으로 실패해도 되는 허용 범위를 수치로 정한 것이다.</p>
<p>  Error Budget = 100% - SLO
  SLO 99.9% → 한 달 43.2분까지 다운돼도 괜찮다</p>
<p>  버짓을 최대한 아끼는 게 목표가 아니다.
  버짓은 새 기능을 배포하기 위한 연료다.
  버짓이 남아있을 때 적극적으로 배포하고,
  소진되면 배포를 중단하고 안정성 개선을 먼저 한다.</p>
<p>  버짓 소진이 꼭 개발팀 배포 때문만은 아니다.
  인프라 문제나 외부 의존성 장애도 버짓을 소진시킨다.</p>
<hr>
<h2 id="toil">Toil</h2>
<p>  자동화할 수 있는데 사람이 손으로 반복하고 있는 작업이다.</p>
<p>  귀찮은 일이랑은 다르다.
  반복적이고, 자동화 가능하고, 서비스가 커질수록 같이 늘어나는 작업이 Toil이다.</p>
<p>  Google SRE 기준으로 Toil은 업무 시간의 50%를 넘으면 안 된다.
  넘기는 순간 개선하는 팀이 아니라 그냥 반복 작업하는 팀이 된다.</p>
<p>  자동화도 비용이 들기 때문에 무조건 하는 게 아니라
  절감 효과가 자동화 비용보다 클 때 한다.</p>
<hr>
<h2 id="observability">Observability</h2>
<p>  모니터링이랑 다른 개념이다.</p>
<p>  모니터링은 미리 정해둔 지표를 보는 것이고,
  Observability는 어떤 질문이든 데이터로 답할 수 있는 능력이다.</p>
<p>  세 기둥으로 구성된다.</p>
<table>
<thead>
<tr>
<th>기둥</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td>Metrics</td>
<td>얼마나 이상한지 수치로 감지</td>
</tr>
<tr>
<td>Logs</td>
<td>무슨 일이 있었는지 원인 파악</td>
</tr>
<tr>
<td>Traces</td>
<td>어느 구간에서 문제가 생겼는지 위치 특정</td>
</tr>
</tbody></table>
<p>  세 개가 같이 있어야 장애를 빠르게 해결할 수 있다.
  Metrics만 있으면 &quot;이상하다&quot;는 건 알지만 왜, 어디서인지는 모른다.</p>
<hr>
<h2 id="alerting-설계">Alerting 설계</h2>
<p>  알림이 많다고 좋은 게 아니다.</p>
<p>  알림이 너무 많으면 Alert Fatigue가 생긴다.
  팀이 알림에 무감각해져서 진짜 장애 알림도 무시하게 된다.</p>
<p>  좋은 알림은 사용자가 실제로 영향을 받는 증상 기준으로 설계한다.</p>
<p>  ❌ &quot;DB 슬로우 쿼리 10개 발생&quot; → 내부 수치, 사용자 영향 불명확
  ✅ &quot;결제 성공률 95% 아래로 하락&quot; → 사용자가 결제를 못 하고 있음</p>
<p>  그리고 알림마다 Runbook을 연결해두면
  처음 보는 알림도 절차대로 대응할 수 있다.</p>
<hr>
<h2 id="incident-management">Incident Management</h2>
<p>  장애가 발생했을 때 표준화된 절차로 대응하는 것이다.</p>
<p>  감지 → 대응 → 완화 → 해결 → 사후분석</p>
<p>  완화는 일단 불을 끄는 것이고, 해결은 불이 왜 났는지 찾는 것이다.
  급할 때는 완화 먼저, 그 다음 근본 원인을 해결한다.</p>
<p>  장애가 끝난 후에는 반드시 Postmortem을 작성한다.
  핵심은 사람을 비난하지 않는 것이다.
  누가 실수했는지가 아니라 왜 그 실수가 장애로 이어질 수 있었는지를 본다.</p>
<p>  근본 원인은 5 Whys로 찾는다.
  &quot;왜?&quot;를 5번 반복해서 표면적 원인이 아닌 진짜 원인을 찾는 것이다.
  마지막 원인이 팀이 실제로 개선할 수 있는 것이어야 한다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Incident Management]]></title>
            <link>https://velog.io/@han_s/Incident-Management</link>
            <guid>https://velog.io/@han_s/Incident-Management</guid>
            <pubDate>Wed, 11 Mar 2026 09:37:27 GMT</pubDate>
            <description><![CDATA[<h2 id="인시던트가-뭔가">인시던트가 뭔가</h2>
<p>  서비스 품질이 저하되거나 중단되는 사건이다.
  중요한 건 발생했을 때 표준화된 절차로 대응하는 것이다.</p>
<hr>
<h2 id="인시던트-대응-5단계">인시던트 대응 5단계</h2>
<table>
<thead>
<tr>
<th>단계</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Detection (감지)</td>
<td>알림으로 장애 인지</td>
</tr>
<tr>
<td>Response (대응)</td>
<td>담당자 연락, 상황 파악 시작</td>
</tr>
<tr>
<td>Mitigation (완화)</td>
<td>임시 조치로 영향 최소화</td>
</tr>
<tr>
<td>Resolution (해결)</td>
<td>근본 원인 해결</td>
</tr>
<tr>
<td>Postmortem (사후분석)</td>
<td>재발 방지 문서 작성</td>
</tr>
</tbody></table>
<p>  Mitigation과 Resolution을 헷갈리기 쉬운데 이렇게 구분하면 된다.</p>
<p>  Mitigation = 불 끄기 (서버 재시작으로 일단 복구)
  Resolution = 불이 왜 났는지 찾기 (메모리 누수 코드 수정)</p>
<p>  급할 때는 Mitigation 먼저, 그 다음 Resolution이다.</p>
<hr>
<h2 id="postmortem-사후-분석">Postmortem (사후 분석)</h2>
<p>  인시던트가 끝난 후 재발을 막기 위해 작성하는 문서다.
  서비스가 복구됐다고 안 쓰면 같은 장애가 반복된다.</p>
<h3 id="blameless-무비난-원칙">Blameless (무비난) 원칙</h3>
<blockquote>
<p>사람을 비난하지 않는다. 시스템의 문제를 찾는다.</p>
</blockquote>
<p>  ❌ 잘못된 접근
  &quot;김개발이 배포하다가 실수한 거잖아요&quot;</p>
<p>  ✅ 올바른 접근
  &quot;왜 배포 실수가 장애로 이어질 수 있는 구조였는가?&quot;</p>
<p>  사람을 탓하면 다음번에 장애를 숨기게 된다.
  시스템을 탓해야 다음번에 솔직하게 보고한다.</p>
<hr>
<h2 id="5-whys-기법">5 Whys 기법</h2>
<p>  근본 원인을 찾는 방법이다. &quot;왜?&quot;를 5번 반복한다.</p>
<p>  장애: 사용자들이 로그인을 못 하고 있다</p>
<p>  Why 1: 왜? → 인증 서버가 응답하지 않는다
  Why 2: 왜? → 메모리가 꽉 찼다
  Why 3: 왜? → 특정 요청이 메모리를 반환하지 않는다
  Why 4: 왜? → 예외 발생 시 finally 블록이 없다
  Why 5: 왜? → 예외 케이스 테스트 기준이 없었다</p>
<p>  근본 원인: 테스트 기준 부재</p>
<p>  표면적 원인만 보면 재시작으로 끝난다.
  근본 원인까지 찾아야 재발을 막을 수 있다.</p>
<p>  5 Whys의 핵심은 마지막 원인이 <strong>팀이 실제로 개선할 수 있는 것</strong>이어야 한다는 점이다.
  &quot;회사에 돈이 없어서&quot; 같은 답은 Action Item으로 이어질 수 없다.</p>
<hr>
<h2 id="postmortem-구성">Postmortem 구성</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td>인시던트 요약</td>
<td>언제, 얼마나, 어떤 영향</td>
</tr>
<tr>
<td>타임라인</td>
<td>시간 순서로 무슨 일이 있었는지</td>
</tr>
<tr>
<td>근본 원인</td>
<td>5 Whys로 찾은 진짜 원인</td>
</tr>
<tr>
<td>Action Items</td>
<td>재발 방지를 위한 구체적 조치 목록</td>
</tr>
</tbody></table>
<p>  Action Items는 반드시 구체적이고 추적 가능해야 한다.</p>
<p>  ❌ 나쁜 Action Item
  &quot;장애 재발 방지를 위해 노력한다&quot;</p>
<p>  ✅ 좋은 Action Item
  &quot;예외 케이스 테스트 가이드라인 작성 (담당: 김개발, 기한: 3/20)&quot;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Alerting 설계]]></title>
            <link>https://velog.io/@han_s/Alerting-%EC%84%A4%EA%B3%84</link>
            <guid>https://velog.io/@han_s/Alerting-%EC%84%A4%EA%B3%84</guid>
            <pubDate>Tue, 10 Mar 2026 08:29:45 GMT</pubDate>
            <description><![CDATA[<h2 id="alert-fatigue-알림-피로">Alert Fatigue (알림 피로)</h2>
<p>  나쁜 알림 설계의 가장 큰 부작용이다.</p>
<p>  알림이 너무 많으면
  → 팀원이 알림에 무감각해짐
  → 진짜 중요한 알림도 무시하게 됨
  → 실제 장애를 늦게 발견
  → 서비스 다운</p>
<p>  알림의 신뢰도를 유지하는 것 자체가 SRE의 중요한 역할이다.</p>
<hr>
<h2 id="나쁜-알림-vs-좋은-알림">나쁜 알림 vs 좋은 알림</h2>
<p>  ❌ 나쁜 알림
  CPU가 75%를 넘을 때마다 즉시 알림을 보낸다.
  순간적인 스파이크에도 울리고, 하루에 수십 번 발생할 수 있다.</p>
<p>  ✅ 좋은 알림
  CPU가 75%를 5분 이상 지속할 때 알림을 보낸다.
  10분 쿨다운으로 같은 알림이 반복되지 않는다.</p>
<hr>
<h2 id="좋은-알림의-5가지-원칙">좋은 알림의 5가지 원칙</h2>
<table>
<thead>
<tr>
<th>원칙</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Actionable</td>
<td>받으면 바로 조치할 수 있어야 한다</td>
</tr>
<tr>
<td>Symptom-based</td>
<td>사용자 영향 기준으로 설정한다</td>
</tr>
<tr>
<td>노이즈 제거</td>
<td>쿨다운, 지속시간 조건으로 불필요한 알림을 차단한다</td>
</tr>
<tr>
<td>심각도 구분</td>
<td>Critical은 즉시 대응, Warning은 나중에 확인</td>
</tr>
<tr>
<td>Runbook 연결</td>
<td>알림마다 대응 절차 문서를 링크한다</td>
</tr>
</tbody></table>
<hr>
<h2 id="symptom-based-vs-cause-based">Symptom-based vs Cause-based</h2>
<p>  가장 중요한 원칙이다.</p>
<p>  ❌ Cause-based (원인 기반)
  &quot;DB 슬로우 쿼리가 10개 발생했다&quot;
  → 내부 수치일 뿐, 사용자가 지금 불편한지 모른다</p>
<p>  ✅ Symptom-based (증상 기반)
  &quot;결제 성공률이 95% 아래로 떨어졌다&quot;
  → 사용자가 실제로 결제를 못 하고 있다</p>
<p>  사용자가 느끼는 증상을 기준으로 설계해야 한다.</p>
<hr>
<h2 id="runbook이-뭔가">Runbook이 뭔가</h2>
<p>  알림마다 연결해두는 대응 절차 문서다.</p>
<p>  알림: &quot;결제 오류율 2% 초과&quot;
  Runbook:</p>
<ol>
<li><p>결제 서비스 로그 확인</p>
</li>
<li><p>외부 PG사 상태 페이지 확인</p>
</li>
<li><p>이상 없으면 DB 커넥션 확인</p>
</li>
<li><p>해결 안 되면 온콜 담당자 호출</p>
<p>Runbook이 있으면 처음 보는 알림도 절차대로 대응할 수 있다.
없으면 매번 &quot;이거 어떻게 처리하지?&quot;부터 시작한다.</p>
</li>
</ol>
<hr>
<h2 id="정리">정리</h2>
<table>
<thead>
<tr>
<th></th>
<th>나쁜 알림</th>
<th>좋은 알림</th>
</tr>
</thead>
<tbody><tr>
<td>기준</td>
<td>내부 수치</td>
<td>사용자 영향</td>
</tr>
<tr>
<td>빈도</td>
<td>잦음</td>
<td>꼭 필요할 때만</td>
</tr>
<tr>
<td>중복</td>
<td>없음</td>
<td>쿨다운 적용</td>
</tr>
<tr>
<td>대응</td>
<td>즉흥적</td>
<td>Runbook 따라 처리</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Observability]]></title>
            <link>https://velog.io/@han_s/Observability</link>
            <guid>https://velog.io/@han_s/Observability</guid>
            <pubDate>Mon, 09 Mar 2026 10:10:39 GMT</pubDate>
            <description><![CDATA[<p>Observability(관측 가능성)</p>
<p>  처음엔 모니터링이랑 같은 말인 줄 알았는데 달랐다.</p>
<hr>
<h2 id="모니터링이랑-뭐가-다른가">모니터링이랑 뭐가 다른가</h2>
<p>  모니터링: &quot;CPU가 80%다&quot; → 미리 정해둔 지표를 보는 것
  Observability: &quot;왜 저 요청만 느린 거지?&quot; → 어떤 질문이든 데이터로 답할 수 있는 것</p>
<p>  모니터링은 알고 있는 문제를 감지한다.
  Observability는 모르는 문제도 찾아낼 수 있다.</p>
<hr>
<h2 id="세-기둥-three-pillars">세 기둥 (Three Pillars)</h2>
<p>  Observability는 세 가지로 구성된다.</p>
<table>
<thead>
<tr>
<th>기둥</th>
<th>형태</th>
<th>질문</th>
<th>도구</th>
</tr>
</thead>
<tbody><tr>
<td>Metrics</td>
<td>시계열 숫자</td>
<td>얼마나?</td>
<td>Prometheus, Grafana</td>
</tr>
<tr>
<td>Logs</td>
<td>이벤트 텍스트</td>
<td>무슨 일이?</td>
<td>ELK Stack, Loki</td>
</tr>
<tr>
<td>Traces</td>
<td>요청 흐름</td>
<td>어디서?</td>
<td>Jaeger, Zipkin</td>
</tr>
</tbody></table>
<hr>
<h2 id="각각-어떤-상황에서-쓰는가">각각 어떤 상황에서 쓰는가</h2>
<p>  ✅ Metrics
  오류율, 응답시간, CPU 같은 수치를 추적할 때.
  &quot;이상하다&quot;는 걸 가장 먼저 감지하는 역할이다.</p>
<p>  ✅ Logs
  특정 오류가 왜 발생했는지 파악할 때.
  &quot;무슨 일이 있었는지&quot; 상세하게 기록되어 있다.</p>
<p>  ✅ Traces
  요청이 시스템을 통과하는 전체 경로와 구간별 시간을 보여준다.</p>
<p>  사용자 요청 총 2,100ms
    ├─ API 서버 처리:  50ms
    ├─ DB 쿼리:     1,800ms  ← 여기가 문제
    └─ 외부 API 호출: 250ms</p>
<p>  DB가 느린지, 외부 API가 느린지 딱 집어낼 수 있다.</p>
<hr>
<h2 id="장애-상황에서-세-개를-같이-쓰면">장애 상황에서 세 개를 같이 쓰면</h2>
<p>  1단계 - Metrics로 감지:  &quot;오류율이 갑자기 5%로 올랐다&quot;
  2단계 - Logs로 원인 파악: &quot;결제 서비스에서 timeout 에러 발생&quot;
  3단계 - Traces로 위치 특정: &quot;외부 PG사 API 호출에서 3초씩 걸림&quot;</p>
<p>  세 개가 같이 있어야 장애를 빠르게 해결할 수 있다.
  하나만 있으면 절반만 보이는 것과 같다.</p>
<hr>
<h2 id="observability가-없으면">Observability가 없으면</h2>
<p>  ❌ 장애 발생
  → 어디가 문제인지 몰라서 코드 뒤짐
  → 로그 추가하고 재배포
  → 재현 시도
  → 틀리면 다시 반복
  → 수 시간 소요</p>
<p>  Observability가 있으면 Metrics로 감지하고,
  Logs로 원인 찾고, Traces로 위치 특정해서 수십 분 안에 해결된다.
  MTTR(평균 복구 시간)이 극적으로 줄어든다.</p>
<hr>
<h2 id="정리">정리</h2>
<table>
<thead>
<tr>
<th>기둥</th>
<th>알 수 있는 것</th>
<th>알 수 없는 것</th>
</tr>
</thead>
<tbody><tr>
<td>Metrics만 있을 때</td>
<td>이상 징후 감지</td>
<td>왜, 어디서 문제인지</td>
</tr>
<tr>
<td>Logs 추가</td>
<td>원인 파악</td>
<td>어느 구간인지</td>
</tr>
<tr>
<td>Traces 추가</td>
<td>병목 위치까지 특정</td>
<td>—</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toil]]></title>
            <link>https://velog.io/@han_s/Toil</link>
            <guid>https://velog.io/@han_s/Toil</guid>
            <pubDate>Sun, 08 Mar 2026 03:14:30 GMT</pubDate>
            <description><![CDATA[<h2 id="toil이-뭔가">Toil이 뭔가</h2>
<p>  한 줄 정의</p>
<blockquote>
<p>&quot;자동화할 수 있는데 사람이 손으로 반복하고 있는 작업&quot;</p>
</blockquote>
<p>  단순히 귀찮은 일이 아니다. Toil로 분류되려면 6가지를 만족해야 한다.</p>
<table>
<thead>
<tr>
<th>특징</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>수동적</td>
<td>사람이 직접 해야 한다</td>
</tr>
<tr>
<td>반복적</td>
<td>같은 작업이 계속 발생한다</td>
</tr>
<tr>
<td>자동화 가능</td>
<td>기계가 대신할 수 있다</td>
</tr>
<tr>
<td>전술적</td>
<td>당장은 해결되지만 장기적 가치가 없다</td>
</tr>
<tr>
<td>비례 증가</td>
<td>서비스가 커질수록 작업량도 같이 늘어난다</td>
</tr>
<tr>
<td>방치하면 쌓임</td>
<td>줄이려는 노력 없이는 계속 늘어난다</td>
</tr>
</tbody></table>
<hr>
<h2 id="뭐가-toil이고-뭐가-아닌가">뭐가 Toil이고 뭐가 아닌가</h2>
<p>  처음에 헷갈렸던 부분이다.</p>
<p>  ✅ Toil 맞음</p>
<ul>
<li>서버 추가할 때마다 설정 파일 직접 수정</li>
<li>배포할 때마다 같은 체크리스트 수동 확인</li>
<li>매월 서버 100대에 직접 SSH 접속해서 패치 적용</li>
</ul>
<p>❌ Toil 아님</p>
<ul>
<li><p>장애 원인 분석 (매번 다른 문제, 판단 필요)</p>
</li>
<li><p>코드 리뷰 (판단 필요)</p>
</li>
<li><p>아키텍처 설계 (창의적 작업)</p>
<p>장애 원인 분석을 Toil로 착각하기 쉬운데,
매번 다른 원인을 다루고 판단이 필요하기 때문에 Toil이 아니다.</p>
</li>
</ul>
<hr>
<h2 id="50-규칙">50% 규칙</h2>
<p>  Google SRE에서 정한 기준이다.</p>
<blockquote>
<p>SRE는 업무 시간의 50% 이상을 Toil에 써서는 안 된다</p>
</blockquote>
<table>
<thead>
<tr>
<th>Toil 비율</th>
<th>상태</th>
</tr>
</thead>
<tbody><tr>
<td>50% 미만</td>
<td>정상. 나머지를 자동화·개선에 사용</td>
</tr>
<tr>
<td>50~70%</td>
<td>경고. 자동화 계획 즉시 수립 필요</td>
</tr>
<tr>
<td>70% 초과</td>
<td>위험. SRE가 아니라 그냥 운영 인력이 된 상태</td>
</tr>
</tbody></table>
<hr>
<h2 id="10분밖에-안-걸리니까-괜찮다는-착각">&quot;10분밖에 안 걸리니까 괜찮다&quot;는 착각</h2>
<p>  Toil을 방치하는 가장 흔한 이유다.</p>
<p>  10분 × 365일 = 연 60시간이다.
  팀원 5명이면 연 300시간이다.
  그리고 서비스가 커지면 10분이 20분, 30분이 된다.</p>
<p>  지금 작다고 방치하면 나중에 더 크게 돌아온다.</p>
<hr>
<h2 id="자동화-투자-판단법">자동화 투자 판단법</h2>
<p>  Toil을 발견했다고 무조건 자동화하는 게 아니다.</p>
<blockquote>
<p>작업 시간 × 발생 빈도 &gt; 자동화 개발 시간이면 해야 한다</p>
</blockquote>
<p>  매주 3시간짜리 Toil이 있고 자동화 개발에 20시간이 걸린다면,
  7주 후부터 이득이고 1년 기준 136시간을 절약한다. 해야 한다.</p>
<p>  반대로 1년에 한 번 있는 작업을 자동화하는 데 40시간을 쓰면
  본전 뽑는 데 40년이 걸린다. 이건 하지 않는 게 낫다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>  Toil을 완전히 없애는 게 목표가 아니다.
  현실적으로 제로는 불가능하고, 자동화 자체도 비용이 든다.</p>
<p>  목표는 50% 이하로 유지하면서 남은 시간을 진짜 엔지니어링에 쓰는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Error Budget]]></title>
            <link>https://velog.io/@han_s/Error-Budget</link>
            <guid>https://velog.io/@han_s/Error-Budget</guid>
            <pubDate>Fri, 06 Mar 2026 13:35:25 GMT</pubDate>
            <description><![CDATA[<h2 id="error-budget">Error Budget</h2>
<p> 지난 글에서 SLI / SLO / SLA를 정리했다.</p>
<p> 이번엔 SLO를 배우고 나면 자연스럽게 나오는 질문,
 &quot;그래서 얼마나 실패해도 되는 거야?&quot; 에 대한 답인
 Error Budget을 정리해본다.</p>
<hr>
<h2 id="왜-필요한가">왜 필요한가</h2>
<p>  SLO를 정하고 나면 팀 안에서 이런 상황이 생긴다.</p>
<h3 id="상황">상황</h3>
<p>  개발팀:  &quot;새 기능 배포하고 싶은데요&quot;
  SRE팀:  &quot;배포하면 장애 날 수도 있어요. 위험합니다&quot;
  개발팀:  &quot;그럼 언제 배포할 수 있어요?&quot;
  SRE팀:  &quot;...&quot;</p>
<p>  SRE팀이 배포를 막는 역할이 되면 개발팀과 계속 충돌한다.
  이걸 없애려면 &quot;얼마나 실패해도 되는가&quot;를 미리 숫자로 정해야 한다.
  그게 Error Budget이다.</p>
<hr>
<h2 id="공식">공식</h2>
<p>  Error Budget = 100% - SLO</p>
<p>  SLO가 99.9%라면
  Error Budget = 100% - 99.9% = 0.1%
  0.1%가 체감이 잘 안 돼서 한 달(30일) 기준 분 단위로 바꾸면
  한 달 총 분 = 30 × 24 × 60 = 43,200분
  허용 다운타임 = 43,200 × 0.001 = 43.2분</p>
<p>  SLO 99.9% = 한 달에 43분까지는 서버가 죽어도 괜찮다는 뜻이다.</p>
<hr>
<h2 id="slo별로-얼마나-차이나는지">SLO별로 얼마나 차이나는지</h2>
<p>  직접 비교해보면 차이가 크게 느껴진다.</p>
<table>
<thead>
<tr>
<th>SLO</th>
<th>한 달 허용 다운타임</th>
</tr>
</thead>
<tbody><tr>
<td>99%</td>
<td>7시간 18분</td>
</tr>
<tr>
<td>99.9%</td>
<td>43분</td>
</tr>
<tr>
<td>99.99%</td>
<td>4분 19초</td>
</tr>
<tr>
<td>99.999%</td>
<td>26초</td>
</tr>
</tbody></table>
<hr>
<h2 id="배포-결정에-어떻게-쓰이는가">배포 결정에 어떻게 쓰이는가</h2>
<p>  버짓이 얼마나 남았냐에 따라 배포 여부를 결정한다.</p>
<p>  버짓 50% 이상 남음  →  대규모 배포 가능
  버짓 20~50% 남음   →  소규모 배포만 허용
  버짓 20% 미만 남음  →  배포 중단, 안정성 개선 집중
  버짓 소진           →  모든 배포 금지</p>
<p>  이렇게 하면 &quot;배포해도 돼요?&quot; 가 주관적인 판단이 아니라
  데이터 기반 대화가 된다.</p>
<hr>
<h2 id="가장-중요한-관점">가장 중요한 관점</h2>
<p>  처음 배울 때 이렇게 오해하기 쉽다.</p>
<p>  ❌ 버짓이 있으니까 그냥 실패해도 된다
  ❌ 버짓을 최대한 아껴야 한다</p>
<p>  ✅ 버짓은 혁신(배포)을 위한 연료다</p>
<p>  버짓이 남아있을 때 배포를 망설이는 것 자체가 낭비다.
  버짓은 다음 달로 이월되지 않는다.
  다 쓰지 않고 달이 끝나면 그냥 사라진다.</p>
<p>  반대로 버짓이 소진됐을 때 배포를 강행하는 것도 문제다.
  버짓 소진은 &quot;이번 달 시스템이 많이 불안정했다&quot;는 신호인데,
  원인도 모르는 상태에서 변경을 추가하면 위험이 겹친다.</p>
<hr>
<h2 id="버짓이-소진되는-원인">버짓이 소진되는 원인</h2>
<p>  한 가지 더 알게 된 것이 있다.</p>
<p>  버짓 소진이 꼭 개발팀 배포 때문만은 아니라는 점이다.</p>
<ul>
<li><p>개발팀 신규 배포 중 장애</p>
</li>
<li><p>인프라 문제로 서버 다운</p>
</li>
<li><p>외부 의존성 장애 (DB, 결제 API 등)</p>
</li>
<li><p>예측 불가한 자연 발생 장애</p>
<p>외부 API가 다운돼서 내 서비스가 영향을 받아도 버짓이 소진된다.
그래서 버짓이 소진됐을 때 개발팀만 탓할 수 없고,
SRE팀이 같이 원인을 찾아야 한다.</p>
</li>
</ul>
<hr>
<h2 id="정리">정리</h2>
<table>
<thead>
<tr>
<th>개념</th>
<th>한 줄 요약</th>
</tr>
</thead>
<tbody><tr>
<td>Error Budget</td>
<td>실패해도 되는 허용 범위 (100% - SLO)</td>
</tr>
<tr>
<td>버짓 남음</td>
<td>적극적으로 배포하고 실험</td>
</tr>
<tr>
<td>버짓 소진</td>
<td>배포 중단, 원인 분석 먼저</td>
</tr>
<tr>
<td>버짓 리셋</td>
<td>다음 달 돼도 원인 모르면 또 소진됨</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[SRE]]></title>
            <link>https://velog.io/@han_s/SRE</link>
            <guid>https://velog.io/@han_s/SRE</guid>
            <pubDate>Wed, 04 Mar 2026 09:09:21 GMT</pubDate>
            <description><![CDATA[<h2 id="sre가-뭔데">SRE가 뭔데</h2>
<p>  Google이 2003년에 만든 직군이자 운영 방법론이다.</p>
<p>  핵심은 이 한 문장이다.</p>
<blockquote>
<p>&quot;소프트웨어 엔지니어링 방식으로 운영 문제를 해결한다&quot;</p>
</blockquote>
<p>  기존에는 개발팀이 코드를 만들면 운영팀이 서버를 관리하는 구조였는데,
  서비스가 커질수록 수동 운영이 불가능해졌다.
  Google이 &quot;그냥 운영도 코드로 자동화하면 되지 않나?&quot;라고 생각한 게 시작이다.</p>
<p>  DevOps랑 자주 비교되는데 이렇게 이해하면 편하다.</p>
<ul>
<li><p>DevOps : 개발과 운영이 협력해야 한다는 <strong>문화/철학</strong></p>
</li>
<li><p>SRE : 그 철학을 <strong>어떻게 실행할지</strong>에 대한 구체적인 방법론</p>
<p>DevOps가 &quot;뭘 해야 하는지&quot;라면, SRE는 &quot;어떻게 하는지&quot;다.</p>
</li>
</ul>
<hr>
<h2 id="sli---지금-서비스-상태를-수치로-측정하는-것">SLI - 지금 서비스 상태를 수치로 측정하는 것</h2>
<p>  <strong>SLI(Service Level Indicator)</strong> 는 서비스 품질을 측정한 수치다.</p>
<p>  중요한 건 <strong>&quot;사용자가 체감하는 품질&quot;</strong> 을 기준으로 잡아야 한다는 점이다.</p>
<p>  좋은 SLI 예시</p>
<ul>
<li><p>가용성 : 정상 응답 수 / 전체 요청 수 × 100 = 99.95%</p>
</li>
<li><p>오류율 : 5xx 오류 수 / 전체 요청 수 × 100 = 0.03%</p>
</li>
<li><p>응답시간 : 요청의 99%가 200ms 이내로 처리됨</p>
<p>나쁜 SLI 예시</p>
</li>
<li><p>CPU 사용률 80% → 사용자 입장에서 직접적인 영향이 아님</p>
</li>
<li><p>서버 대수 3대 → 서비스 품질을 나타내지 않음</p>
<p>SLI는 <strong>측정된 숫자 그 자체</strong>다. 여기에 아무 판단이나 행동이 들어오면 SLI가 아니다.
&quot;현재 가용성이 99.7%이다&quot; — 이게 SLI다.</p>
</li>
</ul>
<hr>
<h2 id="slo---얼마나-유지해야-하는지-목표를-정하는-것">SLO - 얼마나 유지해야 하는지 목표를 정하는 것</h2>
<p>  <strong>SLO(Service Level Objective)</strong> 는 SLI에 목표값을 붙인 것이다.
  팀 내부에서 &quot;이 수준은 지키자&quot;고 정한 기준선이다.</p>
<p>  SLI :  현재 가용성이 99.7%이다       ← 측정값
  SLO :  가용성은 99.9% 이상이어야 한다 ← 목표값</p>
<p>  SLO는 내부 기준이라서, 위반해도 고객한테 직접 책임지는 일은 없다.
  다만 팀이 &quot;뭔가 잘못됐다&quot;는 신호로 받아들여야 한다.</p>
<p>  좋은 SLO를 정의하려면 세 가지 조건을 만족해야 한다.</p>
<ul>
<li><strong>사용자 관점</strong> : 사용자가 느끼는 품질을 반영해야 한다</li>
<li><strong>측정 가능</strong> : 수치로 명확하게 측정할 수 있어야 한다</li>
<li><strong>현실적</strong> : 달성 가능한 수준이어야 한다 (100%는 현실적으로 불가능하다)</li>
</ul>
<hr>
<h2 id="sla---고객한테-약속하는-것">SLA - 고객한테 약속하는 것</h2>
<p>  <strong>SLA(Service Level Agreement)</strong> 는 SLO를 고객과 계약으로 맺은 것이다.
  여기서부터 <strong>위반하면 패널티(환불, 크레딧 지급 등)</strong> 가 생긴다.</p>
<p>  SLO :  내부 목표 &quot;우리 팀은 99.9% 유지하자&quot;
  SLA :  외부 계약 &quot;고객에게 99.5% 보장, 위반 시 크레딧 지급&quot;</p>
<p>  AWS S3 서비스 정책을 보면 이런 내용이 있다.</p>
<blockquote>
<p>월간 가동률 99.9% 미만 시 서비스 크레딧 지급</p>
</blockquote>
<p>  이게 SLA다. AWS 내부에서 실제로 유지하는 SLO는 이것보다 훨씬 높게
  설정되어 있을 것이다.</p>
<hr>
<h2 id="왜-sla를-slo보다-낮게-잡는지">왜 SLA를 SLO보다 낮게 잡는지</h2>
<p>  처음에 이게 이해가 안 됐는데 이렇게 생각하면 된다.</p>
<p>  SLO = 99.9%  (내부 목표)
  SLA = 99.5%  (고객 보장)
        ↑
     0.4% 차이 = 여유분</p>
<p>  SLO를 약간 못 지켜서 실제 가용성이 99.6%가 되더라도,
  SLA(99.5%)는 지킬 수 있다. 고객 클레임이 발생하지 않는다.</p>
<p>  이 버퍼가 있어야 팀이 사고 없이 운영할 수 있다.</p>
<hr>
<h2 id="세-개념-정리">세 개념 정리</h2>
<p>  헷갈리지 않으려고 체온계로 비유해봤다.</p>
<p>  SLI  =  체온계 수치    (지금 38.2°C)
  SLO  =  의사의 목표    (37.5°C 이하로 유지)
  SLA  =  보험 계약      (40°C 이상이면 보험금 지급)</p>
<p>  표로 보면 이렇다.</p>
<table>
<thead>
<tr>
<th>용어</th>
<th>한 줄 요약</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>SLI</td>
<td>측정된 수치</td>
<td>가용성 99.7%</td>
</tr>
<tr>
<td>SLO</td>
<td>내부 팀의 목표값</td>
<td>가용성 99.9% 이상 유지</td>
</tr>
<tr>
<td>SLA</td>
<td>고객과의 계약</td>
<td>99.5% 보장, 위반 시 환불</td>
</tr>
</tbody></table>
<p>  외워야 할 것만 정리하면</p>
<ul>
<li>SLA ≤ SLO (항상 SLA가 더 낮거나 같다)</li>
<li>SLI는 숫자만, SLO는 숫자 + 기준, SLA는 숫자 + 기준 + 패널티</li>
<li>SLO 위반은 팀 내부 문제, SLA 위반은 고객 클레임</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>