实验环境
centos7.4
主机名称
IP
配置
用途
controlnode
172.16.1.120
1核/1G/60G
ansible
slavenode1
172.16.1.121
1核/1G/60G
被管理主机
slavenode2
172.16.1.122
1核/1G/60G
被管理主机
第
1 章
• 节省时间,提高工作效率
• 消除重复任务
• 更少的错误风险
• 改善协作和工作满意度
• 克服复杂性
• 更多创新资源
• 加强问责制和合规性
Ansible是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署,滚动更新。Ansible适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
第 2 章
在172.16.1.120节点上操作
• Python2.6/2.7/3.x
• RedHat,Debian,CentOS,OSX等。不支持Windows
• OpenSSH
• Python2.6/2.7/3.x
• yum
install ansible -y (推荐)
• pip
install ansible
• https://releases.ansible.com/ansible or
https://github.com/ansible/ansible.git
# vi
/etc/ansible/ansible.cfg
[defaults]
默认配置项
inventory
= /etc/ansible/hosts
# 远程主机清单
forks =
15
# 执行并发数,默认5
sudo_user =
root
# ssh远程主机sudo 提权到的用户
remote_port = 22
# ssh远程主机的端口号
host_key_checking = False
# 禁用SSH密钥主机检查。
timeout =
30
# 执行超时时间,默认10s
log_path =
/var/log/ansible.log
# 日志路径
private_key_file = /root/.ssh/id_rsa
基于密钥方式连接远程主机的本地密钥路径
如果设置,则始终使用此私钥文件进行身份验证。
清单列表密钥路径
> private_key_file > 执行ansible用户的密钥路径
说明:
1)
如果未开启host_key_checking =
False选项会报如下错误
# /etc/ansible/hosts
示例1:未分组的主机
green.example.com
blue.example.com
192.168.100.1
192.168.100.10
# 示例2:属于webservers组主机集合
[webservers]
alpha.example.org
beta.example.org
192.168.1.100
192.168.1.110
www[001:006].example.com
表示www001.example.com到www006.example.com的主机
示例3:属于dbservers组主机集合
[dbservers]
db01.intranet.mydomain.net
db02.intranet.mydomain.net
10.25.1.56
10.25.1.57
db-[99:101]-node.example.com
主机和主机组变量(主机变量优先级大于主机组变量)
vim /etc/ansible/hosts
[webservers]
172.16.1.121:22 ansible_ssh_user=root
ansible_ssh_pass='123456' http_port=80
172.16.1.122:22 ansible_ssh_user=root
ansible_ssh_pass='123456'
[webservers:vars]
http_port=8080
server_name=www.baidu.com
实验:
ansible
webservers -m command -a "echo {{http_port}}" -o
ansible webservers -m command -a
"echo {{server_name}}" -o
命令说明:
ansible webservers -m command -a
"echo {{http_port}}" -o
ansible:ansible命令
webservers:/etc/ansible/hosts中配置的主机组名称,指定 all (分组和未分组的主机)代表所有主机,指定172.16.1.121代表单台主机。
-m:指定使用的模块,默认是command模块(简单的shell命令),可以省略不写。
-a:指定具体使用的shell指令,比如"echo
{{http_port}}"表示在远程主机上打印http_port这个变量。
-o:对ansible的输出的结果进行压缩(即,输出的结果显示在一行)。
组变量分解到单个文件(文件名和inventory中配置的主机组名一致,并且以.yml结尾)
mkdir -p
/etc/ansible/group_vars/
vim
/etc/ansible/group_vars/webservers.yml
http_port:
8080
server_name: www.baidu.com
ansible常用命令
ansible:ansible指令
ansible-doc:ansible帮助命令,后接模块名称
ansible-playbook:ansible剧本
第 3 章
在172.16.1.120节点上操作。
ad-hoc指在linux终端上直接使用ansible命令,执行临时命令,不会记录任何操作记录。
inventory中配置的连接远端主机的用户名、密码或密钥,优先级最高。
格式:ansible< host-pattern> [
options ]
选项:
-a MODULE_ARGS,
--args=MODULE_ARGS
模块参数
-C, --check
运行检查,不执行任何操作
-e EXTRA_VARS,
--extra-vars=EXTRA_VARS
设置附加变量 key=value
-f FORKS,
--forks=FORKS
指定并行进程数量,默认5
-i INVENTORY,
--inventory=INVENTORY
指定主机清单文件路径
--list-hosts
输出匹配的主机列表,不执行任何操作
-m MODULE_NAME,
--module-name=MODULE_NAME
执行的模块名,默认command
--syntax-check
语法检查playbook文件,不执行任何操作
-t TREE, --tree=TREE
将日志输出到此目录
-v,
--verbose
详细信息,-vvv更多, -vvvv debug
--version
查看程序版本
连接选项:控制谁连接主机和如何连接
-k, --ask-pass
请求连接密码
--private-key=PRIVATE_KEY_FILE,
--key-file=PRIVATE_KEY_FILE
私钥文件
-u REMOTE_USER,
--user=REMOTE_USER
连接用户,默认None。
-T TIMEOUT,
--timeout=TIMEOUT
覆盖连接超时时间,默认10秒
提权选项:控制在目标主机以什么用户身份运行
-b,
--become
以另一个用户身份操作
--become-method=BECOME_METHOD
提权方法,默认sudo
--become-user=BECOME_USER
提权后的用户身份,默认root
-K,
--ask-become-pass
提权密码
vim
/etc/ansible/hosts
[webservers]
172.16.1.121:22 ansible_ssh_user=root
ansible_ssh_pass='123456'
172.16.1.122:22 ansible_ssh_user=root
ansible_ssh_pass='123456'
ssh-keygen
一直回车完成密钥对的创建
ssh-copy-id
root@172.16.1.121
ssh-copy-id root@172.16.1.122
发送公钥到被管理主机
vim
/etc/ansible/hosts
[webservers]
172.16.1.121:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
172.16.1.122:22 ansible_ssh_user=root
在/etc/ansible/ansible.cfg中配置了private_key_file =
/root/.ssh/id_rsa,
不指定ansible_ssh_key=/root/.ssh/id_rsa也可,如果指定会覆盖配置。
# 生产环境中推荐使用ssh密钥对认证,下面的实验都是基于ssh密钥对做的。
第 4 章
1
shell模块
-m
command 模块不支持
"&&、||、>>、>"等特殊符号,只能执行一些简单的shell命令,如果想要执行一些复杂的命令需要使用 -m
shell 模块。
2
ansible 进行sudo提权
(1)
在172.16.1.120节点上操作
1)
配置主机清单
vim /etc/ansible/hosts
[webservers]
172.16.1.121:22
ansible_ssh_user=user ansible_ssh_key=/root/.ssh/id_rsa
172.16.1.122:22
ansible_ssh_user=user ansible_ssh_key=/root/.ssh/id_rsa
2)
发送root用户的公钥分别到172.16.1.121、172.16.1.122节点的user用户下
ssh-copy-id user@172.16.1.121
ssh-copy-id user@172.16.1.122
(2)
分别在172.16.1.121和172.16.1.122节点上进行操作
1)
创建user用户
useradd user
echo "user" | passwd --stdin user
2)
sudo提权
visudo
user ALL=(ALL) NOPASSWD:
ALL
(3)
测试
在172.16.1.120节点上进行操作
ansible webservers -m shell -a "ls /root/" --become
--become-user root -o
(4)
补充
如果inventory中指定远程主机的形式为<主机IP>:
ALL
那么使用如下命令可进行普通用户的提权操作。
ansible webservers -m shell -a "ls /root/" -u user -k --become --become-user
root -K -o
1
copy
ansible webservers -m copy -a "src=/root/anaconda-ks.cfg dest=/tmp/"
-o
2
file
ansible webservers -m file -a "dest=/root/lc_dir state=directory"
-o
"value of state must be one of: absent, directory, file, hard, link,
touch"
ansible webservers -m yum -a "name=httpd state=present" -o
"value of state must be one of: absent, installed, latest, present,
removed"
1
user
ansible webservers -m user -a "name=foo password=liuchang.com state=present"
-o
"value
of state must be one of: absent, present"
2
group
ansible webservers -m group -a "name=bee state=present" -o
"value
of state must be one of: absent, present"
1
安装git软件包
ansible webservers -m yum -a "name=git state=present" -o
2
拉去源代码到本地
ansible webservers -m git -a "repo=https://github.com/ansible/ansible.git
dest=/tmp/ansible/" -o
说明:目标目录必须是一个空目录,如果不存在会自动创建。
ansible webservers -m service -a "name=httpd state=started"
-o
"value of state must be one of: reloaded, restarted, started,
stopped"
ansible webservers -m service -a "name=httpd enabled=true" -o
"Valid
booleans include: 0, 'on', 'f', 'false', 1, 'no', 'n', '1', '0', 't', 'y',
'off', 'yes', 'true'"
ansible webservers -m setup -a "filter=ansible_nodename"
常用过滤选项:
ansible_nodename #
主机名
ansible_os_family #
操作系统
ansible_pkg_mgr # 包管理软件名称
ansible_processor # 处理器信息
ansible_processor_cores #
处理器的核数
第 5 章
在172.16.1.120节点上进行操作
特点
• 易读的编排语言
• 适合配置管理和应用部署
• 非常适合部署复杂的工作
2.1 自动部署Nginx
cat /root/nginx.yml
---
-
hosts: webservers
gather_facts:
no
vars:
hello:
Ansible
tasks:
-
name: Add repo
yum_repository:
name: nginx
description: nginx repo
baseurl:
http://nginx.org/packages/centos/7/$basearch/
gpgcheck: no
enabled: 1
-
name: Install nginx
yum:
name: nginx
state: latest
-
name: Copy nginx configuration file
copy:
src: ./site.conf
dest: /etc/nginx/conf.d/site.conf
-
name: Start nginx
service:
name: nginx
state: restarted
-
name: Create wwwroot directory
file:
dest: /var/www/html
state: directory
-
name: Create test page index.html
shell:
echo "hello {{hello}}" > /var/www/html/index.html
2.2 检测语法
ansible-playbook nginx.yml --syntax-check
2.3 nginx站点配置
cat /root/site.conf
server
{
listen
80;
server_name
www.liuchang.com;
location
/ {
root /var/www/html;
index index.html;
}
}
2.4
ansible-playbook执行及测试访问
1
执行ansible-playbook
ansible-playbook nginx.yml
2
访问测试网站
curl 172.16.1.121 -H "Host:www.liuchang.com"
hello
Ansible
• 缩进表示层级关系
• 不支持制表符“tab”缩进,使用空格缩进
• 通常开头缩进 2 个空格
• 字符后缩进 1 个空格,如冒号、逗号等
• “---” 表示YAML格式,一个文件的开始
• “#”注释
---
-
name: play1
hosts: webservers
gather_facts: no
remote_user: root
vars:
var_name:
value
tasks:
-
name: echo
shell: "echo {{var_name}}"
-
name: play2
hosts: webservers
gather_facts: no
remote_user: root
vars:
var_name:
value
tasks:
-
name: echo
shell: "echo {{var_name}}"
---
- hosts: webservers
gather_facts:
no
remote_user:
root
vars:
var_name:
value
tasks:
- name:
echo
shell:
"echo {{var_name}}"
notify:在任务结束时触发
handlers:由特定条件触发Tasks,handlers:
与 tasks:
对齐
cat nginx_handler.yml
---
-
hosts: webservers
gather_facts: no
tasks:
-
name: Copy nginx configuration file
copy:
src: ./site.conf
dest: /etc/nginx/conf.d/site.conf
notify:
- restart nginx
handlers:
-
name: restart nginx
service:
name=nginx state=reloaded
1
playbook文件
cat redis_tags.yml
---
-
hosts: webservers
gather_facts: no
tasks:
-
name: Install redis
yum: name=redis state=present
tags: install
-
name: Copy redis configuration file
copy: src=redis.conf
dest=/etc/redis/redis.conf
tags: configuration
-
name: Restart redis
service: name=redis state=restarted
tags: restart
2
执行指定的tags
ansible-playbook redis_tags.yml --tags "install,restart"
3
跳过指定的tags
ansible-playbook redis_tags.yml --skip-tags "configuration"
1
语法检查:ansible-playbook
main.yml --syntax-check
debug:
只能存在一个单独的任务中,该任务中无其它的命令。
2
打印语句
cat ansible_debug.yml
---
-
hosts: webservers
gather_facts: yes
vars:
server_name:
www.liuchang.com
tasks:
-
name: test1
debug:
msg="{{server_name}}"
-
name: test2
debug:
msg:
- "{{inventory_hostname}}"
-
"{{ansible_hostname}}"
cat tomcat.yml
---
-
hosts: webservers
gather_facts: no
vars:
tomcat_version:
8.5.58
tomcat_install_dir:
/usr/local
tasks:
-
name: Install jdk1.8
yum: name=java-1.8.0-openjdk
state=present
-
name: Download tomcat
get_url:
url=http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v{{ tomcat_version
}}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz dest=/tmp
-
name: Unarchive tomcat-{{ tomcat_version }}.tar.gz
unarchive:
src: /tmp/apache-tomcat-{{
tomcat_version }}.tar.gz
dest: "{{ tomcat_install_dir
}}"
copy: no
-
name: Start tomcat
shell: cd {{ tomcat_install_dir }}
&&
mv apache-tomcat-{{ tomcat_version
}} tomcat8 &&
cd tomcat8/bin&& nohup
./startup.sh &
第 6 章
playbook变量使用的优先级:
命令行变量( -e )>
playbook变量 > inventory主机变量 >
inventory组变量
1
playbook 文件
cat var.yml
---
-
hosts: webservers
gather_facts: no
vars:
var_name1:
value1
var_name2:
value2
tasks:
-
name: line_var
debug: msg="{{server_names}}"
-
name: playbook_var
shell: echo {{var_name1}}&&
echo
{{var_name2}}
2
测试
ansible-playbook var.yml -e server_names=www.souhu.com
将一个任务运行后返回的值写入到变量中,方便下一个任务使用。
cat register.yml
---
-
hosts: webservers
gather_facts: no
tasks:
-
name: Get date
command: date +"%F_%T"
register: datetime
-
name: Echo datetime
file: dest=/tmp/{{datetime.stdout}}
state=touch
-
name: Echo datetime Debug
debug: msg="{{datetime.stdout}}"
1
playbook文件
cat system_info.yml
---
-
hosts: webservers
gather_facts: yes
tasks:
-
name: Get hostname
debug:
msg:
-
"{{ansible_hostname}}"
-
"{{inventory_hostname}}"
2
查看执行结果
ansible-playbook system_info.yml
第 7 章
include*(动态):在运行时导入
• --list-tags,--list-tasks不会显示到输出
• 不能使用notify触发来自include*内处理程序名称(handlers)
import*(静态):在Playbook解析时预先导入
• 不能与循环一起使用
• 将变量用于目标文件或角色名称时,不能使用inventory(主机/主机组等)中的变量
1
# cat lnmp.yml
---
-
import_playbook: nginx.yml
-
import_playbook: mysql.yml
-
import_playbook: php.yml
2
# cat nginx.yml
---
-
name: INSTALL NGINX
hosts: webservers
gather_facts: no
tasks:
-
name: Install nginx
debug: msg="install nginx …"
3
# cat mysql.yml
---
-
name: INSTALL MYSQL
hosts: webservers
gather_facts: no
tasks:
-
name: Install mysql
debug: msg="install mysql …"
4
# cat php.yml
---
-
name: INSTALL PHP
hosts: webservers
gather_facts: no
tasks:
-
name: Install php
debug: msg="install php …"
5
查看执行结果
ansible-playbook lnmp.yml
6
补充
1
# cat lnmp.yml
---
-
hosts: webservers
gather_facts: no
tasks:
-
include_tasks: nginx.yml
vars:
name: nginx
-
import_tasks: mysql.yml
vars:
name: mysql
-
import_tasks: php.yml
vars:
name: php
2
# cat nginx.yml
---
-
name: Install nginx
debug: msg="install {{name}} …"
3
# cat mysql.yml
---
-
name: Install mysql
debug: msg="install {{name}} …"
4
# cat php.yml
---
-
name: Install php
debug: msg="install {{name}} …"
5
查看执行结果
6
补充
第 8 章
1
playbook文件
cat condition.yml
---
-
hosts: webservers
gather_facts: yes
tasks:
-
name: Host 172.16.1.121 run this task
debug:
msg="{{ansible_default_ipv4.address}}"
when: ansible_default_ipv4.address ==
'10.0.0.121'
-
name: Update apache version - yum
yum: name=httpd state=present
when: ansible_pkg_mgr == 'yum'
notify: restart httpd
-
name: Update apache version - apt
apt: name=apache2 state=present
update_cache=yes
when: ansible_pkg_mgr == 'apt'
notify: restart apache2
-
name: shut down CentOS 7 and Debian 7 systems
command: echo "hello"
when: (ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7") or
(ansible_distribution == "Debian"
and ansible_distribution_major_version == "7")
-
name: shut down CentOS 7 systems
command: echo "hello"
when:
- ansible_distribution ==
"CentOS"
- ansible_distribution_major_version
== "7"
handlers:
-
name: restart httpd
service: name=httpd state=restared
-
name: restart apache2
service: name=apache2 state=restared
2
查看运行结果
ansible-playbook condition.yml
1
playbook文件
cat cycle.yml
---
-
hosts: webservers
gather_facts: no
tasks:
-
name: with_list
debug: msg="{{item}}"
with_list:
- one
- two
-
name: with_list -> loop
user: name={{item}} state=present
loop:
- wangwu
- zhaoliu
-
name: with_items
user: name={{item.name}} group={{item.groups}}
state=present
with_items:
- {name: 'zhangsan', groups:
'nginx'}
- {name: 'lisi', groups:
'nginx'}
2
查看运行结果
第 9 章
1
playbool文件
cat jinja2.yml
---
-
hosts: webservers
gather_facts: no
vars:
hello: Ansible
tasks:
-
template: src=f.j2 dest=/tmp/f.j2
2模板文件
cat f.j2
#########List_Loop#########
{%
set list=['one', 'two', 'three'] %}
{%
for i in list %}
{% if
i == 'two' %}
->
two
{%
elif loop.index == 1 %}
->
one
{%
else %}
{{i}}
{%
endif %}
{%
endfor %}
######Group_Vars###########
{{
http_port }}
{{
server_name }}
########Dict_Loop##########
{%
set dict={'zhangsan': '26', 'lisi': '25'} %}
{%
for key, value in dict.iteritems() %}
{{key}} -> {{value}}
{%
endfor %}
1
playbool文件
[root@controlnode
~]# cat /root/ansible_yml/jinja2_nginx/main.yml
---
-
hosts: webservers
gather_facts: no
vars:
http_port:
80
server_name:
www.changliu.com
tasks:
-
name: Copy nginx configuration file
template: src=site.conf.j2
dest=/etc/nginx/conf.d/site.conf
notify: reload nginx
handlers:
-
name: reload nginx
service: name=nginx state=reloaded
2
模板文件
[root@controlnode
~]# cat /root/ansible_yml/jinja2_nginx/site.conf.j2
{%
set list=[10, 11, 12, 13, 14] %}
upstream
{{ server_name }} {
{%
for i in list %}
server 172.16.1.{{ i
}}:8080;
{%
endfor %}
}
server
{
listen {{
http_port }};
server_name {{ server_name }};
location
/ {
proxy_pass http://{{ server_name
}};
}
}
3
查看执行结果
[root@controlnode ~]#
ansible-playbook /root/ansible_yml/jinja2_nginx/main.yml
4
在被管理主机上查看结果
[root@slavenode1
~]# cat /etc/nginx/conf.d/site.conf
upstream
www.changliu.com {
server
172.16.1.10:8080;
server
172.16.1.11:8080;
server
172.16.1.12:8080;
server
172.16.1.13:8080;
server
172.16.1.14:8080;
}
server
{
listen 80;
server_name www.changliu.com;
location
/ {
proxy_pass
http://www.changliu.com;
}
}
site.yml # role 执行的入口,是一个playbook文件,定义了要执行的roles所在的目录
hosts # 远程主机组
group_vars/ # 主机组变量
roles/
common/ #
存放公共角色的目录
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/#
存放指定角色目录
tasks/
defaults/
meta/
tasks # 包含角色要执行的主要任务列表,必须包含一个main.yml文件。
handlers # 包含角色使用的处理程序,必须包含一个main.yml文件。
defaults # 角色默认的变量
vars # 角色其他的变量
files # 角色部署时用到的文件
templates # 角色部署时用到的模板(jinja2)
meta # 角色定义的一些元数据
示例一:
---
-
hosts: webservers
roles:
-
common
-
nginx
-
php
示例二:
---
-
hosts: webservers
roles:
-
common
-
role: nginx
vars:
dir: '/opt/a'
app_port: 5000
-
role: php
vars:
dir: '/opt/b'
app_port: 5001
示例三:
---
-
hosts: webservers
roles:
-
role: common
tags: ["common"]
-
role: nginx
tags: ["nginx"]
-
role: php
tags: ["php"]
(1)
roles 目录结构
(1)
执行roles
(2)
第二次执行roles
最佳实践:https://docs.ansible.com/ansible/latest/userguide/playbooksbest_practices.html
示例参考:https://github.com/ansible/ansible-examples
(1)
ansiable使用roles的作用
1)
一键部署所需要的项目;
2)
可以将配置打包分享给其他人使用,被分享的人也可以做到一键部署;
3)
roles的目录是已经约定好的,很容易维护和管理。
(2)
ansible软件输出颜色说明
1)
绿色信息: 查看主机信息/对主机未做改动
2)
黄色信息: 对主机数据信息做了修改
3)
红色信息: 命令执行出错了
4)
粉色信息: 忠告信息
5)
蓝色信息: 显示ansible命令执行的过程
cat zabbix_agent.yml
---
-
hosts: webservers
gather_facts: yes
vars:
zabbix_server:
10.0.0.120
tasks:
-
name: Copy zabbix agent - CentOS6
# yum:
name=https://repo.zabbix.com/zabbix/4.0/rhel/6/x86_64/zabbix-agent-4.0.0-2.el6.x86_64.rpm
state=present
copy: src=zabbix-agent-4.0.23-1.el6.x86_64.rpm
dest=/tmp
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "6"
-
name: Copy zabbix agent - CentOS7
# yum:
name=https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.0-2.el7.x86_64.rpm
state=present
copy: src=zabbix-agent-4.0.23-1.el7.x86_64.rpm
dest=/tmp
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7"
-
name: Install zabbix agent - CentOS6
yum:
name=/tmp/zabbix-agent-4.0.23-1.el6.x86_64.rpm state=present
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "6"
-
name: Install zabbix agent - CentOS7
yum: name=/tmp/zabbix-agent-4.0.23-1.el7.x86_64.rpm
state=present
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7"
-
name: Copy zabbix agent configuration file
template: src=zabbix_agentd.conf.j2
dest=/etc/zabbix/zabbix_agentd.conf
notify:
- restart
zabbix-agent
-
name: Start zabbix agent
service: name=zabbix-agent state=started
enabled=true
handlers:
-
name: restart zabbix-agent
service: name=zabbix-agent
state=restarted
cat zabbix_agentd.conf.j2
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
DebugLevel=3
EnableRemoteCommands=0
Server={{
zabbix_server }}
ListenPort=10050
ListenIP={{
ansible_default_ipv4.address }}
StartAgents=3
ServerActive={{
zabbix_server }}
Hostname={{
ansible_default_ipv4.address }}
HostnameItem=system.hostname
HostMetadata=linux
HostMetadataItem=system.uname
RefreshActiveChecks=120
BufferSend=5
BufferSize=100
MaxLinesPerSecond=20
Timeout=30
AllowRoot=0
User=zabbix
Include=/etc/zabbix/zabbix_agentd.d/*.conf
手机扫一扫
移动阅读更方便
你可能感兴趣的文章