Docker - перезагрузка хоста raspberry pi из контейнера докера - PullRequest
2 голосов
/ 26 марта 2019

У меня есть приложение на Python, которое должно быть запущено на Raspberry Pi.Я создал файл docker-compose, чтобы настроить его, и моей точкой входа является сценарий оболочки, который проверяет различные вещи на хосте, такие как:

  1. Убедитесь, что SPI включен, еслизатем он не включается, открывая /boot/config.txt и записывая в него.
  2. Установка и включение службы наблюдения.
  3. Автоматический запуск моего док-контейнера при перезагрузке путем записи его в /etc / rc.local (хотя я подумываю заменить его перезапуском: всегда или если-остановлен флаг из файла docker-compose)

Проблема заключается в том, что если я включу SPI, то raspberry piМне нужно перезагрузить компьютер, чтобы настроить его (не совсем понятно почему), но когда мой сценарий оболочки достигает команды sudo reboot из контейнера Docker, я получаю следующую ошибку:

 Failed to connect to bus: No such file or directory
 Failed to talk to init daemon.

Я понимаю, что это, вероятно,пытается найти dbus и демон init в контейнере docker, но они не существуют.Как мне предоставить контейнеру доступ к этим ресурсам?Нужно ли монтировать другой том?Это мой файл docker-compose.yml:

version: "3"

services:
    mongoDB:
        restart: unless-stopped
        volumes:
            - "/data/db:/data/db"
        ports:
            - "27017:27017"
            - "28017:28017"
        image: "andresvidal/rpi3-mongodb3:latest"
    mosquitto:
        restart: unless-stopped
        ports:
            - "1883:1883"
        image: "mjenz/rpi-mosquitto"
    FG:
        privileged: true
        network_mode: "host"
        depends_on:
            - "mosquitto"
            - "mongoDB"
        volumes:
            - "/home/pi:/home/pi"
            - "/boot:/boot"
        #image: "arkfreestyle/fg:v1.8"
        image: "test:latest"
        entrypoint: /app/docker-entrypoint.sh
        restart: unless-stopped

FG - это мое приложение на python с точкой входа docker-entrypoint.sh, которое выглядит так:

#!/bin/sh
if [ ! -f /home/pi/.initialized ]; then                                                                                                                                                                                    
    echo "Initializing..."                                                                                                                                                                                

    # Turn spi on
    if grep -Fxq "dtparam=spi=on
dtparam=watchdog=on" /boot/config.txt
    then
        echo "\nSPI is already enabled"
        echo "Creating .initialized"
        # Create .initialized hidden file
        touch /home/pi/.initialized
        echo "Starting application..."
        sudo python3 __main__.py -debug
    else
        ### Enable SPI ###
    fi
    fi

    ### Create .initialized file ### 
    echo "Rebooting in ten seconds..."
    sleep 10
    sudo reboot # This line results in the error

else
    echo "Initialized already!"
    sudo python3 __main__.py -debug                                                                                                                                                                                     
fi       

Уже привилегированная опциядает моему контейнеру доступ к GPIO, я подумал, что это даст мне и перезагрузку, но, похоже, это не так.Пожалуйста, дайте мне знать, что мне нужно сделать, чтобы перезагрузить компьютер.

1 Ответ

2 голосов
/ 26 марта 2019

Мое первое предположение состоит в том, что вам просто нужно выставить /run/dbus и /run/systemd для вашего контейнера, как в:

docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd ...

Но хотя это необходимо, этого недостаточно;только с этими двумя подключенными монтировками попытка взаимодействия с хостом systemd изнутри контейнера приводит к:

[root@631fff40f09c /]# reboot
Failed to connect to bus: No data available
Failed to talk to init daemon.

Оказывается, что для того, чтобы это работало, контейнер должен работать на хостеглобальное пространство имен PID, что означает, что нам нужно:

docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd --pid=host ...

С этим, выполнение reboot внутри контейнера успешно перезагружает хост.

В docker-compose.yml это выглядело бычто-то вроде:

FG:
    privileged: true
    network_mode: "host"
    pid: "host"
    depends_on:
        - "mosquitto"
        - "mongoDB"
    volumes:
        - "/home/pi:/home/pi"
        - "/boot:/boot"
        - "/run/dbus:/run/dbus"
        - "/run/systemd:/run/systemd"
    image: "test:latest"
    entrypoint: /app/docker-entrypoint.sh
    restart: unless-stopped
...