백엔드 엔지니어링수정 2026-08-30

되돌아오는 질문들 — 고를 때 · 터졌을 때 · 설명해야 할 때

사내 인증 서비스 여섯 편의 마지막이다. 앞의 다섯 편을 세 벌로 다시 엮는다. 고를 때 저울질하는 선택지 다섯, 증상만 보고는 원인을 잘못 짚기 쉬운 실패 모드 여덟, 설명해야 할 때 필요한 문답 스물다섯과 길게 답해야 하는 넷이다.

앞 편으로 요구 문장에서 파드 개수까지 내려오는 경로가 끝났다. 그런데 되돌아오는 질문은 그 경로를 순서대로 따라오지 않는다. 「왜 그렇게 골랐나」는 방식을 정한 자리와 구현한 자리에 함께 걸린다.

첫 편이 예고한 대로 이 편은 앞의 다섯 편을 세 벌로 다시 엮는다. 고를 때의 선택지, 터졌을 때 증상에서 원인으로 거슬러 가는 실패 모드, 설명해야 할 때의 문답이다. 앞 편들이 사슬을 따라 내려왔다면 이 편은 그것을 가로로 자른다.

고를 때 — 다섯 개의 갈림길

이 프로젝트가 저울질한 선택지는 다섯이다. 어느 쪽도 틀리지 않고, 무엇을 포기할 수 있는지가 다르다.

선택지얻는 것치르는 값이 선택이 맞는 상황
로그인 상태를 서버에 둔다필요한 순간 바로 끊을 수 있다저장소 하나를 함께 봐야 해 늘리기 까다롭다서비스가 하나뿐이고 회수가 타협 불가일 때
서명된 문자열만으로 검증한다늘리기 자유롭고 검증에 조회가 없다발급된 것을 만료 전에 되돌릴 수 없다여러 서비스가 같은 신원을 인정하고 호출량이 클 때
짧은 것과 긴 것을 나눠 회전시킨다확장성을 지키며 회수 지연에 상한을 둔다발급·폐기 절차가 늘고 저장소가 다시 필요하다회수와 확장을 둘 다 요구받을 때
권한을 서명 안에 실어 보낸다인가 판단에 조회가 일어나지 않는다조직이 바뀌어도 만료까지는 옛 권한이다수명을 분 단위로 짧게 잡을 수 있을 때
권한을 요청마다 다시 읽는다고친 즉시 다음 요청부터 반영된다요청마다 조인 비용이 고정으로 붙는다겸직·이동이 잦고 반영이 늦으면 사고일 때

다섯 행은 두 종류의 질문이다. 앞의 세 행 — 서버 저장, 서명 검증, 둘로 나눈 회전 — 은 로그인 상태를 어디에 둘 것인가를 묻고, 뒤의 두 행 — 서명 안에 싣기, 요청마다 읽기 — 은 권한을 언제 읽을 것인가를 묻는다. 앞은 편4가, 뒤의 마지막 행은 편3의 매핑 테이블이 다뤘다. 넷째 행만 앞의 다섯 편이 고르지 않은 길이라 여기서 처음 저울에 얹힌다.

둘이 독립이 아니라는 점이 함정이다. 셋째 행을 골라 수명을 짧게 잡아 두면 넷째 행의 단점이 저절로 작아지고, 수명을 길게 잡은 채 권한까지 실어 보내면 조직 개편 다음 날에도 어제의 권한으로 통과하는 요청이 남는다. 한 칸의 선택이 다른 칸의 값을 바꾼다.

이 저울은 인증에만 있는 것이 아니다. 무엇을 얻으면 무엇을 내놓아야 하는 구조는 코드를 대신 실행해 주는 환경의 격리 수준에서도 똑같이 나타난다.

터졌을 때 — 여덟 가지 실패 모드

아래 여덟은 증상만 보고 원인을 짚으면 대체로 틀리는 것들이다. 드러나는 현상과 실제 원인의 거리가 멀다.

