카나리 배포

Canary deployment

새 버전을 소수의 트래픽에 먼저 열고 지표를 확인하며 점진적으로 확대합니다.

···
html
<div class="demo"><div class="head"><b>CANARY ROLLOUT</b><span id="phase">observe</span></div><div class="scene"><div class="label">TRAFFIC <strong>100%</strong></div><div class="bar"><div id="new" class="new"></div></div><div class="legend"><span>OLD <b id="oldPct">95%</b></span><span>NEW <b id="newPct">5%</b></span></div><div class="steps"><i id="s0"></i><i id="s1"></i><i id="s2"></i><i id="s3"></i></div></div><div class="foot"><span>measure → promote or roll back</span><span>tap to advance</span></div></div>
css
.demo{width:min(94vw,690px);height:min(86vh,310px);padding:clamp(10px,2.4vmin,20px);border:1px solid var(--line);border-radius:14px;background:var(--surface);display:flex;flex-direction:column;gap:clamp(7px,2vmin,14px);font:600 clamp(9px,2.5vmin,15px)/1.3 ui-monospace,monospace}.head,.foot{display:flex;justify-content:space-between;gap:8px}.head b{color:var(--accent)}.head span,.foot{color:var(--muted)}.foot{font-size:.82em}.scene{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;gap:clamp(8px,2vmin,17px)}.label,.legend{display:flex;justify-content:space-between}.label strong{color:var(--accent)}.bar{height:clamp(20px,7vmin,45px);border:1px solid var(--line);border-radius:8px;background:var(--accent-2);overflow:hidden}.new{height:100%;width:5%;background:var(--accent);margin-left:auto;transition:width .5s}.legend span:last-child{color:var(--accent)}.steps{display:flex;gap:5px}.steps i{height:clamp(3px,1vmin,6px);flex:1;background:var(--line);border-radius:9px}.steps i.on{background:var(--accent)}
js
const shares=[5,25,50,100];let step=0;function advance(){const share=shares[step];document.getElementById('new').style.width=share+'%';document.getElementById('oldPct').textContent=(100-share)+'%';document.getElementById('newPct').textContent=share+'%';document.getElementById('phase').textContent=share===100?'released':'observe · '+share+'%';for(let i=0;i<4;i++)document.getElementById('s'+i).classList.toggle('on',i<=step);step=(step+1)%4}advance();const timer=setInterval(advance,1050);document.querySelector('.demo').addEventListener('pointerdown',()=>{clearInterval(timer);advance()})

카나리 배포는 기존 버전을 계속 운영하면서 새 버전으로 가는 트래픽을 조금씩 늘립니다. 각 단계에서 오류율과 지연 같은 지표를 확인하고 문제가 생기면 새 버전으로 가는 비율을 다시 낮춥니다.

데모의 막대는 기존 버전과 새 버전의 트래픽 비중이 5%, 25%, 50%, 100%로 바뀌는 과정을 보여줍니다. 실제 배포의 승격 조건은 사용자 경험에 영향을 주는 지표와 충분한 관측 시간으로 정해야 합니다.

언제 쓰나

새 릴리스의 위험을 실제 트래픽으로 작게 검증하고 빠르게 되돌릴 수 있어야 할 때 사용합니다.

페이지로 열기 ↗