불변 인프라
고친 사람 github-actions[bot]
불변 인프라는 서버를 고치지 않고 새로 만들어 바꾸는 운영 방식입니다. 설정 하나를 바꿀 때도 새 서버를 띄워 옛 서버와 갈아 끼웁니다. 그래서 돌고 있는 서버는 만들어진 때의 모습을 끝까지 지킵니다. 서버마다 설정이 조금씩 달라지는 일을 막으려고 씁니다.
쉽고 빠른 이해
불변 인프라는 돌고 있는 서버에 손대지 않습니다. 타임아웃을 30초에서 60초로 늘려야 하면 60초가 들어간 서버를 새로 띄웁니다. 그다음 30초짜리 서버를 지웁니다.
이렇게 하는 까닭은 서버를 고쳐 쓰다 보면 서버마다 조금씩 달라지기 때문입니다. 누가 무엇을 고쳤는지 모르게 된 서버는 망가졌을 때 똑같이 다시 세우기 어렵습니다.
어떻게 도나:
- 프로그램과 설정을 모두 담은 서버의 원본을 미리 만들어 둡니다
- 그 원본으로 새 서버를 띄웁니다
- 요청을 새 서버로 옮깁니다
- 옛 서버는 고치지 않고 지웁니다
대가는 작은 변경에도 원본을 다시 만들고 서버를 갈아야 한다는 것입니다. 서버 안에 둔 데이터는 서버와 함께 사라지므로 데이터는 서버 밖에 따로 둡니다. 데이터를 쥔 서버나 한두 대뿐인 서버에는 잘 맞지 않습니다.
상세
이 절은 서버를 고쳐 쓰는 쪽과 견주는 데서 시작합니다. 서버를 찍어 내는 이미지를 본 뒤 타임아웃 값 하나를 바꾸는 일을 두 쪽에서 따라갑니다.
끝으로 서버 밖에 두는 데이터와 불변 인프라가 치르는 대가를 봅니다.
고쳐 쓰는 서버
서버는 한번 띄우면 오래 씁니다. 새 버전 프로그램을 올리거나 설정을 바꿀 일이 생기면 이미 돌고 있는 서버의 안을 고칩니다. 가변 인프라는 이렇게 돌고 있는 서버를 제자리에서 고쳐 쓰는 운영 방식입니다. 불변 인프라와 맞세우려고 붙인 이름입니다.
서버 안을 고치는 길은 둘입니다. 사람이 SSH(Secure Shell, 암호화된 연결로 원격 서버에 접속하는 도구)로 들어가 명령을 치기도 합니다. 설정 관리 도구가 설정 파일을 읽어 서버를 고치기도 합니다. 어느 길이든 서버는 남고 안의 내용만 바뀝니다.
고쳐 쓰는 쪽에서는 고친 흔적이 서버 안에만 남기 쉽습니다. 장애 난 밤에 서버 한 대만 손으로 고치면 같아야 할 서버끼리 설정이 달라집니다. 서버의 실제 모습이 적어 둔 설정에서 이렇게 벌어지는 일을 구성 드리프트라 합니다.
드리프트가 몇 달 쌓이면 서버 한 대 한 대가 다 달라집니다. 이런 서버를 눈송이 서버라 부릅니다. 안에 무엇이 들었는지 아무도 모르니 망가지면 똑같이 다시 세울 수 없습니다.
고치지 않고 갈아 끼우는 서버
불변 인프라는 돌고 있는 서버를 고치는 길을 아예 닫습니다. 서버는 띄운 뒤로 한 번도 바뀌지 않습니다. 바꿀 일이 생기면 바뀐 내용을 담은 서버를 새로 띄웁니다. 그다음 옛 서버를 지웁니다.
「불변」이라는 이름은 프로그래밍에서 왔습니다. 한번 만든 값을 고치지 않고, 바꿀 때는 새 값을 만드는 성질을 불변성이라 합니다. 불변 인프라는 이 성질을 서버에 들인 것입니다.
불변이라고 해서 서버 안의 모든 것이 멈춰 있지는 않습니다. 서버는 계속 요청을 받고 메모리에 값을 씁니다. 바뀌지 않는 것은 설치된 프로그램과 설정입니다.
서버를 찍어 내는 이미지
새 서버를 띄울 때마다 손으로 꾸리면 그 서버도 사람 손을 탑니다. 그래서 불변 인프라는 서버에 들어갈 것을 미리 한 덩어리로 묶어 둡니다. 이 덩어리를 이미지라 합니다.
이미지에는 애플리케이션 코드, 라이브러리, 설정 파일이 함께 들어 있습니다. 같은 이미지로 띄운 서버는 몇 대든 안이 같습니다. 서버의 모습을 이미지 하나가 정하는 셈입니다.
이미지는 무엇을 띄우느냐에 따라 두 가지로 나뉩니다. 가상 머신은 물리 컴퓨터 한 대를 나눠 여러 대처럼 쓰게 해 주는 소프트웨어 컴퓨터입니다. 운영체제까지 따로 갖습니다.
컨테이너는 운영체제 하나를 여러 프로그램이 나눠 쓰는 방식입니다. 프로그램마다 떨어진 실행 공간을 받습니다. 운영체제를 따로 띄우지 않아 가상 머신보다 가볍습니다.
어느 쪽이든 규칙은 같습니다. 띄운 뒤에는 안을 고치지 않습니다.
이미지도 사람이 손으로 만들지 않습니다. 서버에 어떤 프로그램이 깔려 있고 설정 값이 무엇이어야 하는지 파일에 적어 둡니다. 빌드 도구가 그 파일을 읽어 이미지를 만듭니다. 코드형 인프라는 이렇게 서버를 파일로 적어 다루는 일을 말합니다.
그 파일은 버전관리 도구에 넣어 둡니다. 그러면 이미지마다 무엇이 들어갔고 누가 바꿨는지가 기록으로 남습니다.
타임아웃 하나를 바꾸는 두 방식
요청 타임아웃을 30초에서 60초로 늘리는 일을 두 쪽에서 따라가 봅니다. 서버는 여러 대입니다. 그 앞에 로드 밸런서가 있습니다. 로드 밸런서는 들어오는 요청을 여러 서버에 나눠 보내는 장비입니다.
고쳐 쓰는 쪽에서는 서버마다 들어가 설정 파일의 30을 60으로 고칩니다. 그다음 프로그램을 다시 시작합니다. 몇 분이면 끝납니다. 한 대를 빠뜨리면 그 서버만 30초로 남습니다.
갈아 끼우는 쪽에서는 서버에 들어가지 않습니다. 이미지를 만드는 파일에서 30을 60으로 고칩니다. 빌드 도구가 그 파일로 새 이미지를 만듭니다. 새 이미지로 서버를 띄운 뒤 로드 밸런서가 요청을 새 서버로 돌립니다.
sequenceDiagram
participant 빌드 as 빌드 도구
participant 새 as 새 서버
participant 부하 as 로드 밸런서
participant 옛 as 옛 서버
Note over 부하,옛: 요청은 30초짜리 옛 서버로 간다
빌드->>빌드: 60초가 든 새 이미지를 만든다
Note over 새: 새 이미지로 띄운다
부하->>새: 요청을 보내기 시작한다
부하->>옛: 요청을 끊는다
Note over 옛: 고치지 않고 지운다
그림에서 옛 서버는 끝까지 30초입니다. 60초는 새 서버에만 있습니다. 요청이 새 서버로 옮겨 가야 바뀐 값이 운영에 들어갑니다.
아래 표는 두 쪽을 같은 변경 하나로 견준 것입니다.
| 고쳐 쓰는 서버 | 갈아 끼우는 서버 | |
|---|---|---|
| 고치는 곳 | 돌고 있는 서버 안 | 이미지를 만드는 파일 |
| 걸리는 시간 | 명령 몇 줄 | 이미지 빌드와 서버 띄우기 |
| 남는 기록 | 누가 적어야 남는다 | 파일 변경 이력에 남는다 |
| 되돌리기 | 60을 다시 30으로 고친다 | 옛 이미지로 서버를 다시 띄운다 |
| 서버끼리 | 빠뜨린 서버만 다르다 | 같은 이미지면 같다 |
갈아 끼우는 쪽은 느립니다. 대신 파일만 읽으면 지금 도는 서버에 무엇이 들었는지 압니다.
드리프트가 생기지 않는 까닭
돌고 있는 서버를 바꾸는 길이 없으면 실제 모습이 적어 둔 모습에서 벌어질 틈도 없습니다. 서버의 모습은 이미지가 정합니다. 이미지는 파일이 정합니다.
선언적 설정은 어떤 명령을 어떤 순서로 칠지가 아니라 서버가 마지막에 어떤 모습이어야 하는지를 적는 방식입니다. 「타임아웃을 30에서 60으로 고쳐라」 대신 「타임아웃은 60초다」라고 적습니다. 불변 인프라에서는 파일에 적힌 이 모습이 곧 도는 서버의 모습입니다.
서버를 늘릴 때도 같습니다. 요청이 늘면 서버를 자동으로 더 띄우는 오토스케일링은 같은 이미지로 새 서버를 찍어 냅니다. 새 서버에서만 설정이 달라 장애가 나는 일이 없습니다.
롤백도 같은 흐름을 탑니다. 롤백은 배포한 변경을 앞 상태로 되돌리는 일입니다. 옛 이미지를 지우지 않고 두면, 그 이미지로 서버를 다시 띄우고 요청을 옮기면 됩니다.
요청을 옛 서버에서 새 서버로 옮기는 방법은 여럿입니다. 블루-그린 배포는 서버를 두 벌 나란히 두고 요청을 한꺼번에 넘깁니다. 롤링 업데이트는 서버를 몇 대씩 차례로 바꿉니다.
서버 밖에 두는 데이터
서버를 수시로 지우므로 서버 안에 쌓인 것은 서버와 함께 사라집니다. 그래서 오래 남아야 하는 데이터는 서버 밖에 둡니다.
| 서버 안에 두면 사라지는 것 | 두는 곳 |
|---|---|
| 주문·회원 같은 업무 데이터 | 따로 운영하는 데이터베이스 |
| 사용자가 올린 파일 | 오브젝트 스토리지 같은 외부 저장소 |
| 로그 | 로그를 모아 두는 별도 시스템 |
요청을 처리하는 데 필요한 데이터를 서버 안에 쌓아 두지 않는 성질을 무상태라 합니다. 불변 인프라로 굴리는 서버는 대개 무상태 서버입니다. 그래야 아무 때나 지워도 잃는 것이 없습니다.
환경마다 달라지는 값도 이미지 밖에 둡니다. 데이터베이스 주소나 비밀번호가 그렇습니다. 이미지에 박으면 개발용과 운영용 이미지를 따로 만들어야 합니다.
이런 값은 서버가 뜰 때 넣어 줍니다. 프로그램이 실행될 때 운영체제에서 받아 읽는 환경 변수로 넣기도 합니다. 비밀번호와 키는 시크릿 관리 도구에서 받아 오기도 합니다. 이미지 하나로 개발과 운영을 모두 띄울 수 있게 됩니다.
대가와 맞지 않는 경우
첫째 대가는 시간입니다. 설정 값 하나를 바꿔도 이미지를 새로 만들고 서버를 갈아야 합니다. 장애 중에 급히 고칠 때도 이 길을 거칩니다.
둘째 대가는 자동화입니다. 이미지 빌드, 서버 띄우기, 요청 옮기기가 자동으로 돌지 않으면 변경 한 번이 사람 손으로 하루가 걸립니다. 이 자동화를 먼저 갖춰야 불변 인프라가 굴러갑니다.
셋째 대가는 저장 공간과 관리입니다. 변경마다 이미지가 하나씩 생깁니다. 롤백에 쓸 이미지는 남기고 나머지는 지우는 규칙이 따로 있어야 합니다.
데이터를 쥐고 있는 서버에는 들이기 어렵습니다. 데이터베이스 서버를 지우고 새로 띄우면 데이터를 옮기는 일이 따라옵니다. 이런 서버는 데이터를 담은 디스크를 떼어 새 서버에 다시 붙이기도 합니다. 그 서버만 고쳐 쓰기도 합니다.
서버가 한두 대이고 바뀔 일이 드물면 계산이 달라집니다. 자동화를 갖추는 품이 드리프트를 막아 얻는 것보다 클 수 있습니다.
관련 항목
불변 인프라가 막으려는 장애
구성 드리프트 · 눈송이 서버 · 설정 오류 · 부분 배포
불변 인프라와 맞세워지는 운영 방식
가변 인프라 · 설정 관리 · 제자리 업데이트 · 패치 관리 · SSH
불변 인프라가 기대는 원칙
불변성 · 선언적 설정 · 코드형 인프라 · 단일 진실 원천 · 멱등성 · 무상태 · 버전관리
불변 인프라가 서버를 찍어 내는 이미지
이미지 · 머신 이미지 · 컨테이너 이미지 · 골든 이미지 · 아티팩트 저장소 · 컨테이너 레지스트리 · 재현 가능한 빌드
불변 서버로 띄우는 실행 단위
새 서버로 요청을 옮기는 배포 방식
블루-그린 배포 · 롤링 업데이트 · 카나리 배포 · 롤백 · 로드 밸런서 · 헬스 체크 · 오토스케일링
불변 서버가 밖에 맡기는 데이터와 설정
데이터베이스 · 오브젝트 스토리지 · 로그 수집 · 환경 변수 · 시크릿 관리
불변 인프라를 구현하는 도구
Docker · Kubernetes · 테라폼 · Packer
불변 인프라가 속하는 상위 분야
다른 이름: immutable infrastructure · 불변 인프라스트럭처 · 불변 서버 · immutable server