Вы пропускаете процессы зомби.
Когда вы запускаете в контейнере Docker, ваш процесс имеет идентификатор процесса 1. Это означает, что если что-то внутри контейнера будет убито, а его родитель исчезнет (например,поскольку он сделал двойной ответвление, чтобы стать процессом-демоном), ваш процесс становится его новым родителем, и вы несете ответственность за wait (2) его. Когда вы этого не делаете, вы получаете зомби-процессы, подобные этому.
Один немедленный ответ может быть на os.waitpid(-1, 0)
после того, как вы выполните команду "kill". Это заставит вас ждать следующего, что выйдет, и выполнить необходимую очистку.
Хотя было бы чище не пытаться выполнить эту очистку настолько косвенно. Вместо того, чтобы запускать подпроцесс в качестве демона и пытаться очистить его позже, вы можете использовать subprocess.Popen()
для создания процесса. Вы можете запустить процесс "на переднем плане", но не блокировать его завершение в процессе Python. Это будет выглядеть примерно так:
vpn = subprocess.Popen(["/usr/sbin/openvpn", "--config", config_file])
...
vpn.kill()
vpn.wait()
Если вы можете разделить вещи так, чтобы эти два элемента работали в отдельных контейнерах, что было бы еще лучше;тогда вы можете избежать этой проблемы управления.
(... что происходит, когда config_file = "/dev/null; cat /etc/shadow"
? Попробуйте избегать использования команд строковой формы, таких как os.system()
, если это вообще возможно.)