실패겉으로 보이는 것실제 원인손대야 할 곳
인증 서비스 전면 중단사내 모든 시스템에서 로그인이 막힌다전 시스템이 한 지점에 매달려 있다복제본을 여러 노드에 흩고 되돌리는 절차를 짧게
생존 프로브가 부르는 재시작파드가 뜨자마자 죽기를 반복한다기동 시간을 점검이 기다려 주지 않는다기동 전용 프로브를 두고 첫 검사 시각과 판정 기준을 함께 늘린다
준비 프로브를 걸지 않음배포 직후 몇 분간 오류 응답이 튄다준비 안 된 파드에 요청이 들어간다준비 프로브를 필수로, 교체 중 결원 허용치를 0으로
교체 도중의 스키마 충돌옛 판 파드에서만 오류가 난다되돌릴 수 없는 변경을 한 번에 넣었다열 추가 · 양쪽 쓰기 · 이관 · 제거로 쪼갠다
권한 조회가 부르는 연쇄 질의목록 화면 하나가 유독 느려진다연관을 따라가며 행마다 질의가 나간다필요한 것만 조인하거나 결과 모양으로 바로 받는다
매니페스트에 남은 자격증명저장소를 볼 수 있으면 다 본다인코딩된 문자열을 암호화로 착각했다바깥 비밀 저장소로 옮기고 접근을 좁힌다
서명 열쇠 유출발급하지 않은 문자열이 통과한다열쇠가 이미지나 저장소에 들어 있다실행 시점에 주입하고 교체 절차를 만든다
떠난 사람의 접근이 남음회수했는데도 한동안 들어와진다수명이 회수 요구보다 길다수명을 줄이고 저장된 갱신 수단을 폐기한다

여덟 행은 넷으로 묶인다. 가용성 쪽이 넷 — 전면 중단, 생존 프로브 재시작, 준비 프로브 누락, 교체 중 스키마 충돌. 성능 쪽이 하나로 권한 조회의 연쇄 질의. 비밀 관리 쪽이 둘 — 매니페스트에 남은 자격증명, 서명 열쇠 유출. 회수 쪽이 하나로 떠난 사람의 접근이다. 고치는 자리는 이 묶음과 나란하지 않다. 배포 설정만으로 끝나는 것은 둘째와 셋째뿐이고, 나머지 여섯은 코드 · 이관 절차 · 비밀 저장소로 흩어진다.

두 번째 행에는 모양이 둘이다. 기동이 늦어 첫 검사에 걸리는 쪽은 표대로 첫 검사 시각을 늘리면 끝나지만, 부하로 느려져 걸리는 쪽은 교체되기 때문에 죽는 것이라 원인과 결과가 뒤집혀 보인다.

도식을 탭하면 확대해서 볼 수 있습니다

오판의 대가가 용량 축소이고, 줄어든 용량이 다시 느려짐을 키운다. 고리를 끊는 지점은 판정 기준이지 재시작 횟수가 아니다.

설명해야 할 때 — 스물다섯 개의 문답

질문을 성격에 따라 네 묶음으로 나눴다. 대조로 답하는 것은 표에, 판단의 근거를 말해야 하는 것은 문장에 담았다. 묶음은 앞 편들의 순서를 따르고, 번호는 원래 목록의 것을 그대로 둔다.

인증 도메인과 표준 — 1 · 3 · 2 · 8 · 9 · 22

1. 인증과 인가는 무엇이 다른가. 앞은 상대가 주장하는 신원이 사실인지를 가리고, 뒤는 확인된 그 사람이 이 자원에 손댈 수 있는지를 정한다. 순서가 고정이라 인가는 인증 다음에만 판단되고, 실패했을 때의 응답도 「아직 누구인지 모른다」와 「누군지는 알지만 안 된다」로 갈린다. 편2가 이 구분 위에 통째로 서 있다.

3. 신원 증명 문자열에 개인정보를 넣어도 되나. 안 된다. 담긴 내용은 열쇠 없이도 되읽히고, 붙어 있는 서명은 바꿔치기를 막을 뿐 내용을 가리지 못한다. 사고로 이어지는 이유는 서명이라는 낱말이 주는 안전한 느낌에 있다. 밀봉했다고 여기지만 실제로 한 일은 투명한 봉투에 도장을 찍은 것이다.

