머신 이미지
고친 사람 github-actions[bot]
머신 이미지는 서버 한 대를 새로 띄울 때 쓰는 틀입니다. 운영체제와 프로그램과 설정이 미리 다 들어 있습니다. 이 틀 하나로 똑같은 서버를 몇 대든 찍어 냅니다. 새 서버는 켜지자마자 바로 일할 수 있습니다.
쉽고 빠른 이해
무슨 일을 하는 물건인가 — 서버를 찍어 내는 틀입니다. 웹 서버용 틀을 하나 만들어 두면 같은 웹 서버를 열 대든 백 대든 그 틀로 띄웁니다.
왜 이렇게 하나 — 틀이 없으면 서버마다 운영체제를 깔고 프로그램을 설치해야 합니다. 이 일은 느립니다. 사람이 손으로 하다 보면 서버마다 조금씩 달라지기도 합니다.
어떻게 도나
- 운영체제와 프로그램을 다 깔아 둔 디스크를 한 벌 복사해 틀로 저장합니다
- 서버가 필요하면 그 틀을 복사해 새 디스크를 만들고 부팅합니다
- 처음 켜질 때 서버 이름이나 주소처럼 서버마다 다른 값만 채웁니다
대가 — 틀이 큽니다. 설정 한 줄을 바꿔도 틀을 새로 만들어야 합니다. 틀을 오래 안 고치면 그 안의 프로그램이 낡습니다. 그래서 같은 서버를 여러 대 자주 띄울 때 제값을 하고, 한 대를 오래 켜 두는 서버에는 수고가 더 큽니다.
상세
이 절은 머신 이미지 안에 무엇이 들었는지부터 봅니다. 그다음 이미지 하나가 서버 한 대로 바뀌는 순서를 따라갑니다. 이어서 이미지를 만드는 두 방법을 견줍니다. 끝으로 이미지를 쓰면 무엇을 얻고 무엇을 치르는지, 컨테이너 이미지와는 어떻게 다른지 봅니다.
붕어빵 틀을 떠올리면 쉽습니다. 반죽과 팥을 부을 때마다 모양을 새로 빚지 않습니다. 틀에 부으면 늘 같은 모양이 나옵니다.
가상 머신은 실물 컴퓨터 한 대를 소프트웨어로 나눠 여러 대처럼 쓰게 만든 컴퓨터입니다. 가상 머신을 돌리는 소프트웨어를 하이퍼바이저라고 합니다. 이 문서에서 「서버」라고 부르는 것은 대개 이 가상 머신 한 대입니다.
머신 이미지는 가상 머신 한 대가 부팅하는 데 필요한 디스크 내용을 남김없이 복사해 둔 것입니다. 하이퍼바이저는 이미지를 복사해 새 가상 머신의 디스크로 붙입니다. 그리고 전원을 넣습니다. 그러면 이미지를 만들 때와 같은 상태의 서버가 하나 더 생깁니다.
클라우드에서는 사용자가 이미지를 고르기만 하면 클라우드가 하이퍼바이저 위에 서버를 만들어 줍니다. 클라우드마다 부르는 이름은 다릅니다. AWS(Amazon Web Services)는 이것을 AMI(Amazon Machine Image)라고 부릅니다.
이미지 안에 든 것
머신 이미지에는 크게 두 가지가 들어 있습니다. 하나는 디스크 내용입니다. 다른 하나는 그 디스크를 어떻게 띄울지 적은 정보입니다.
| 담긴 것 | 어느 쪽 | 무엇인가 |
|---|---|---|
| 부트로더 | 디스크 내용 | 전원이 들어오면 가장 먼저 도는 작은 프로그램입니다. 운영체제를 메모리에 올립니다 |
| 운영체제 | 디스크 내용 | 커널과 기본 명령어, 시스템 파일입니다 |
| 설치된 패키지 | 디스크 내용 | 웹 서버, 언어 런타임, 모니터링 에이전트처럼 미리 깔아 둔 프로그램입니다 |
| 설정 파일 | 디스크 내용 | 그 프로그램들이 읽을 설정입니다 |
| 애플리케이션 | 디스크 내용 | 팀이 만든 코드를 넣기도 하고 안 넣기도 합니다 |
| 띄울 때 쓰는 정보 | 띄우는 정보 | CPU(Central Processing Unit, 중앙 처리 장치) 종류, 부팅 방식, 디스크가 여럿이면 그 목록입니다 |
부팅 방식은 전원이 들어온 뒤 컴퓨터가 부트로더를 어떤 절차로 찾아 부르는지를 말합니다. 이 절차가 맞지 않으면 디스크 내용이 멀쩡해도 서버가 켜지지 않습니다.
디스크 내용은 운영체제까지 전부 들어 있어서 크기가 큽니다. 보통 기가바이트 단위입니다.
이미지 하나가 서버 한 대가 되기까지
이미지는 모든 서버에 똑같이 들어갑니다. 그런데 서버마다 달라야 하는 값이 있습니다. 서버 이름, IP 주소(Internet Protocol 주소), 접속에 쓰는 SSH(Secure Shell, 원격 접속 프로토콜) 키가 그렇습니다. 이런 값은 이미지에 넣지 않고 서버가 처음 켜질 때 채웁니다.
flowchart TD
A["이미지를 고른다"] --> B["이미지를 복사해 새 디스크를 만든다"]
B --> C["그 디스크로 부팅한다"]
C --> D["첫 부팅 때 서버마다 다른 값을 채운다"]
D --> E["서버가 일을 시작한다"]
첫 부팅 때 값을 채우는 일은 이미지 안에 미리 넣어 둔 초기화 프로그램이 합니다. 리눅스 클라우드 이미지에서는 cloud-init 이 이 일을 합니다. 이 프로그램은 서버를 만든 쪽이 넘겨준 값을 읽어 서버 이름을 정하고 키를 넣습니다. 이 단계 덕분에 이미지 하나로 서로 다른 서버를 여러 대 띄울 수 있습니다.
같은 틀을 여러 대에 쓰므로 틀에 넣으면 안 되는 것도 있습니다. 비밀번호나 인증 키를 이미지에 넣어 두면 그 이미지로 띄운 모든 서버가 같은 비밀을 나눠 갖습니다. 이미지가 새어 나가면 비밀도 같이 샙니다.
flowchart TD
I["머신 이미지 하나<br/>운영체제 · 프로그램 · 설정"]
I --> S1
I --> S2
I --> S3
subgraph S1["서버 1"]
C1["이미지에서 온 공통 부분"]
V1["첫 부팅 때 채운 값<br/>이름 · IP 주소 · SSH 키"]
end
subgraph S2["서버 2"]
C2["이미지에서 온 공통 부분"]
V2["첫 부팅 때 채운 값<br/>이름 · IP 주소 · SSH 키"]
end
subgraph S3["서버 3"]
C3["이미지에서 온 공통 부분"]
V3["첫 부팅 때 채운 값<br/>이름 · IP 주소 · SSH 키"]
end
그림에서 공통 부분에 비밀을 넣으면 세 서버가 모두 같은 비밀을 갖게 됩니다. 서버마다 달라야 하는 것은 아래 칸, 곧 첫 부팅 때 채우는 쪽에 둡니다.
이미지를 만드는 두 방법
이미지를 만드는 일을 흔히 「이미지를 굽는다」고 합니다. 방법은 둘입니다. 하나는 이미 켜져 있는 서버의 디스크를 복사하는 방법입니다. 다른 하나는 기본 이미지에서 출발해 정해진 순서대로 굽는 방법입니다.
기본 이미지는 운영체제만 깔린 채 배포되는 이미지입니다. 운영체제를 만드는 곳이나 클라우드가 내놓습니다. 아무 프로그램도 더하지 않았을 뿐 부팅은 됩니다.
첫째는 서버 한 대를 손으로 꾸린 뒤 그 디스크를 복사해 이미지로 삼는 방법입니다. 디스크를 한 시점의 모습 그대로 복사해 두는 일을 스냅샷이라고 합니다. 빠르고 쉽습니다. 대신 그 서버에 누가 무엇을 했는지가 이미지에 기록으로 남지 않습니다. 다음에 같은 이미지를 다시 만들려면 그 손길을 기억해 내야 합니다.
둘째는 무엇을 설치하고 무엇을 고칠지 파일에 적어 두는 방법입니다. 도구가 그 파일을 읽어 이미지를 만듭니다. 도구는 기본 이미지로 임시 서버를 띄웁니다. 파일에 적힌 대로 설치와 설정을 마칩니다. 그 임시 서버의 디스크를 복사해 새 이미지로 저장합니다. 임시 서버는 버립니다. Packer가 이런 도구입니다.
flowchart TD
A["기본 이미지"] --> B["임시 서버를 띄운다"]
F["설치와 설정을 적은 파일"] --> C
B --> C["파일대로 설치하고 설정한다"]
C --> D["임시 서버의 디스크를 복사해 새 이미지로 저장한다"]
D --> E["임시 서버는 버린다"]
둘째 방법은 파일이 곧 이미지의 설계도입니다. 그 파일을 버전 관리 도구에 넣으면 이미지마다 무엇이 들어갔고 누가 바꿨는지가 남습니다. 서버를 파일로 적어 다루는 이 방식을 코드형 인프라라고 합니다.
설치와 설정 단계에서는 설정 관리 도구를 불러 쓰기도 합니다. 설정 관리 도구는 서버에 무엇을 깔고 어떻게 설정할지 적은 내용을 읽어 서버를 그 상태로 맞춰 주는 도구입니다. 앤서블이 그런 도구입니다.
잘 다듬어 팀의 표준으로 삼은 이미지는 골든 이미지입니다. 새 서버는 모두 이 이미지에서 출발합니다.
이미지로 무엇을 얻나
첫째는 속도입니다. 운영체제 설치와 프로그램 설치를 이미지를 만들 때 한 번만 합니다. 서버를 띄울 때는 복사하고 부팅만 하면 됩니다. 요청이 몰려 서버를 급히 늘려야 할 때 이 차이가 큽니다. 부하에 맞춰 서버 수를 자동으로 늘리고 줄이는 오토스케일링이 머신 이미지에 기대는 까닭입니다.
둘째는 서버끼리 안이 같다는 것입니다. 같은 이미지로 띄운 서버는 몇 대든 안이 같습니다.
사람이 서버마다 손으로 고치다 보면 서버끼리 조금씩 달라집니다. 서버의 실제 상태가 의도한 상태에서 벗어나는 이 현상이 드리프트입니다. 드리프트가 쌓여 손을 너무 많이 탄 서버는 다시 만들 수 없게 됩니다. 이런 서버를 스노우플레이크 서버라고 부릅니다. 이미지에서 띄운 서버는 언제든 다시 만들 수 있습니다.
셋째는 되돌리기 쉽다는 것입니다. 새 이미지로 띄운 서버에 문제가 있으면 옛 이미지로 다시 띄우면 됩니다. 롤백이 이미지 하나를 고르는 일로 줄어듭니다.
이 셋을 끝까지 밀고 가면 불변 인프라가 됩니다. 한 번 띄운 서버는 고치지 않습니다. 바꿀 것이 생기면 새 이미지를 만듭니다. 그 이미지로 새 서버를 띄워 옛 서버와 갈아 끼웁니다. 이 방식으로 다루는 서버가 불변 서버입니다.
이미지가 치르는 값
이미지는 큽니다. 운영체제까지 전부 들었으니 저장하고 옮기는 데 공간과 시간이 듭니다.
작은 변경도 이미지를 새로 구워야 합니다. 설정 한 줄을 바꾸려 해도 임시 서버를 띄우고 설치를 다시 거쳐야 합니다. 굽는 데 수십 분이 걸리기도 합니다.
이미지는 낡습니다. 이미지를 만든 뒤에 나온 보안 패치는 이미지에 없습니다. 오래된 이미지로 띄운 서버는 처음부터 패치가 밀린 채 시작합니다. 그래서 이미지를 주기적으로 다시 굽는 팀이 많습니다.
이미지는 그것을 띄우는 쪽에 묶입니다. 한 클라우드에서 만든 이미지를 다른 클라우드나 다른 하이퍼바이저에서 그냥 띄울 수는 없는 경우가 많습니다. 디스크를 담는 파일 형식과 부팅 방식이 서로 다르기 때문입니다. 같은 설계도 파일로 클라우드마다 이미지를 따로 굽는 것도 이 때문입니다.
컨테이너 이미지와 무엇이 다른가
컨테이너는 이미 도는 운영체제 위에서 프로그램 하나를 따로 떼어 가둬 돌리는 단위입니다. 컨테이너가 올라타는 그 서버를 호스트라고 부릅니다. 컨테이너 이미지는 컨테이너를 찍어 내는 틀입니다. 이름이 비슷하지만 담는 것과 띄우는 것이 다릅니다.
| 머신 이미지 | 컨테이너 이미지 | |
|---|---|---|
| 담는 것 | 커널을 포함한 운영체제 전체와 프로그램 | 애플리케이션과 실행에 필요한 파일. 커널은 없습니다 |
| 띄우면 | 가상 머신 한 대 | 컨테이너 하나 |
| 커널 | 자기 커널로 부팅합니다 | 호스트의 커널을 나눠 씁니다 |
| 크기 | 보통 기가바이트 단위 | 보통 그보다 작습니다 |
| 뜨는 시간 | 운영체제 부팅을 거칩니다 | 부팅 없이 프로세스 하나를 띄웁니다 |
두 이미지는 함께 쓰이기도 합니다. 컨테이너를 돌릴 서버는 머신 이미지로 띄웁니다. 그 서버 위에서 애플리케이션은 컨테이너 이미지로 띄웁니다. 두 이미지가 각각 어느 층을 채우는지는 아래와 같습니다.
flowchart TD
subgraph CT["컨테이너 여럿 — 컨테이너 이미지가 채운다"]
A1["애플리케이션과 그 파일"]
A2["애플리케이션과 그 파일"]
end
subgraph VM["가상 머신 한 대 — 머신 이미지가 채운다"]
OS["운영체제와 커널"]
end
HV["하이퍼바이저"]
HW["실물 컴퓨터"]
CT --> VM
VM --> HV
HV --> HW
쓸 때와 안 쓸 때
머신 이미지가 제값을 하는 때는 같은 서버를 여러 대 자주 띄울 때입니다. 부하에 따라 서버 수가 오르내리는 서비스가 그렇습니다. 서버를 고쳐 쓰지 않고 갈아 끼우려 할 때도 이미지가 출발점이 됩니다.
오래 켜 두고 한 대만 쓰는 서버라면 이미지를 굽는 수고가 얻는 것보다 클 수 있습니다. 애플리케이션만 자주 바뀌고 운영체제는 거의 안 바뀐다면 컨테이너 이미지로 애플리케이션을 갈아 끼우는 편이 가볍습니다.
관련 항목
머신 이미지로 띄우는 대상
가상 머신 · 인스턴스 · 하이퍼바이저 · 클라우드 · 베어메탈
머신 이미지를 이루는 구성 요소
디스크 · 부트로더 · 운영체제 · 커널 · 패키지 · 루트 파일 시스템
머신 이미지를 만드는 도구와 방법
Packer · 스냅샷 · 설정 관리 · 앤서블 · 골든 이미지 · 베이스 이미지
머신 이미지를 출발점으로 삼는 운영 방식
불변 인프라 · 불변 서버 · 코드형 인프라 · 프로비저닝 · 테라폼 · 오토스케일링 · 롤백
머신 이미지로 풀려는 재현성 문제
구성 드리프트 · 스노우플레이크 서버 · 재현 가능한 빌드
머신 이미지와 헷갈리는 이웃
이미지 · 컨테이너 이미지 · 디스크 이미지 · ISO 이미지 · 컨테이너
클라우드마다 머신 이미지를 가리키는 다른 이름
AMI · 커스텀 이미지 · VM 템플릿
다른 이름: machine image · 가상 머신 이미지 · VM 이미지 · 서버 이미지