zapętlić urządzenie w kontenerze Linux?

14

Próbuję użyć urządzenia pętlowego wewnątrz kontenera, aby zamontować jakiś plik obrazu:

> sudo losetup /dev/loop0 test.img
losetup: /dev/loop0: failed to set up loop device: No such file or directory

/dev/loop0 naprawdę nie istnieje i

> sudo mknod /dev/loop0 b 7 0
mknod: ‘/dev/loop0’: Operation not permitted

Jak mogę to zrobić? Czy kontener potrzebuje uprawnień grupy cgroup, których może nie mieć?

Johannes Ernst
źródło

Odpowiedzi:

17

Jeśli używasz systemd-nspawn, uruchom kontener za pomocą --capability=CAP_MKNODprzełącznika wiersza polecenia. Umożliwi to tworzenie węzłów urządzeń w kontenerze. Następnie utwórz urządzenie pętlowe:

# mknod /dev/loop0 b 7 0

Pamiętaj, że to urządzenie pętli jest współdzielone z hostem i /dev/loop0tam również jest wywoływane . I że można teraz uzyskać dostęp do urządzeń hosta, jeśli znasz numery główne i podrzędne. Mogą być również inne konsekwencje, o których nie myślałem. Być ostrzeżonym.

Troels Folke
źródło
Czy ktoś może potwierdzić, że --capability=CAP_MKNODnadal działa? Wydaje mi się, że to nie ma żadnego efektu, Operation not permittednawet się z tym zgadzam , podobnie jak ten użytkownik i ten użytkownik .
nh2
2
Mam go teraz do pracy, ale oprócz dawania --capability=CAP_MKNODmusiałem ustawić DeviceAllow=block-loop rwmjednostkę systemd-nspawn, aby działało ( stąd ten pomysł ).
nh2
Musiałem dodać, --device-cgroup-rule="b 7:* rmw"aby docker runumożliwić pełny dostęp do urządzeń sprzężenia zwrotnego (ale żadnych innych, ponieważ nie ma --privilege). Znaleziono za pośrednictwem docs.docker.com/edge/engine/reference/commandline/create/… i przetestowano na dokerze 18.06.1-ce (dokument twierdzi, że dotyczy tylko Docker Edge)
RobM
9

Urządzenia pętli są dostarczane przez moduł jądra. Dlatego potrzebujesz specjalnych uprawnień, aby uzyskać do nich dostęp. Musisz je również wyeksponować w kontenerze lub ręcznie utworzyć pliki urządzenia.

Szybka odpowiedź

docker run --privileged=true ...

Alternatywa

sudo losetup /dev/loop0 test.img
mount /dev/loop0 /mnt
docker run -v /mnt:/mnt ...

To prawie działa

docker run --device=/dev/loop-control:/dev/loop-control --device=/dev/loop0:/dev/loop0 --cap-add SYS_ADMIN ...

Jednak pojawia się ten błąd:

root@5c033d5f8625:/# sudo mount /dev/loop0 /mnt
mount: block device /dev/loop0 is write-protected, mounting read-only
mount: cannot mount block device /dev/loop0 read-only

Zobacz ten link, aby uzyskać więcej informacji .


Uwaga na stronie podręcznika systemd-nspawn:

systemd-nspawn ogranicza dostęp do różnych interfejsów jądra w kontenerze tylko do odczytu, takich jak / sys, / proc / sys lub / sys / fs / selinux. Interfejsy sieciowe i zegar systemowy nie mogą być zmieniane z poziomu kontenera. Węzły urządzeń mogą nie zostać utworzone. Nie można zrestartować systemu hosta i modułów jądra nie można załadować z kontenera.

Matt
źródło