2. 신원 증명 문자열의 세 조각.

조각담는 것이것만으로 알 수 있는 것
머리형식과 서명 알고리즘어떤 방식으로 검증해야 하는가
본문발급자 · 만료 시각 · 서비스가 넣은 값누구이고 언제까지 유효한가
서명앞 두 조각을 서명 열쇠로 계산한 값중간에 고쳐졌는가

세 조각을 점으로 이어 붙인 이 형식은 암호화가 아니라 옮기기 쉬운 인코딩이다.

8 · 9 · 22. 표준과 방식은 각자 다른 문제를 푼다.

이름푸는 문제신원 확인은 누가 하나
위임 인가 표준비밀번호를 넘기지 않고 자원 접근 권한만 맡긴다위에 얹는 신원 계층이 따로 맡는다
문서 기반 사내 연동 표준인증 결과와 속성을 문서로 만들어 서비스 쪽에 넘긴다보증하는 쪽이 문서에 담아 보낸다
시스템 사이의 인증사람이 없는 자리에서 호출하는 쪽을 식별한다사람 대신 시스템 자격증명으로 판별한다

첫 행이 헷갈리는 이유는 편2가 짚은 대로 이름에 인가가 들어 있는데도 로그인 버튼에 쓰이기 때문이다. 셋째 행은 사람이 아니라 시스템이 주체라 화면도 비밀번호도 없고, 권한 모델을 사람 쪽과 따로 설계해야 한다.

요구사항에서 스키마로 — 13 · 24 · 12 · 14 · 25

13 · 24. 두 절차는 같은 모양이다.

순서명세에서 저장 구조로유스케이스 그리기
1기능 요구 문장을 모은다시스템이 어디까지인지 선을 긋는다
2문장마다 메서드와 경로를 붙인다선 바깥에서 관여하는 주체를 찾는다
3되풀이되는 명사를 후보로 꺼낸다주체가 시스템에 시키는 일을 꺼낸다
4관계와 수량 제약을 정한다포함 · 확장 관계를 정리한다
5명세에 근거가 없는 것을 지운다요구와 하나씩 대조해 검토한다

두 절차의 공통점은 마지막 줄이다. 근거 없는 것을 남기지 않는 단계가 있어야 산출물이 다음 단계의 입력이 된다.

12. 회원과 권한을 왜 표 하나로 갈랐나. 편3이 열 하나를 표 하나로 가른 그 자리다. 답에서 빠뜨리면 안 되는 것은 근거가 요구 목록의 한 줄이라는 사실이다 — 요구가 바뀌면 되돌릴 자리를 알 수 있다.

14. 기능 요구와 품질 요구. 앞은 무엇을 하는가이고 뒤는 어떤 수준으로 하는가다. 구현을 정하는 것은 앞이지만 배포 형태를 정하는 것은 뒤다. 클러스터가 들어온 이유도 기능이 아니라 「멈추면 안 된다」는 품질 요구였다.

25. 요구가 바뀌어도 설계가 버티게 하려면. 지키는 것이 아니라 바뀌어도 되는 자리를 미리 정해 두는 것이다. 규칙을 조건문으로 박으면 개편될 때마다 배포가 따라야 하지만, 정책 데이터의 행으로 두면 운영 화면에서 끝난다. 환경마다 달라지는 값은 이미지 밖에 두고, 바깥에 약속한 응답 모양은 필드를 더하는 것까지만 허용한다.

구현의 선택 — 4 · 5 · 6 · 23 · 7 · 10 · 11

4. 로그인 상태를 서버에 둘 것인가 문자열에 실을 것인가. 앞 절 표의 첫 두 행이 이 질문의 양극이고, 둘 다 요구받으면 셋째 행으로 간다. 이 프로젝트가 그 경우였다.

5. 갱신 수단을 왜 쓸 때마다 바꾸나. 한 번 발급한 것을 오래 쓰게 두면 새어 나갔을 때 알아챌 방법이 없다. 쓸 때마다 갈고 옛것을 버리면, 버린 것이 다시 들어오는 순간이 유출의 신호가 된다. 회전의 값어치는 교체가 아니라 탐지 신호가 생기는 데 있다.

