您如何使用Ansible确认服务是否在特定端口上运行?
例如:
我知道有service
和wait_for
命令,它们分别检查服务是否正在运行以及是否正在使用某个端口 - 但我到目前为止还没找到任何内容检查特定服务是否正在侦听特定端口。 service
和wait_for
将表明服务和端口,但不保证该端口被该特定服务占用 - 它可以被任何东西占用。 wait_for
,据我所知,只是检查它是否被使用。
regex_search
上有一个wait_for
参数,它提到在套接字连接中搜索特定字符串,但据我所知,这只是读取该套接字下的任何信息而不是任何信息。访问发送该信息的内容。
我们怎么能这样做?
答案 0 :(得分:5)
有几种方法可以解释您的问题,因此我将尝试回答这两个问题:
如果您的目标是验证特定端口是否正在为特定应用程序协议提供服务,我会通过运行适当的客户端来检查这一点。
为了检查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
如果您想检查特定的流程ID,可以使用lsof
:
- name: check that pid {{apache_pid}} is listening on port 80
shell: lsof -p 1036 -P | grep 'TCP \*:80'
但同样,我并不一定认为这些选项特别有用。前面部分中的服务检查似乎更合适。
答案 1 :(得分:2)
在ansible中没有内置模块可以验证端口和服务的组合。您可能需要做的是找出对netstat之类命令的适当调用,并通过command或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调用的shell脚本,并在将结果返回到ansible之前对输出进行更详细的解析/验证。但是,您需要在调用之前安装该脚本。
答案 2 :(得分:2)
AFAIK没有内置模块可以做到这一点。使用shell模块或编写执行所有检查的小shell命令可能是微不足道的。
您可以使用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
答案 3 :(得分:2)
也许你用错误的方法看待这个问题。
您可以使用配置管理系统(如Ansible)对系统进行更改,但是您可以使用Serverspec
之类的内容来确保正确的进程正在侦听正确的端口。
此外,您的剧本应该以这样的方式构建,即您不会处于不同的服务可能在同一端口上侦听的模糊情况。