首页 > 解决方案 > 如何解决 exceptions.OSError: [Errno 1] Operation not allowed (docker container)?

问题描述

我正在尝试使用bluepy扫描 BLE 设备。我的scan.py代码是——

from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate(DefaultDelegate):
    def __init__(self):
        DefaultDelegate.__init__(self)

    def handleDiscovery(self, dev, isNewDev, isNewData):
        if isNewDev:
            print "Discovered device", dev.addr
        elif isNewData:
            print "Received new data from", dev.addr

# prepare scanner
scanner = Scanner().withDelegate(ScanDelegate())

# scan for 5 seconds
devices = scanner.scan(5.0)

for dev in devices:
    print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)
    for (adtype, desc, value) in dev.getScanData():
        print "  %s = %s" % (desc, value)

根据文档(最后作为注释提到)-

(1) LE scanning must be run as root

这意味着我们需要使用sudo. 我运行它 -

sudo python scan.py

基本上bluepy-helper需要sudo扫描。需要设置blupe-helper的功能才能在没有sudo. 根据解决方案,我做了-

sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python2.7/site-packages/bluepy/bluepy-helper

现在从终端运行扫描代码,无需sudo像 --

python scan.py

最后,我做了一个 Dockerfile——

FROM arm32v7/python:2.7.15-jessie
WORKDIR /usr/app/gfi_ble
COPY . /usr/app/gfi_ble
RUN chmod 755 ./setcap_for_bluepy_helper.sh
RUN pip install -r requirements.txt
CMD ["./setcap_for_bluepy_helper.sh", "--", "python", "src/scan.py"]

setcap_for_bluepy_helper.sh的内容是——

#!/bin/bash
cmd="$@"
>&2 setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python2.7/site-packages/bluepy/bluepy-helper
exec $cmd

图像已成功创建,但是当我运行容器时,出现如下错误 -

Creating con_gfi_ble ... done
Attaching to con_gfi_ble
con_gfi_ble | 2019-01-12 23:06:24+0000 [-] Unhandled Error
con_gfi_ble |   Traceback (most recent call last):
con_gfi_ble |     File "/usr/app/gfi_ble/src/scan.py", line 17, in new_devices
con_gfi_ble |       devices = scanner.scan(5.0)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 852, in scan
con_gfi_ble |       self.start(passive=passive)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 789, in start
con_gfi_ble |       self._startHelper(iface=self.iface)
con_gfi_ble |     File "/usr/local/lib/python2.7/site-packages/bluepy/btle.py", line 284, in _startHelper
con_gfi_ble |       preexec_fn = preexec_function)
con_gfi_ble |     File "/usr/local/lib/python2.7/subprocess.py", line 394, in __init__
con_gfi_ble |       errread, errwrite)
con_gfi_ble |     File "/usr/local/lib/python2.7/subprocess.py", line 1047, in _execute_child
con_gfi_ble |       raise child_exception
con_gfi_ble |   exceptions.OSError: [Errno 1] Operation not permitted
con_gfi_ble | 

问题: exceptions.OSError: [Errno 1] Operation not allowed 是什么意思?

当我从终端运行它时,我的代码很好。容器有什么问题?任何想法!

标签: dockerbluetooth-lowenergycontainersdockerfile

解决方案


Docker 容器以减少的功能运行。这可以防止容器内的 root 通过运行没有命名空间的内核命令以及访问容器外部的主机部分(如原始网络接口或物理设备)来逃避容器。如果需要,您需要在外部向容器添加功能,但请理解这会降低 docker 的默认设置提供的安全性。

docker run,这看起来像:

docker run --cap-add=NET_ADMIN --cap-add=NET_RAW ...

https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

在撰写文件中,这看起来像:

version: '2'

services:
  app:
    image: your_image
    cap_add:
      - NET_ADMIN
      - NET_RAW

参考:https ://docs.docker.com/compose/compose-file/

这不适用于群模式。正在进行工作以增加在集群模式下运行具有附加功能的命令的能力。如果您需要,有一些丑陋的解决方法。

请注意,您不应该sudo在容器内运行。这样做意味着一切都可以将自己提升为 root 并且违背了以用户身份运行任何东西的目的。相反,您应该以 root 身份启动容器并尽快将其放入普通用户,这是一种单向操作。


推荐阅读