6. 문자열 방식에서 로그아웃은 어떻게 만드나. 서버가 들고 있는 갱신 수단을 지우는 것이 본체다. 신원 증명 쪽은 서버에 없어 회수할 대상이 없고, 차단 목록을 두는 순간 무상태의 이점이 깎인다. 근본 대응은 수명을 짧게 잡는 것이고, 로그아웃 뒤 남는 창이 곧 그 수명이다.

23. 권한을 고치면 언제부터 먹히나. 요청마다 정책 데이터를 다시 읽거나, 수명을 지연을 감당할 만큼 줄이는 두 길이다. 캐시를 두겠다면 만료를 기다리지 말고 변경이 일어난 순간 그 항목을 버려야 한다. 시간으로 낡는 캐시는 지연을 옮길 뿐이다.

#질문답의 뼈대
7비밀번호 해시에 왜 느린 함수를 쓰나계산 비용을 조절할 수 있고 무작위 값을 안에 품는다. 빠른 해시는 대입 공격에 그만큼 유리하다
10인증 검사가 왜 요청 분배 앞인가통과 못 한 요청을 앞에서 끊어야 인가 판단이 컨트롤러마다 흩어지지 않는다
11저장 객체를 응답에 그대로 쓰면저장 구조가 바깥 약속과 묶이고, 감출 필드가 새고, 참조가 돌고, 조회가 늘어난다

뒤의 둘은 경계를 지키는 비용을 미리 치르는 쪽이 싸다는 이야기이고, 첫째는 비용을 일부러 크게 잡아야 안전해지는 드문 자리다.

배포와 운영 — 15 · 16 · 17 · 18 · 19 · 20 · 21

#질문답의 뼈대
15배포 오브젝트와 복제본 관리자의 관계앞이 뒤를 판마다 새로 찍어 내고, 트래픽을 옮긴 뒤 이전 판을 남겨 되돌릴 길을 낸다
16앞에 주소를 하나 세우는 이유파드 주소는 다시 뜰 때마다 바뀐다. 고정된 이름과 분배가 필요하다
17설정값과 비밀값을 왜 나누나민감한지 여부가 다르다. 뒤쪽은 인코딩만 되어 있어 접근 통제와 바깥 저장소가 따로 필요하다

세 행을 요구사항 쪽 말로 옮기면 각각 「판을 갈아 끼울 수 있게」, 「부르는 쪽이 파드의 생사를 몰라도 되게」, 「환경마다 다른 값을 이미지 밖에 두되 민감한 것은 따로 잠가 두게」다.

18. 생존 프로브와 준비 프로브. 실패했을 때 하는 일이 정반대다. 생존 프로브가 실패하면 컨테이너를 교체하고, 준비 프로브가 실패하면 교체 없이 요청만 잠시 끊는다. 그래서 생존 프로브에는 스스로 회복할 수 없는 상태만 넣는다. 뭉뚱그리면 앞 절의 고리가 만들어진다.

19. 교체 도중의 스키마 변경. 롤링 교체는 옛 판과 새 판이 잠시 함께 도는 것을 전제한다. 한쪽만 아는 변경을 한 번에 넣으면 다른 쪽이 깨진다. 더하고, 양쪽에 쓰고, 옮기고, 지우는 순서로 쪼개면 각 단계가 양쪽에서 성립한다.

20. 복제본 자동 조절의 전제. 셋이 먼저다. 상태를 들고 있지 않을 것, 컨테이너마다 필요한 자원량이 선언돼 있을 것, 판단 근거가 될 지표가 모이고 있을 것. 첫째가 빠지면 늘려도 요청이 엉키고, 둘째가 빠지면 사용률을 잴 분모가 없으며, 셋째가 빠지면 잴 것 자체가 안 모인다.

21. 한 지점에 전부 매달린 구조를 어떻게 다루나. 다음 절에서 층을 나눠 답한다. 편5의 배포 설정만으로는 절반까지밖에 못 간다는 것이 요지다.

