Podman 루트리스 컨테이너와 Copy Fail 익스플로잇
(garrido.io)- CVE-2026-31431 Copy Fail은 로컬 비권한 사용자가
root셸을 얻을 수 있게 하며, Podman 루트리스 컨테이너 안에서도 컨테이너 내부root권한 상승이 가능함 - Podman 루트리스 컨테이너는 사용자 네임스페이스, UID 분리, Linux capabilities를 조합해 컨테이너 내부
root를 호스트의 비권한 사용자로 매핑하고 호스트 권한을 제한함 - 테스트에서 rootless non-root 컨테이너의
foo사용자는 Copy Fail 실행 후 컨테이너 내부root가 될 수 있었지만, 권한은 호스트 비권한 사용자bar가 가능한 범위로 제한됐고 호스트root소유 파일은 읽지 못함 --security-opt=no-new-privileges나--cap-drop=all을 적용하면 Copy Fail 실행 후에도 셸이foo와 capabilitiesnone상태로 유지되어 즉각적인root셸 획득과 capability 상승을 막을 수 있음- Copy Fail의 효과는 컨테이너 생명주기를 넘어 남을 수 있어 커널 패치와 재부팅이 필요하며, 읽기 전용 루트 파일시스템, cgroups 리소스 제한, 얇은 런타임 이미지, 방화벽 같은 심층 방어를 함께 적용해야 함
Copy Fail과 Podman 루트리스 컨테이너의 노출 범위
- CVE-2026-31431은 4월 29일 copy.fail에서 공개됐으며, 공개된 Python 스크립트를 실행하면 로컬 비권한 사용자가
root셸을 얻을 수 있음 - Copy Fail은 Linux 컨테이너 안에서도 악용 가능하며, Podman 루트리스 컨테이너에서도 컨테이너 내부
root셸 획득이 가능함 - 테스트에서는 컨테이너
root가 호스트 수준에서 컨테이너를 실행한 비권한 사용자bar의 권한 범위로 제한됨 - Podman의 루트리스 구현은 사용자 네임스페이스, UID 분리, Linux capabilities를 조합해 컨테이너 프로세스의 호스트 권한을 제한함
- Copy Fail은 루트리스 컨테이너도 취약점에 면역이 아니지만, Podman 설정으로 침해 후 공격 범위를 줄일 수 있음을 보여줌
루트리스 컨테이너의 동작 방식
-
기본 예제: 비권한 사용자
bar가 HTTP 서버 실행- 예제 환경은 UID
1001인 비권한 사용자bar가 Podman으로ubuntu:latest기반 이미지를 빌드하고,python3 -m http.server를 실행하는 구성임 - 호스트에서
ps로 보면python3프로세스는 사용자bar소유로 실행됨 - Podman은 fork/exec 모델을 사용하므로 컨테이너 프로세스는
podman run프로세스의 후손이 되며, 일반적인 UID 분리로 컨테이너 프로세스를 호스트root나 다른 사용자와 분리할 수 있음 - 일반적인 Docker 구성에서는 비권한 사용자가
docker run을 실행해도 Docker 클라이언트가 루트 권한 데몬과 통신하고, 데몬이 최종적으로 컨테이너 프로세스를 생성하므로 호스트에서 컨테이너 프로세스가root로 보일 수 있음
- 예제 환경은 UID
-
루트리스 rootful
- 컨테이너 이미지는 명시적인
USER지시어나--user플래그가 없으면 보통 컨테이너 명령을 내부root로 실행함 podman top출력에서 HTTP 서버 프로세스는 호스트 사용자1001로 매핑되지만, 컨테이너 내부 사용자로는root로 실행됨- 이 구성은 호스트에서는 비권한 사용자로 실행되지만 컨테이너 내부에서는
root인 rootless rootful 상태임
- 컨테이너 이미지는 명시적인
-
사용자 네임스페이스
- Podman 루트리스 컨테이너는 사용자 네임스페이스를 사용해 컨테이너 안팎의 UID/GID를 다르게 매핑함
- 예제에서 컨테이너 내부 UID
0인root는 호스트의 UID1001인bar로 매핑됨 /etc/subuid의bar:165536:65536설정은bar의 네임스페이스 프로세스에 할당 가능한 UID 범위를 정함- 예제에서는
bar의 UID1001외에165536부터231072까지의 UID가bar프로세스에 할당될 수 있음 - 컨테이너 내부 사용자
www-data로sleep을 실행하면 내부에서는www-data지만 호스트에서는165568로 표시됨 podman unshare로 사용자 네임스페이스에 들어가면, 호스트에서bar:bar소유인 홈 디렉터리가 네임스페이스 내부에서는root:root로 보임- Docker도 사용자 네임스페이스를 지원하지만 별도 설정이 필요하고 하나의 사용자 네임스페이스만 허용되는 반면, Podman은 각 UNIX 사용자의 루트리스 컨테이너를 해당 사용자 네임스페이스에서 실행함
-
권한 작업과 Linux capabilities
- Podman은 Linux capabilities를 사용해 컨테이너 프로세스에 세분화된 루트 권한을 부여함
- 이미지 빌드 중
apt install같은 작업은chown,dac_override,fowner,setgid,setuid,net_bind_service,sys_chroot같은 capability 조합으로 가능해짐 podman build --cap-drop=all로 모든 capability를 제거하면apt가setgroups,setegid,seteuid,chown등에 실패해 이미지 빌드가 실패함- 필요한 capability만 추가하는 방식도 가능하며, 예제에서는
CAP_SETUID,CAP_SETGID,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER를 추가해 패키지 설치를 수행함 - 기본 실행 상태의 HTTP 서버는 컨테이너 내부
root로 실행되며CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT같은 많은 effective capabilities를 가짐 - HTTP 서버에는 이런 권한이 필요 없으므로
podman run --cap-drop=all로 모든 capability를 제거할 수 있으며, 이때podman top에서는 effective capabilities가none으로 표시됨
-
루트리스 non-root
- 컨테이너 내부에서도 비권한 사용자로 HTTP 서버를 실행하려면 기존
/etc/passwd의 사용자, 예를 들어www-data를 쓰거나 이미지 빌드 중 전용 사용자를 만들 수 있음 - 예제에서는 UID
1002인foo사용자와 그룹을 만들고/var/www/html에 읽기 권한을 부여한 뒤USER foo:foo를 설정함 - 이 이미지를
--cap-drop=all로 실행하면 프로세스는 컨테이너 내부foo, 호스트 UID166537, effective capabilitiesnone상태가 됨 - 컨테이너 프로세스는 필요한 최소 권한으로 실행해야 하며, 예를 들어
foo가 권한 포트80에 바인딩해야 한다면--cap-add=CAP_NET_BIND_SERVICE를 추가해야 함 - 컨테이너 실행 방식은 네 가지로 구분됨
root호스트 사용자 + 컨테이너root: root rootfulroot호스트 사용자 + 컨테이너 비권한 사용자: root non-root- 비권한 호스트 사용자 + 컨테이너
root: rootless rootful - 비권한 호스트 사용자 + 컨테이너 비권한 사용자: rootless non-root
- Podman은 rootless rootful 컨테이너 실행을 쉽게 만들며, 컨테이너 프로세스를 비권한 사용자로 실행할 수 있다면 rootless non-root 구성도 비교적 쉽게 만들 수 있음
- 컨테이너 내부에서도 비권한 사용자로 HTTP 서버를 실행하려면 기존
바인드 마운트와 UID 격리
- 호스트 디렉터리를 컨테이너에 마운트하면 호스트
root, 호스트bar, 네임스페이스foo가 소유한 파일의 접근 가능 여부가 UID 매핑에 따라 달라짐 - 예제에서는
/var/lib/bar/test디렉터리에 호스트root소유root.txt, 호스트bar소유bar.txt를 만들고, 컨테이너에서/test로 읽기/쓰기 마운트함 - 컨테이너를
foo로 실행하면 호스트bar소유 파일은 컨테이너 내부에서root:root로 보이고, 호스트root소유 파일은 네임스페이스에 매핑되지 않아nobody:nogroup으로 보임 - 컨테이너 내부
foo는bar.txt와root.txt를 읽지 못하며, rootless non-root가 rootless rootful보다 추가 격리를 제공함 foo가 마운트 디렉터리에 만든foo.txt는 호스트에서 UID166537소유로 표시되고, 호스트 사용자bar는 해당 파일 내용을 읽지 못함- 컨테이너를 내부
root로 실행하면 네임스페이스root는 호스트bar소유 파일과foo소유 파일을 읽을 수 있지만, 호스트root소유 파일은 읽지 못함 - 내부
root로 실행하면서--cap-drop=all을 적용하면foo파일도 읽지 못하고, 호스트bar소유 파일만 읽을 수 있음
Copy Fail 테스트
-
테스트 조건
- Copy Fail 테스트에는 원래 공개된 커밋
8e918b5의 익스플로잇 버전이 사용됨 - 예제 컨테이너 이미지는 기존 HTTP 서버 이미지에
curl을 추가해 컨테이너 안에서 익스플로잇 스크립트를 내려받을 수 있게 함 - 이미지 이름은
copyfail로 빌드됨 - 테스트 커널은 Debian의
6.12.74+deb13+1-amd64이며, Debian 기준 최근 버전 중6.12.85미만이면 아직 패치되지 않은 커널로 사용 가능하다고 봄 - 일반적으로 비권한 사용자
foo가su를 호출하면root비밀번호를 요구함 - 각 테스트에서는 컨테이너 사용자가
/tmp에 Copy Fail 스크립트를 다운로드하고 실행한 뒤,root셸을 얻으면sleep을 호출함 - Copy Fail은 컨테이너 생명주기를 넘어 지속되므로 각 테스트 전에 VM을 재부팅함
- Copy Fail 테스트에는 원래 공개된 커밋
-
루트리스 rootful에서의 결과
--user=root로 컨테이너를 실행하면 컨테이너 내부 프로세스는 이미root임- 이 상태에서 Copy Fail 스크립트를 실행하고
su를 호출하면uid=0(root)셸을 얻지만,root사용자는 원래 비밀번호 없이su로 다른 root 셸을 열 수 있으므로 Copy Fail이 실질적으로 추가하는 바는 없음 podman top에서는/bin/bash,python3 copy_fail_exp.py,su,sleep모두 컨테이너 내부root, 호스트 사용자1001로 표시됨- 동일한 capability 집합이 유지되며
CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT가 보임 - 내부
root는 마운트된/test에서bar.txt와foo.txt는 읽지만, 호스트root소유root.txt는 읽지 못함
-
루트리스 non-root에서의 결과
- 컨테이너를
foo로 실행한 뒤 Copy Fail 스크립트를 실행하고su를 호출하면 컨테이너 내부root로 권한 상승됨 - 결과 셸의
id는uid=0(root) gid=1002(foo) groups=1002(foo)로 표시됨 podman top에서는 초기/bin/bash, 익스플로잇 실행 프로세스,su호출은 호스트 UID166537, 컨테이너 사용자foo, capabilitiesnone상태로 보임- 권한 상승 후
[sh]와sleep은 호스트 사용자1001, 컨테이너 사용자root로 표시되고, rootless rootful과 같은 capability 집합을 얻음 - 권한 상승된 컨테이너
root도 호스트root소유root.txt는 읽지 못함 - 이 상태에서는 컨테이너가 침해됐지만, 공격 범위는 컨테이너와 호스트 비권한 사용자
bar가 가능한 범위로 제한됨
- 컨테이너를
-
no-new-privileges적용 시 결과- Podman은
--security-opt=no-new-privileges로 컨테이너 프로세스가 시작 시점보다 더 많은 권한을 얻지 못하게 할 수 있음 - rootless non-root 컨테이너에 이 옵션을 적용하고 Copy Fail을 실행하면 셸은 열리지만 여전히
uid=1002(foo)상태임 podman top에서도 모든 프로세스가 호스트 UID166537, 컨테이너 사용자foo, capabilitiesnone으로 유지됨- 마운트된
/test에서도foo는 자기 파일만 읽을 수 있고bar.txt와root.txt는 읽지 못함 - 컨테이너는 침해됐지만, 내부 비권한 사용자
foo와 capability 없는 상태로 제한됨
- Podman은
-
--cap-drop=all적용 시 결과- rootless non-root 컨테이너를
--cap-drop=all로 실행해도foo는 원래 capability가 없음 - 이 상태에서 Copy Fail을 실행하고
su를 호출하면 열린 셸은uid=1002(foo)로 유지됨 podman top에서도/bin/bash, 익스플로잇 실행,su, 셸,sleep모두foo와 capabilitiesnone상태임- 익스플로잇은
root셸 획득에는 실패하고,foo는/test에서 자기 파일만 읽을 수 있음 - 이 결과는
no-new-privileges테스트와 유사하며, 두 조치는 함께 사용해 capability 노출을 효과적으로 줄일 수 있음
- rootless non-root 컨테이너를
-
익스플로잇의 지속성
- 즉각적인
root셸과 capability 획득은no-new-privileges나--cap-drop=all로 막을 수 있었지만, 익스플로잇 자체의 효과는 남음 - 이후 capability 제한 없이 새 컨테이너를 실행하면 비권한 컨테이너 사용자
foo가su만 호출해도 컨테이너root가 될 수 있음 - 따라서 커널 패치와 재부팅이 여전히 필요함
- 즉각적인
심층 방어 전략
-
읽기 전용 이미지
podman run에--read-only를 추가하면 컨테이너 루트 파일시스템이 읽기 전용으로 마운트됨- Podman은 기본적으로
/tmp,/run,/var/tmp같은 일부 디렉터리를 쓰기 가능하게 마운트하므로, 완전히 읽기 전용으로 만들려면--read-only-tmpfs=false도 추가해야 함 - 읽기 전용 컨테이너가 침해되면 시스템에 쓰기 작업이 허용되지 않아 익스플로잇 이후 일부 공격을 제한할 수 있음
- 다만
curl출력을python3로 파이프할 수 있으므로 읽기 전용 설정만으로 익스플로잇 실행 자체를 막지는 못함 - 예제의
python3HTTP 서버는 파일시스템 쓰기가 필요 없어 이 옵션을 안전하게 사용할 수 있음 - 많은 사전 빌드 이미지는 특정 디렉터리에 쓰기 접근을 전제로 하므로 읽기 전용 루트 파일시스템에서 제대로 동작하지 않을 수 있음
- 읽기 전용 루트 파일시스템은 컨테이너에 연결된 쓰기 가능 볼륨과 독립적이며, 침해 시 해당 마운트 디렉터리에는 여전히 쓸 수 있음
-
리소스 제한
- Docker와 Podman은 cgroups를 사용해 컨테이너에 제공되는 리소스를 제한할 수 있음
- 컨테이너에는 무제한 메모리, CPU, PID가 필요하지 않음
podman stats로 컨테이너 리소스 사용량을 확인한 뒤 그에 맞춰 제한을 적용할 수 있음
-
사용 가능한 바이너리 제한
- 예제는 단순화를 위해
ubuntu이미지를 사용했지만,ubuntu이미지는 침해 시 공격자가 사용할 수 있는 많은 바이너리를 포함함 - HTTP 서버 실행에는 이런 바이너리 대부분이 필요하지 않음
- 런타임 이미지는 가능한 한 얇게 구성하는 편이 좋음
- 멀티스테이지 빌드를 사용해 빌드 타임 환경과 런타임 환경을 분리할 수 있음
- python3 같은 목적별 이미지, Debian의
-slim변형,alpine같은 더 작은 배포판을 기반으로 사용할 수 있음 - 컨테이너 프로세스와 호환된다면 distroless images나
scratch를 사용해 셸, 패키지 관리자, 시스템 유틸리티가 없는 런타임을 만들 수 있음
- 예제는 단순화를 위해
-
방화벽
iptables나nftables를 사용해 컨테이너 프로세스를 방화벽으로 제한할 수 있음- 컨테이너 프로세스에 꼭 필요한 수신·송신 연결만 허용해야 함
- HTTP 서버 예제에서는 DNS나 로컬·원격 서버로의 연결이 필요하지 않으므로, 성립된 수신 연결에서 오는
tcp패킷만 허용하는 식으로 제한할 수 있음
운영상 의미
- 표준 Podman 루트리스 컨테이너는 표준 Docker 컨테이너 구성보다 더 나은 격리 수단을 기본적으로 제공함
- Docker도 rootless 실행과 비권한 사용자 네임스페이스 사용이 가능하지만, Podman보다 더 많은 설정 노력이 필요하며 아키텍처 차이도 영향을 줌
- Docker는 여전히 널리 사용되며 Dokku, Kamal, Coolify, Dokploy 같은 셀프호스팅 도구도 기본적으로 Docker를 사용함
- Docker Hub 이미지를 충분히 검토하지 않고 실행하거나 잠금 조치를 적용하지 않으면 필요한 것보다 넓은 공격 표면으로 서비스가 실행될 수 있음
- 컨테이너 이미지의 구현 세부사항을 이해해야 함
- 어떤 사용자 또는 사용자들이 컨테이너 프로세스를 실행하는지 알아야 함
- 컨테이너 프로세스가 루트 파일시스템의 어떤 디렉터리에 의존하는지 알아야 함
- 필요한 Linux capabilities와 필요하지 않은 capabilities를 구분해야 함
- Podman과 컨테이너가 제공하는 여러 메커니즘을 조합하면 컨테이너를 강화하고 침해 시 폭발 반경을 줄일 수 있음
- 워크로드에 따라 컨테이너를 유일한 보안 경계로 의존해서는 안 됨
- 컨테이너와 별도 물리·가상 머신을 함께 사용하면 효과적으로 분리할 수 있음
- Podman은 같은 호스트 안에서도 각 워크로드를 별도의 비권한 사용자와 자체 사용자 네임스페이스로 실행해 격리하는 방법을 제공함
추가 자료
Lobste.rs 의견들
-
공개된 익스플로잇보다 취약점이 가능하게 하는 원시 동작에 초점을 맞춰야 함
이 취약점은 읽기 전용 여부와 관계없이 페이지 캐시에 쓸 수 있게 하므로, 악성 컨테이너가 overlayfs의 베이스 이미지 파일에 속한 페이지를 변조할 수 있고, 컨테이너 배포 방식에 따라 다른 컨테이너로도 영향이 넘어갈 수 있음
여기서의 rootless 구성이라면 호스트 시스템에서 같은 사용자로 실행되는 다른 컨테이너가 대상이 됨
다른 익스플로잇 방식으로는, 이미 사용 중인 것으로 알려진 베이스 이미지 기반 컨테이너를 실행하거나 찾아서 그 컨테이너 안의 페이지 캐시를 변조한 뒤, 같은 런타임과 overlayfs 데이터를 공유하는 다른 컨테이너가 그 코드를 실행하게 만들 수 있음
rootless와 사용자 네임스페이스는 중요하지만 여기서는 별 도움이 되지 않으며, copy.fail 사이트가 말하듯 컨테이너에서는 seccomp로socket(AF_ALG, ...)시스템 호출을 막는 쪽을 검토해야 함- 기본 원시 동작까지는 깊게 생각하지 못했고, rootless 컨테이너가 제공하는 네임스페이스와 capability를 정리해 침해된 컨테이너의 노출 범위를 평가하는 데 더 신경 썼음
“컨테이너 배포 방식에 따라”가 구체적으로 무엇을 뜻하는지 더 설명해 주면 좋겠음
rootless Podman의 장점은 워크로드에 따라 호스트에서 같은 사용자로 컨테이너를 실행할 필요가 없다는 점임
주 워크스테이션 사용자로 여러 rootless 컨테이너를 돌리는 경우를 말한 거라면 동의하지만, 서버에서는 각각을 별도 사용자로 분리할 수 있고 같은 컨테이너 이미지도 서로 다른 비권한 사용자로 실행 가능함
대부분을root로 실행하는 Docker 기본값과는 꽤 다르지만, 이것이 궁극적인 보안 경계가 아니라는 점도 글 말미에 적었고, 여러 비권한 사용자에 rootless 컨테이너를 나눠 쓰는 방식이 적절한지는 용도에 따라 달라짐
특정 워크로드는 VM으로 분리해 쓰고 있음
rootless와 사용자 네임스페이스가 여기서 도움이 되지 않는다는 말이 익스플로잇 방지를 뜻하는지 궁금함
seccomp는 아직 컨테이너에 명시적 정책을 써본 적이 없어 다루지 않았지만, 더 살펴볼 좋은 계기임
- 기본 원시 동작까지는 깊게 생각하지 못했고, rootless 컨테이너가 제공하는 네임스페이스와 capability를 정리해 침해된 컨테이너의 노출 범위를 평가하는 데 더 신경 썼음
-
Podman과 rootless 컨테이너를 좋아하지만, CopyFail을 보고 형제 댓글과 같은 결론에 도달했음
podman+rootless의 추가 접근 제어 이점이 있어도 결국 컨테이너는 보안 경계가 아니다라는 고전적 조언을 다시 확인하게 됐고, 커널 익스플로잇 하나면 전부 뚫릴 수 있음
취미로 시스템 관리를 하는 수준이지만, 이 영역의 새로운 흐름으로 libkrun backend for crun with podman을 봤음
대부분의 컨테이너화된 워크로드를 그대로 다루면서도 내부적으로는 별도 게스트 커널을 가진 MicroVM에서 실행된다는 약속인데, 성숙도·실전 검증·보안 감사 수준은 잘 모르겠고 일부는 상당히 최첨단으로 보임
MicroVM이 LLM 코딩 도구에서 적극적으로 채택되고 있어 그런 상태가 오래갈 수도 있음
podman machine도 유망해 보였지만, 아쉽게도 개발자 워크스테이션 용도만 염두에 둔 것이고 호스트 시스템당 컨테이너 실행 VM을 하나만 두는 모델이었음
그래도 “컨테이너는 보안 경계가 아니다”라는 말은 너무 단순하다고 봄. 컨테이너는 분명 보안 경계이지만, 우리가 믿고 싶은 만큼 강하지 않을 뿐임- 대부분의 클라우드 컨테이너 배포가 VM을 쓰는 이유도 같음. VM은 방어 가능한 경계임
로컬 배포에서는 이 선이 좀 더 흐릿함
하드웨어 관점에서 VM이 프로세스보다 본질적으로 더 안전한 것은 아니지만, 세 가지 이유로 경계가 더 방어 가능함
VM 탈출은 시스템 호출보다 덜 흔하므로 성능 손상 없이 더 많은 부채널 완화를 적용할 여지가 있음
VM의 호스트 인터페이스는 훨씬 단순함. 블록 장치는 블록 단위 읽기·쓰기 인터페이스가 있고, 네트워크 장치는 프레임을 보내고 받음
Linux나 *BSD가 소켓에 제공하는setsockopt호출은 대부분의 에뮬레이션·반가상화 드라이버보다 훨씬 큰 공격 표면이고, 그조차 커널 전체 공격 표면의 아주 작은 일부임
VM 인터페이스는 상태도 훨씬 적은 편임. 요청-응답 모델의 링에 진행 중인 트랜잭션은 있지만 그 외에는 거의 없음
자격 증명, UID, GID, 파일 디스크립터 테이블 같은 것들은 커널에 상태 기반 복잡성을 추가하고, 버그가 있으면 프로세스가 이를 악용할 수 있음
워크스테이션 변형의 어려움은 이런 복잡성을 다시 들여오게 된다는 점임
예를 들어 컨테이너 베이스 레이어는 불변 파일시스템을 담은 블록 장치로 노출될 수 있지만, 볼륨과 공유 폴더는 아마 9pfs나 VirtIO-FS, 즉 VirtIO 위의 9p 또는 FUSE로 마운트될 것임
그러면 공격 표면이 다시 커짐
운이 좋다면 익스플로잇 체인이 필요함
FreeBSD 쪽에 더 익숙한데, 보통 반가상화·에뮬레이션 장치를 제공하는 구성요소를 Capsicum으로 샌드박스 처리하므로 먼저 호스트 프로세스를 장악하고, 그다음 VM이 접근 권한이 없던 것에 접근하려면 커널까지 뚫어야 함
하지만 이런 추가 샌드박싱을 하지 않으면 컨테이너 탈출이 사용자가 할 수 있는 모든 일을 할 수 있는 세계로 돌아가며, 데스크톱에서 root가 뚫린 것보다 크게 낫지 않음 - Kata Containers와 Firecracker는 이미 꽤 오래된 기술이고, 연구자들이 검토해 왔기 때문에 합리적으로 성숙했다고 봄
개인적으로는 gVisor를 더 선호함. VMM 런타임은 아니지만 몇 년째 존재했고, Tencent 같은 회사에서도 쓰이며, 모든 컨테이너를 이미 Proxmox VM 안에서 돌리는 내 환경에서는 잘 맞음
또 테스트 중인 것은 syd-oci인데, MicroVM이나 gVisor라는 기본 추천지에 비해 다소 주목을 덜 받은 것 같음 - 그 표현이 내 경험과도 맞고, 이 글을 쓰는 과정도 그 사실을 받아들이는 연습에 가까웠음
libkrun 참고 자료도 고맙고, 유망한 가능성으로 보임 - LLM 코딩 도구 쪽의 적극적인 채택은 MicroVM을 더 성숙하게 만들고, 실전 검증과 강화로 이어질 가능성이 큼
보안 감사로 이어질 가능성도 높아 보임
- 대부분의 클라우드 컨테이너 배포가 VM을 쓰는 이유도 같음. VM은 방어 가능한 경계임