Debian systemd network-online.target не работает?

24

Я пытаюсь создать системный сервис на Debian Jessie. Мне нужно, чтобы начать после network-online.targetдостижения.

Проблема в том, что происходит network-online.targetпожар, в то время как network.targetмои интерфейсы еще не настроены, просто запущен запрос DHCP.

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

Как обойти эту проблему или как заставить network-online.targetработать?

10robinho
источник
Какой выход systemctl list-dependencies network-online.target? Также обратите внимание, что network-online.targetнеобязательно означает, что есть доступ в Интернет. Смотрите эту страницу для получения дополнительной информации.
saiarcot895
Вывод команды: network-online.target ● └─systemd-networkd-wait-online.service я уже прочитал эту страницу, я понимаю основную концепцию там, но все же очень странно не иметь определенной точки, где могут запускаться критически важные для сети службы. По крайней мере, он может ждать правильного назначения DHCP.
10robinho
Это означает, что network-online.targetзависит только от systemd-networkd-wait-online.serviceвысказывания, что оно готово. Это не зависит от того, что NetworkManager говорит, что он готов, и не проверяет, что ifupвсе ссылки были успешно запущены (если вы используете этот метод для настройки сети). Ubuntu, с другой стороны, зависит от ifupNetworkManager, но не от systemd-networkd-wait-online..
saiarcot895
Как вы конфигурируете свою сеть: /etc/network/interfacesсистемные .networkфайлы или NetworkManager?
saiarcot895
Вы правы, network-online.targetи network.targetсрабатывают сразу после ifup. Я использую Debian по умолчанию, поэтому /etc/network/interfacesс адресом DHCP. Похоже, что networkd может быть лучшим решением, но это не так просто реализовать.
10robinho

Ответы:

18

Поскольку вы используете /etc/network/interfaces, вам понадобится сервис systemd для контроля состояния каждого интерфейса. Проверьте, есть ли у вас /lib/systemd/system/ifup-wait-all-auto.service(установленный ifupdownпакет в Ubuntu 15.04). Если нет, то создайте /etc/systemd/system/ifup-wait-all-auto.serviceи вставьте следующее:

[Unit]
Description=Wait for all "auto" /etc/network/interfaces to be up for network-online.target
Documentation=man:interfaces(5) man:ifup(8)
DefaultDependencies=no
After=local-fs.target
Before=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=2min
ExecStart=/bin/sh -ec '\
  for i in $(ifquery --list --exclude lo --allow auto); do INTERFACES="$INTERFACES$i "; done; \
  [ -n "$INTERFACES" ] || exit 0; \
  while ! ifquery --state $INTERFACES >/dev/null; do sleep 1; done; \
  for i in $INTERFACES; do while [ -e /run/network/ifup-$i.pid ]; do sleep 0.2; done; done'

[Install]
WantedBy=network-online.target

Это служебный файл, представленный в системе Ubuntu 15.04, но с [Install]добавленным разделом, чтобы немного упростить процесс . Я надеюсь, что поведение ifupв Ubuntu 15.04 такое же, как ifupв Debian Jessie. Если нет, то некоторые изменения будут необходимы (особенно с последней строкой).

Тогда беги sudo systemctl enable ifup-wait-all-auto.service. После перезагрузки компьютера вы должны увидеть, что network-online.targetоно достигнуто после включения интерфейсов (по крайней мере).

saiarcot895
источник
Спасибо за усилия, позвольте мне попробовать это сейчас, и я дам вам обратную связь
10robinho
Я закончил тем, что бежал немного измененная версия ExecStart = /bin/bash -c 'while [ -z "$(hostname -I)" ]; do sleep 1; done;'. Это зависит от того, hostnameчтобы проверить, был ли назначен IP-адрес.
luka5z
Не пытайся спина доктор это. это не потому, что он использует / etc / network / interfaces. Это потому, что systemd настолько небрежен, и работа передается каждому пользователю вместо решения проблемы, в которой он был создан.
Флориан Хейгл
1
Кстати, ifup-wait-all-auto.serviceв ifupdownверсии было удалено 0.8.5ubuntu1: «Drop ifup-wait-all-auto.service. Это было реализовано более элегантно, сделав network-online.target Wants =
network.service
0

Внимание! Только что выяснил это на распбианской Джесси: удалите ВСЕ закомментированные строки в / etc / network interfaces, и это будет работать! Кажется, это ошибка синтаксического анализа =) В моем конкретном случае я оставил комментарий iface eth0 inet dhcpи просто забыл об этом несколько лет назад, но после обновления до Raspbian Jessie и перестройки ядра у меня появилось очень странное поведение: он использовал DHCP и отказался сделать настройку из / etc / network / interfaces. Так что я удалил это из любых комментариев - просто рабочие строки, перезагрузка - и это работает! НЕ ТРЕБУЕТСЯ ЗАПИСЬ / РЕДАКТИРОВАНИЕ СКРИПТА!

Алексей Веснин
источник
Интересно, мне нужно попробовать это. Хотя это не имеет особого смысла :)
10robinho
2
Есть ли у вас какие-либо ссылки по этому поводу? Я хотел бы прочитать сообщения об ошибках и увидеть код ошибки.
ɈsәɹoɈ
Нет, я не открыл билет на ошибку. Чтобы воспроизвести его, просто добавьте несколько комментариев в ваш /etc/network/interfacesфайл - он запустится, если он все еще там.
Алексей Веснин
0

Согласно https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ рекомендуемый способ запуска службы ПОСЛЕ сетевого подключения - это использовать « network-online.target » в файле .service :

 "After=network-online.target"
 "Wants=network-online.target"

Однако после использования « network-online.target » и сбоя моего сервиса из-за того, что работа в сети была не на полном уровне, я обнаружил, что есть ошибка ( https://github.com/coreos/bugs/issues/1966 ) с ней: не гарантируется быть на 100% непогрешимым.

Действительно, когда используются инструменты динамической настройки сети, такие как « NetworkManager », как в этом случае, состояние сети никогда не может быть на 100% точным или предсказуемым. Как видно из ссылки, описывающей ошибку, « network-online.target » может вести себя непоследовательно в зависимости от различных приложений, с которыми он используется.

Обходной путь :
Вам нужно проанализировать порядок запуска услуг и использовать тот, который запускается позже, чем « network-online.target »:

 systemd-analyze plot > /home/pi/graph.svg

Это итеративный процесс, меняющий цели постепенно на более поздние и поздние сервисы, пока вы не найдете тот, который обеспечивает уровень сети и ваша служба запускается без ошибок. В моем собственном случае мне даже пришлось вставить sleep 10в мой скрипт службу SystemD.

F1Linux
источник
0

Однажды я нашел ответ на Github, который решил эту проблему, постоянно пытаясь пропинговать сервер. Только когда пинг проходит, сервис продолжается:

[Service]
ExecStartPre=/bin/sh -c 'until ping -c1 google.com; do sleep 1; done;'
ExecStart=<your command>

Я заменил google.comсвой собственный сервер, потому что мой основной сценарий должен был подключиться к моему серверу.

Сэм
источник