답이 길어지는 네 문항

앞의 스물다섯이 한 문단으로 끝나는 것이라면, 아래 넷은 어느 쪽을 포기했는지까지 말해야 답이 되는 것들이다.

즉시 회수와 무상태 확장이 부딪힐 때. 성격이 다르다는 것부터 짚는다. 앞은 보안 요구, 뒤는 가용성 요구다. 어느 쪽도 버리지 않고 어긋나는 폭에 상한을 두는 쪽으로 간다. 수명을 분 단위로 잡고 갱신 수단만 서버에 두면, 회수할 때 저장된 것을 지우는 것으로 열려 있는 창이 그 수명만큼으로 닫힌다. 검증은 서명 확인으로 끝나 인스턴스는 여전히 늘어난다. 그 창마저 못 견디는 자원에만 요청마다 조회를 붙인다.

요구사항 문서가 코드 품질에 어떻게 닿나. 설계가 뒤집힌 일로 답한다. 처음에는 사람 쪽 표에 역할을 가리키는 열을 두는 구조였는데, 요구 목록의 겸직 한 줄 때문에 관계가 다대다가 되었다. 목록 없이 곧장 구현했다면 이 사실은 겸직 인사가 실제로 생긴 운영 중에 드러났을 것이고, 그때의 스키마 변경에는 데이터 이관이 따라붙는다. 문서의 값어치는 산출물이 아니라 근거가 남아 고칠 자리를 알 수 있게 되는 것이다.

사내 전 시스템이 이 서비스 하나에 매달려 있다. 층을 셋으로 나눈다. 인프라 층에서는 복제본을 여러 노드에 흩고, 준비되지 않은 파드를 분배에서 빼고, 교체 중 결원 허용치를 0으로 둔다. 애플리케이션 층에서는 서명만 확인하면 검증이 끝나도록 해 저장소에 기대지 않게 한다. 저장소가 흔들려도 이미 로그인한 쪽의 호출은 성공하고, 못 하게 되는 것은 새 로그인과 재발급뿐이다. 호출하는 쪽 층에서는 각 시스템이 검증용 공개 열쇠를 미리 받아 둔다. 서명하는 열쇠와 검증하는 열쇠가 갈려 있어야 나눠 줄 수 있다. 마지막은 배포 절차다. 이전 판을 남겨 두면 원인을 알기 전에 되돌리는 선택이 가능해진다.

생존 프로브를 잘못 잡으면 최악이 어디까지 가나. 앞 절 도식의 고리가 그대로 답이다. 지연을 사망으로 잘못 읽은 결과가 용량 감소로 돌아오는 자기증폭이다. 그래서 생존 프로브는 프로세스가 답하는지만 보고 저장소나 바깥 의존성은 넣지 않는다. 느려짐은 준비 프로브가 받는다 — 그쪽 실패는 분배에서만 빼므로 회복하면 다시 들어온다.

정리

여섯 편을 관통한 것은 요구 한 줄이 저장 구조와 파드 개수까지 내려온다는 사슬이었다. 가로로 잘라 보면 그 사슬이 한 방향으로만 흐르지 않는다. 겸직에 관한 한 줄이 표 하나를 만들었고, 그 표가 「권한을 언제 읽을 것인가」라는 선택을 낳았고, 그 선택이 신원 증명의 수명이라는 값으로 배포까지 내려갔다. 반대로 「멈추면 안 된다」는 품질 요구는 배포 형태를 먼저 정한 뒤 거슬러 올라와 상태를 들고 있지 말라는 제약이 되었다.

그래서 되돌아오는 질문에 필요한 것은 항목별 정답이 아니라 그 결정이 어느 요구에서 왔고 무엇을 포기한 것인지다. 앞 절의 문답이 「무엇이 맞나」가 아니라 「무엇을 얻고 무엇을 잃나」로 답하는 이유다. 포기한 것을 말하지 못하는 결정은 근거가 없고, 근거가 없는 설계는 상황이 바뀌었을 때 고칠 자리를 찾지 못한다.