Kiedy ostatnio sprawdzałem, Docker nie miał żadnych środków, aby dać kontenerowi dostęp do portu szeregowego lub USB hosta . Czy jest jakaś sztuczka, która na to pozwala?
139
Kiedy ostatnio sprawdzałem, Docker nie miał żadnych środków, aby dać kontenerowi dostęp do portu szeregowego lub USB hosta . Czy jest jakaś sztuczka, która na to pozwala?
Jest kilka opcji. Możesz użyć --device
flagi, która może użyć, aby uzyskać dostęp do urządzeń USB bez --privileged
trybu:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
Alternatywnie, zakładając, że twoje urządzenie USB jest dostępne z działającymi sterownikami itp. Na hoście w /dev/bus/usb
, możesz to zamontować w kontenerze przy użyciu trybu uprzywilejowanego i opcji woluminów . Na przykład:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
Zauważ, że jak sama nazwa wskazuje, --privileged
jest niepewny i należy obchodzić się z nim ostrożnie.
W obecnych wersjach Dockera możesz użyć
--device
flagi, aby osiągnąć to, co chcesz, bez konieczności udzielania dostępu do wszystkich urządzeń USB.Na przykład, jeśli chcesz, aby był
/dev/ttyUSB0
dostępny tylko w kontenerze Docker, możesz zrobić coś takiego:źródło
--device
flagi, jak określić, które/dev/<device>
z urządzeń z systemem Android jest skojarzone z hostem, zwłaszcza w przypadku korzystania z terminala Docker Quickstart (Host VirtualBox) dla systemu Windows lub Mac?--device
działa do momentu odłączenia / ponownego podłączenia urządzenia USB, a następnie przestaje działać. Musisz użyć urządzeń cgroup .allow ominąć to.Możesz po prostu użyć,
-v /dev:/dev
ale jest to niebezpieczne, ponieważ mapuje wszystkie urządzenia z twojego hosta do kontenera, w tym surowe urządzenia dyskowe i tak dalej. Zasadniczo umożliwia to kontenerowi uzyskanie roota na hoście, co zwykle nie jest tym, czego chcesz.Korzystanie z podejścia cgroups jest lepsze pod tym względem i działa na urządzeniach, które są dodawane po uruchomieniu kontenera.
Zobacz szczegóły tutaj: Dostęp do urządzeń USB w Dockerze bez użycia --privileged
Trochę trudno to wkleić, ale w skrócie, musisz zdobyć główny numer urządzenia postaci i wysłać go do cgroup:
189 to główna liczba / dev / ttyUSB *, którą można uzyskać za pomocą 'ls -l'. W Twoim systemie może wyglądać inaczej niż w moim:
Następnie uruchom kontener w ten sposób:
bez tego każde nowo podłączone lub ponownie uruchomione urządzenie po uruchomieniu kontenera otrzyma nowy identyfikator magistrali i nie będzie miało dostępu do kontenera.
źródło
189
należy go zastąpić. Opis tego, co należy wysłać,devices.allow
można znaleźć tutaj: kernel.org/doc/Documentation/cgroup-v1/devices.txtChciałem rozszerzyć odpowiedzi już udzielone, aby uwzględnić obsługę dynamicznie podłączonych urządzeń, które nie są przechwytywane,
/dev/bus/usb
i jak to działa, gdy używam hosta Windows wraz z maszyną wirtualną boot2docker.Jeśli pracujesz z systemem Windows, musisz dodać reguły USB dla urządzeń, do których chcesz mieć dostęp Docker w menedżerze VirtualBox. Aby to zrobić, możesz zatrzymać maszynę wirtualną, uruchamiając:
Otwórz VirtualBox Manager i dodaj obsługę USB z filtrami zgodnie z wymaganiami.
Uruchom maszynę wirtualną boot2docker:
Ponieważ urządzenia USB są podłączone do maszyny wirtualnej boot2docker, polecenia muszą być uruchamiane z tej maszyny. Otwórz terminal z maszyną wirtualną i uruchom polecenie docker run:
Uwaga, gdy polecenie zostanie uruchomione w ten sposób, przechwycone zostaną tylko wcześniej podłączone urządzenia USB. Flaga woluminów jest wymagana tylko wtedy, gdy chcesz, aby działała z urządzeniami podłączonymi po uruchomieniu kontenera. W takim przypadku możesz użyć:
Uwaga, w niektórych przypadkach musiałem użyć
/dev
zamiast tego,/dev/bus/usb
aby przechwycić urządzenie takie jak/dev/sg2
. Mogę tylko założyć, że to samo dotyczy urządzeń takich jak/dev/ttyACM0
lub/dev/ttyUSB0
.Polecenia uruchamiania dockera będą działać również z hostem Linux.
źródło
Inną opcją jest dostosowanie udev, który kontroluje sposób montowania urządzeń i jakie uprawnienia. Przydatne, aby umożliwić innym użytkownikom dostęp do urządzeń szeregowych. Jeśli masz urządzenia podłączone na stałe, ta
--device
opcja jest najlepszym rozwiązaniem. Jeśli masz urządzenia efemeryczne, oto czego używam:1. Ustaw regułę udev
Domyślnie urządzenia szeregowe są montowane tak, aby tylko użytkownicy root mieli dostęp do urządzenia. Musimy dodać regułę udev, aby były czytelne dla użytkowników innych niż root.
Utwórz plik o nazwie /etc/udev/rules.d/99-serial.rules. Dodaj następujący wiersz do tego pliku:
KERNEL=="ttyUSB[0-9]*",MODE="0666"
MODE = "0666" da wszystkim użytkownikom uprawnienia do odczytu / zapisu (ale nie wykonywania) na urządzeniach ttyUSB. Jest to najbardziej dopuszczalna opcja i możesz chcieć ją jeszcze bardziej ograniczyć w zależności od wymagań bezpieczeństwa. Możesz przeczytać o udev, aby dowiedzieć się więcej o kontrolowaniu tego, co się dzieje, gdy urządzenie jest podłączone do bramy Linuksa.
2. Zamontuj w folderze / dev z hosta do kontenera
Urządzenia szeregowe są często efemeryczne (można je podłączać i odłączać w dowolnym momencie). Z tego powodu nie możemy zamontować w urządzeniu bezpośrednim ani nawet w folderze / dev / serial, ponieważ mogą one zniknąć po odłączeniu urządzeń. Nawet jeśli podłączysz je ponownie, a urządzenie pojawi się ponownie, technicznie rzecz biorąc, jest to inny plik niż ten, który został zamontowany, więc Docker go nie zobaczy. Z tego powodu montujemy cały folder / dev z hosta do kontenera. Możesz to zrobić, dodając następujące polecenie głośności do polecenia uruchamiania platformy Docker:
-v /dev:/dev
Jeśli urządzenie jest podłączone na stałe, użycie opcji --device lub bardziej szczegółowego podłączenia woluminu jest prawdopodobnie lepszą opcją z punktu widzenia bezpieczeństwa.
3. Uruchom kontener w trybie uprzywilejowanym
Jeśli nie użyłeś opcji --device i zamontowano w całym folderze / dev, będziesz musiał uruchomić kontener w trybie uprzywilejowanym (mam zamiar sprawdzić wspomniane powyżej rzeczy cgroup aby sprawdzić czy da się to usunąć ). Możesz to zrobić, dodając następujące polecenie do polecenia uruchamiania platformy Docker:
--privileged
4. Uzyskaj dostęp do urządzenia z folderu / dev / serial / by-id
Jeśli twoje urządzenie można podłączyć i odłączyć, Linux nie gwarantuje, że będzie zawsze zamontowane w tej samej lokalizacji ttyUSBxxx (zwłaszcza jeśli masz wiele urządzeń). Na szczęście Linux automatycznie utworzy dowiązanie symboliczne do urządzenia w folderze / dev / serial / by-id. Plik w tym folderze zawsze będzie miał taką samą nazwę.
To jest krótkie podsumowanie, mam artykuł na blogu, który zawiera więcej szczegółów.
źródło
Trudno nam powiązać określone urządzenie USB z kontenerem docker, który również jest specyficzny. Jak widać, zalecanym sposobem osiągnięcia tego celu jest:
Spowoduje to powiązanie wszystkich urządzeń z tym kontenerem. To niebezpieczne. Do obsługi wszystkich przyznano każdy kontener.
Innym sposobem jest wiązanie urządzeń przez devpath. Może to wyglądać tak:
lub
--device
(lepiej nieprivileged
):Bezpieczniejsze. Ale tak naprawdę trudno jest wiedzieć, jaka jest ścieżka devpath konkretnego urządzenia.
Napisałem to repozytorium, aby rozwiązać ten problem.
https://github.com/williamfzc/usb2container
Po wdrożeniu tego serwera możesz łatwo uzyskać informacje o wszystkich podłączonych urządzeniach za pośrednictwem żądania HTTP:
i dostać:
i przywiąż je do swoich pojemników. Na przykład możesz zobaczyć DEVNAME tego urządzenia
/dev/bus/usb/001/120
:Może to pomoże.
źródło
Przy najnowszych wersjach dockera to wystarczy:
Zapewni dostęp do wszystkich zasobów systemowych (na przykład w / dev)
źródło
Dodając do powyższych odpowiedzi, dla tych, którzy chcą w szybki sposób korzystać z zewnętrznego urządzenia USB (HDD, pendrive) pracującego wewnątrz dockera, a nie korzystających z trybu uprzywilejowanego:
Znajdź devpath do swojego urządzenia na hoście:
Możesz łatwo rozpoznać swój dysk po jego pojemności na liście. Skopiuj tę ścieżkę (w poniższym przykładzie jest to
/dev/sda2
).Zamontuj tę devpath (najlepiej
/media
):Możesz następnie użyć tego jako parametru do polubienia
docker run
:lub w docker compose under volume:
A teraz, gdy uruchomisz i wejdziesz do kontenera, powinieneś mieć dostęp do dysku wewnątrz kontenera pod adresem
/media/<mount folder name>
ZRZECZENIE SIĘ:
źródło
Jeśli chcesz dynamicznie uzyskiwać dostęp do urządzeń USB, które można podłączyć, gdy kontener docker jest już uruchomiony, na przykład uzyskać dostęp do właśnie podłączonej kamery internetowej USB pod adresem / dev / video0, możesz dodać regułę cgroup podczas uruchamiania kontenera. Ta opcja nie wymaga --przywilejowanego kontenera i zezwala tylko na dostęp do określonych typów sprzętu.
Krok 1
Sprawdź numer główny urządzenia typu urządzenia, które chcesz dodać. Możesz to sprawdzić w dokumentacji jądra Linuksa . Lub możesz to sprawdzić dla swojego urządzenia. Na przykład, aby sprawdzić główny numer urządzenia dla kamery internetowej podłączonej do / dev / video0, możesz wykonać
ls -la /dev/video0
. Powoduje to coś takiego:Gdzie pierwsza liczba (81) to główny numer urządzenia. Niektóre popularne numery główne urządzeń:
Krok 2
Dodaj reguły po uruchomieniu kontenera Dockera:
--device-cgroup-rule='c major_number:* rmw'
regułę dla każdego typu urządzenia, do którego chcesz uzyskać dostęp-v /run/udev:/run/udev:ro
-v /dev:/dev
Zakończyć
Aby więc dodać wszystkie kamery internetowe USB i urządzenia serial2usb do kontenera Docker, wykonaj:
źródło