moby: Bluetooth socket can't be opened inside container
Hello,
I’m trying to get my bluetooth dongle working inside a docker container. When I try to start bluetoothd it says
root@a28c9bc0b5ef:~# /usr/local/libexec/bluetooth/bluetoothd -n
bluetoothd[15]: Bluetooth daemon 5.34
bluetoothd[15]: Failed to access management interface
bluetoothd[15]: Adapter handling initialization failed
I traced down the code inside bluez which triggers this behavior (src/shared/mgmt.c:439):
fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
BTPROTO_HCI);
The socket syscall always returns -1. When I “strace” the command I see
socket(PF_BLUETOOTH, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, 1) = -1 EAFNOSUPPORT (Address family not supported by protocol)
The same command works on the host machine without any issues. The bluetooth modules are all loaded:
root@a28c9bc0b5ef:~# lsmod | grep bt
btusb 28346 0
btbcm 4204 1 btusb
btintel 1332 1 btusb
bluetooth 315821 5 bnep,btbcm,btusb,btintel
/sys/class/bluetooth/hci0 exists both on the host as well as inside the container. It doesn’t matter how I run the container. Neither --privileged nor --cap-add=ALL nor --cap-add=NET_ADMIN change this behavior. A quick glance at linux/src/bluetooth/hci_sock.c reveals that CAP_NET_ADMIN and CAP_NET_RAW should be enough to issue any command to the socket (never had anything to do with linux kernel code until yet so I don’t know what exactly I’m talking about, though). I guess this is a problem with how docker(/lxc?) restricts the containers, but I don’t know for sure.
Obligatory bug report information:
# docker version
Client:
Version: 1.8.1
API version: 1.20
Go version: go1.4.2
Git commit: b66e5ef-dirty
Built: Wed Sep 2 19:02:45 UTC 2015
OS/Arch: linux/arm
Server:
Version: 1.8.1
API version: 1.20
Go version: go1.4.2
Git commit: b66e5ef-dirty
Built: Wed Sep 2 19:02:45 UTC 2015
OS/Arch: linux/arm
# docker info
Containers: 5
Images: 27
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 37
Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.1.6-v7+
Operating System: Debian GNU/Linux 8 (jessie)
CPUs: 4
Total Memory: 925.7 MiB
Name: raspberry
ID: T3Z3:Z6BJ:IGU5:F7HP:AGPB:LZTR:VQH2:EZUJ:HTVR:FRFX:H2RT:4V3M
WARNING: No memory limit support
WARNING: No swap limit support
# uname -a
Linux raspberry 4.1.6-v7+ #1 SMP PREEMPT Sun Aug 23 22:01:27 CEST 2015 armv7l GNU/Linux
Environment details: Physical (Raspberry Pi 2) How reproducible: Always Steps to reproduce:
- Build container with bluez installed
- Run with run options mentioned above (parameters don’t seem to matter anyway)
- Start bluetoothd Actual results: Doesn’t start up because it cannot open bluetooth socket Expected results: bluetoothd starts up just fine (at least when run with the right capabilities enabled)
PS1: This also happens on amd64 PS2: This also happens when using the --device switch
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 11
- Comments: 55 (6 by maintainers)
Commits related to this issue
- Add Dockerfile and entrypoint First attempt, got as far as I could before running into https://github.com/moby/moby/issues/16208 will try this on raspberry pi via balena.io to see how it works. — committed to lutostag/bt-speaker by deleted user 5 years ago
- Add Dockerfile and entrypoint First attempt, got as far as I could before running into https://github.com/moby/moby/issues/16208 will try this on raspberry pi via balena.io to see how it works. — committed to lutostag/bt-speaker by deleted user 5 years ago
Is there any way to access the bluetooth hardware without
--net=host
?It seems that the linux kernel currently does not allow containers to create bluetooth sockets (see this kernel patch for more info https://patchwork.kernel.org/patch/9898285/).
One workaround would be to switch bluetooth processes inside the containers back to the host net namespace without impacting the rest of the containers processes (eg. sshd).
To do that:
or alternatively, LD_PRELOAD the following shared object before executing bluetooth processes inside the container
This way you can still use docker port binding for non bluetooth processes inside the container. Pitfall : if the bluetooth process tries to bind to some port it would do so in the host net namespace (as if --net=host was used to start the container).
Hi there,
I needed to get Bluetooth LE working inside a container and I managed to get it up and running with the following container opts:
docker run -ti --privileged --net=host debian:jessie --name bletest /bin/bash
Then a small example:
And here bluetoothd seems to be happy…
I am trying to figure out why the
--net=host
is needed here. I could understand that the container need--privileged
rights, but not to be connected to the host network…YES!!! Thanks!!! Confirmed this --net=host configuration also works with the armv7/armhf-ubuntu:trusty version as well. I can replicate this.
On a side note, following @jfrazelle thoughts that privileged might not be required, I also tested without this option, and I also got it running.
Summary: both the following let BLE work on a rpi2, with stock armhf Ubuntu 14.04 & docker 1.6.2: docker run -it --net=host --name bletest armv7/armhf-ubuntu bash docker run -it --privileged --net=host --name bletest armv7/armhf-ubuntu bash
@herver MANY THANKS
@TeoTN I was able to get this working inside docker swarm, in a service…
docker service create --name mi_atc_reader --cap-add NET_ADMIN --network host mi_atc_reader
(refer to https://github.com/AdysTech/mi_atc_reader)I’ve found out the hard way that
--net host
or rathernetwork_mode: host
doesn’t work with Docker Swarm. Is there any way to access Bluetooth from within docker swarm containers?Hey guys, I created a bluetooth docker image. I can get bluetooth to work inside of python3 with bluez.
https://hub.docker.com/r/don41382/rpi-python3-with-bluetooth/
Cheers Felix
@marcoh00 , can you also look at
bluepy
, specifically at https://github.com/IanHarvey/bluepy from @ianharvey andbluepy-helper
https://github.com/IanHarvey/bluepy/blob/master/bluepy/bluepy-helper.c which is a little C program that interfaces with Bluetooth? There might be a reasonable way to proxy that through to a container.