TL;DR
Mac에서만 Docker를 써온 나는 컨테이너가 리눅스인 게 Mac이라서 그런 줄 알았다. 윈도우에서 돌리면 윈도우 컨테이너가 될 거라고 생각했는데, Docker Desktop은 윈도우에서도 리눅스 VM을 돌리고 있었다. 윈도우 전용 컨테이너가 존재하고 메뉴에서 전환도 되는데, 전환하는 순간 받을 이미지가 없기에 잘 사용되지 않았다. 윈도우 컨테이너를 막고 있던 건 커널이 아니라 라이선스와 생태계였다.
윈도우에서 돌리면 윈도우 컨테이너가 되는 줄 알았다
GitHub에서 dockur/windows라는 프로젝트를 봤다. docker run 한 줄이면 윈도우가 뜨고 브라우저로 접속해서 쓸 수 있다는 건데 스타가 5만 개 넘게 달려 있었다.
보면서 이상했다. 나는 컨테이너가 호스트를 따라간다고 생각하고 있었다. 내가 Docker를 Mac에서만 써서 리눅스 컨테이너만 봤던 거고, 윈도우 PC에서 돌리면 당연히 윈도우 환경이 나올 거라고. 그렇다면 저런 도구가 왜 필요한지 설명이 안 됐다.
Mac에서는 애초에 리눅스 VM이 돌고 있었다
먼저 확인을 위해 다음 커멘드를 입력해봤다.
docker run --rm ubuntu uname -r
Ubuntu 컨테이너 안에서 커널 버전을 물어보면 Ubuntu 커널이 아니라 호스트 커널이 나온다. 컨테이너 이미지에는 커널이 없기 때문이다. ubuntu:22.04 를 풀어보면 glibc나 coreutils, apt 같은 파일들만 있다.

VM과 컨테이너의 층 구조
그래서 Ubuntu, CentOS, Alpine을 아무리 갈아끼워도 커널은 하나다. 셋은 커널이 같고 apt냐 yum이냐, libc 버전이 몇이냐 정도만 다르다. 내가 갈아끼우던 건 OS가 아니라 같은 커널의 껍데기였다.
OS를 나누는 기준은 커널이었다.
문제는 Mac에서 저걸 돌리면 나오는 값이다. linuxkit 같은 이름이 찍힌다. macOS 커널이 아니다. Docker Desktop이 리눅스 VM을 하나 띄워놓고 컨테이너를 전부 그 안에서 돌리고 있기 때문이다.
윈도우에서도 똑같다. WSL2 커널 이름이 찍힌다. 즉 윈도우에서 Docker를 깔아도 기본값은 윈도우 컨테이너가 아니라 리눅스 컨테이너다. 호스트만 윈도우일 뿐 안에서는 리눅스 VM이 돌고 있다.
윈도우 컨테이너가 있기는 하다
윈도우 호스트에서 윈도우 컨테이너를 돌리는 건 가능하다. Windows Server 2016부터 있고, NT 커널을 공유하고 Job Object와 Server Silo로 격리한다. 리눅스의 namespace와 cgroup이 하는 일을 윈도우가 자기 방식으로 구현한 거다.
심지어 숨겨져 있지도 않다. 윈도우용 Docker Desktop 트레이 아이콘을 우클릭하면 Switch to Windows containers... 라는 메뉴가 있다. 누르면 전환된다.
docker run mcr.microsoft.com/windows/servercore:ltsc2022
전환하고 나면 이게 돈다. 커널 공유 원리도 내가 생각했던 그대로다.
그런데 그 상태에서 docker pull ubuntu 를 하면 실패한다. no matching manifest for windows/amd64 라고 나온다. 윈도우용 ubuntu 이미지 같은 건 없기 때문이다.
전환은 되는데 받을 이미지가 없다
docker pull ubuntu는 누구나 공짜로 받아서 아무 데서나 돌릴 수 있다. 하지만 윈도우는 그게 법적으로 안 된다. 인스턴스마다 라이선스가 필요하고 마이크로소프트가 내놓은 컨테이너 이미지도 라이선스 있는 윈도우 호스트에서만 돌릴 수 있다. 이미지를 올려놓고 아무나 받아 쓰게 할 수가 없는 구조다.
| 항목 | 리눅스 컨테이너 | 윈도우 컨테이너 |
| 배포 | 누구나 pull | 라이선스 있는 호스트에서만 |
| 베이스 이미지 크기 | alpine 5MB, ubuntu 30MB | servercore 수 GB |
| 호스트 호환 | 커널 버전 무관 | 빌드 번호 일치 필요 |
| 생태계 | Docker Hub 수백만 개 | 사실상 없음 |
사람들이 도커를 쓰는 이유는 격리보다 Docker Hub 쪽인 것 같다. 남이 만든 이미지를 그냥 받아서 돌리려고 쓰는 거다. 윈도우 컨테이너로 전환하면 그 생태계가 통째로 사라진다. 그래서 메뉴가 있어도 아무도 안 누르고, 안 누르니까 나 같은 사람은 있는 줄도 모른다.
그래서 dockur/windows는 컨테이너가 아니다
처음 봤던 프로젝트로 돌아가면, 컨테이너를 띄워놓고 안을 들여다보면 답이 나온다.
docker exec -it windows ps aux | grep qemu
qemu-system-x86_64가 떠 있다.

컨테이너 안에서 QEMU가 진짜 VM을 하나 띄우고 그 안에 윈도우가 자기 NT 커널을 통째로 들고 도는 구조다. 윈도우 컨테이너 기능은 쓰지도 않는다. 리눅스 호스트에서도 돌아가는 이유가 이거고, /dev/kvm을 넘겨받아야 쓸 만한 속도가 나오는 것도 이 때문이다.
라이선스도 안 푼다. ISO는 마이크로소프트 서버에서 받아오지만 라이선스는 사용자 책임이라고 적어놨다.
결국 팔린 건 기술이 아니라 설치 과정이었다
QEMU로 윈도우 VM 띄우는 건 20년 된 기술이다.
그럼 스타 5만 개는 뭐냐면
- ISO를 자동으로 받아오고
autounattend.xml을 만들어서 클릭 없이 설치를 끝내고- noVNC를 물려서 브라우저로 접속하게 한 것
이걸 docker run 하나로 묶었다.
예전엔 virt-manager 켜고 ISO 구해서 클릭 수십 번 하던 일이라 반나절이 걸렸다.
Mac에서만 써본 탓에 뒤에 리눅스 VM이 있다는 것도 모르고 있었다. 호스트가 뭐든 내가 보고 있던 건 계속 리눅스였다.
사실 dockur/windows는 내가 당장 쓸 일이 없는 도구다. 그런데 이게 왜 화제인지 궁금해서 들여다본 덕에 컨테이너에 대해 안다고 생각했던 걸 다시 확인했고, 모르고 있던 것도 몇 개 알게 됐다.
새로 나오는 걸 따라가는 게 그 기술 하나를 배우는 일만은 아니었다. 이미 안다고 믿던 지식을 점검하고 넓히는 데도 도움이 되었다.
'DevOps & Infra > Docker' 카테고리의 다른 글
| [Docker] 도커가 만들지 않은 것들: namespace·cgroup이 커널에 들어간 10년 (0) | 2026.10.01 |
|---|---|
| [Docker] 컨테이너 통신: Bridge부터 User-defined까지 (0) | 2025.11.28 |