Ansible: Проверьте, прослушивает ли служба определенный порт

как бы вы могли использовать Ansible для подтверждения того, работает ли служба на определенном порту?

например:

  • работает ли Apache на порту 80?
  • MySQL прослушивает порт 3912?
  • слушает ли Tomcat порт 8080?

Я понимаю, что есть service и wait_for команды, которые индивидуально проверяют, работает ли служба и используется ли порт , но я ничего не нашел далеко, чтобы проверить, прослушивает ли конкретная служба определенный порт. service и wait_for укажет, что есть служба и порт, но нет никакой гарантии, что порт взят этой конкретной службой - он может быть взят чем угодно. wait_for, Как я понимаю, просто проверяет, используется ли он.

есть regex_search параметр on wait_for который упоминает поиск в соединении сокета для определенной строки, но, как я понимаю, это просто чтение любого информация, которая поступает в этот сокет, а не имеет доступа к тому, что отправляет эту информацию.

как мы можем это сделать?

4 ответов


есть несколько способов интерпретации вашего вопроса, поэтому я попытаюсь ответить на них обоих:

проверка сетевой службы

если ваша цель-проверить, что определенный порт обслуживает определенный протокол приложения, я бы проверил это, запустив соответствующий клиент.

  • для проверки Apache и Tomcat, я бы GET определенный url и проверьте код результата. Например:

    - name: check if apache is running
      command: curl -sf http://webserver/check_url
    

    и аналогично для Tomcat.

  • для проверки MySQL я бы использовал клиент MySQL:

    - name: check if mysql is running
      command: mysql -h dbhost -P dbport -e 'select 1'
    

проверка того, какой процесс владеет сокетом

если вы действительно хотели посмотреть, что процесс держал определенный порт открыт, я думаю, вы могли бы объединить ss и grep, но это кажется странным и ненужным. Что-то вроде:

    - name: check if httpd has port 80 open
      shell: ss -tp state listening sport = :80 | grep httpd

если вы хотите проверить конкретный идентификатор процесса, вы можете так что-то похожее с lsof:

    - name: check that pid {{apache_pid}} is listening on port 80
      shell: lsof -p 1036 -P | grep 'TCP \*:80'

но опять же, я не обязательно считаю эти варианты особенно полезными. Проверки службы в предыдущем разделе, по-видимому, более уместны.


в ansible нет встроенного модуля, который проверит комбинацию порта и службы. Вероятно, вам нужно будет выяснить соответствующий вызов команды, такой как netstat, и вызвать ее через команда или shell модули. Например, в окне linux следующая команда покажет вам, какой процесс прослушивает порт 80:

$ netstat -tunlp | grep ":80 " | sed -e 's/.*\///'
httpd

поэтому из Ansible вы, вероятно, захотите сделать что-то вроде это:

- name: Get service on port 80
  shell: netstat -tunlp | grep ":80 " | sed -e 's/.*\///'
  register: results

- name: See what netstat returned
  debug: var=results

Если вы хотите быть немного увлекательнее, вы можете написать сценарий оболочки, который инкапсулирует вызов netstat и выполняет более подробный разбор/проверку вывода, прежде чем возвращать результаты в ansible. Но тогда вам нужно будет установить этот скрипт до его вызова.


AFAIK нет встроенного модуля, который делает это. Вероятно, это тривиально сделать с помощью модуля оболочки или написать небольшую команду оболочки, которая выполняет все проверки.

можно использовать fuser команда для проверки того, какой процесс прослушивает данный TCP-порт:

$ sudo fuser -n tcp 80
80/tcp:              20031 20080 20081

можно использовать ps чтобы увидеть название процесса:

$ ps hp 20031,20080,20081 -o comm
apache2
apache2
apache2

сочетает в себе все:

$ ps hp `fuser -n tcp 80 2> /dev/null | cut -d ' ' -f 2` -o comm
apache2

$ ps hp `fuser -n tcp 80 2> /dev/null | cut -d ' ' -f 2` -o comm | grep apache2 -q
$ echo $?  # should be 0 if apache2 is listening on port 80
0

вы смотрите на эту проблему с неправильным подходом. Вы бы использовали системы управления конфигурацией (например, Ansible) для внесения изменений в свою систему, но вы бы использовали что-то вроде Serverspec чтобы убедиться, что правильные процессы прослушивают правильные порты. Кроме того, ваши playbooks должны быть сконструированы таким образом, чтобы вы никогда не находились в двусмысленной ситуации, когда разные службы могут прослушивать одни и те же порты.