1.Saltstack简介
官方文档:https://docs.saltstack.com/en/latest/
saltstack四大功能:
1.远程执行-在远程机器上批量执行命令
2.配置管理
3.云管理(openstack)
4.事件驱动(产生事件 监听事件)
2.安装Saltstack服务
#node1,node2节点
mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#node1安装salt-master,salt-minion
yum install salt-master
yum install salt-minion
#node2安装salt-minion
yum install salt-minion
#node1启动salt-master.service
[root@linux-node1 ~]# systemctl start salt-master.service
#配置minion服务启动
cd /etc/salt/
ls
vim minion
[root@linux-node1 salt]# egrep -v "#|^$" minion
master: 118.190.201.11
[root@linux-node1 salt]# systemctl start salt-minion.service
#node2节点配置启动
[root@linux-node2 ~]# vim /etc/salt/minion
master: 118.190.201.11
[root@linux-node2 ~]# systemctl start salt-minion.service
2.1master与minion之间的通信机制
(1)、minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private key)和 minion.pub(public key),然后将 minion.pub发送给master。
(2)、master在接收到minion的public key后,通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion id命名的 public key,然后master就能对minion发送指令了。
#认证机制 [root@linux-node2 ~]# cd /etc/salt/ [root@linux-node2 salt]# ll total 32 -rw-r----- 1 root root 26374 Oct 14 20:15 minion drwxr-xr-x 2 root root 6 Oct 14 20:16 minion.d -rw-r--r-- 1 root root 23 Oct 14 20:16 minion_id drwxr-xr-x 3 root root 19 Oct 14 20:16 pki [root@linux-node2 salt]# tree . ├── minion ├── minion.d ├── minion_id #缓存/生成的fqdn名,修改主机名时需要删除次文件 └── pki #第一次启动的时候会进行创建 └── minion ├── minion.pem #私钥 └── minion.pub #公钥 3 directories, 4 files #node2存放公钥到node1,因为配置了master主机,并且以id命名 [root@linux-node1 ~]# cd /etc/salt/pki/ [root@linux-node1 pki]# tree . ├── master │ ├── master.pem │ ├── master.pub │ ├── minions │ ├── minions_autosign │ ├── minions_denied │ ├── minions_pre #存放位置 │ │ ├── linux-node1.example.com │ │ └── linux-node2.example.com │ └── minions_rejected └── minion ├── minion.pem └── minion.pub 7 directories, 6 files #master需进行认证才能工作 [root@linux-node1 pki]# salt-key -a linux* #-a参数支持通配符 The following keys are going to be accepted: Unaccepted Keys: linux-node1.example.com linux-node2.example.com Proceed? [n/Y] Y Key for minion linux-node1.example.com accepted. Key for minion linux-node2.example.com accepted. #认证之后node2上发生的变化 [root@linux-node2 salt]# tree . ├── minion ├── minion.d │ └── _schedule.conf ├── minion_id └── pki └── minion ├── minion_master.pub #master的公钥 ├── minion.pem └── minion.pub 3 directories, 6 files #认证之后node1上发生的变化,公钥存放到了minions目录下 [root@linux-node1 pki]# tree . ├── master │ ├── master.pem │ ├── master.pub │ ├── minions │ │ ├── linux-node1.example.com │ │ └── linux-node2.example.com │ ├── minions_autosign │ ├── minions_denied │ ├── minions_pre │ └── minions_rejected └── minion ├── minion_master.pub ├── minion.pem └── minion.pub 7 directories, 7 files
2.2事后修改主机id的操作
1.先停止minion服务 2.使用salt-key -d 把id删除 3.到minion服务的主机上删除pki的目录,删除minion_id的文件 4.之后修改主机id,启动
2.3远程执行命令实践
[root@linux-node1 ~]# salt '*' test.ping linux-node1.example.com: True linux-node2.example.com: True #命令说明salt命令、*匹配所有目标、test.ping引用 #第二个模块 [root@linux-node1 ~]# salt '*' cmd.run 'uptime' linux-node2.example.com: 07:07:34 up 1 day, 13:28, 1 user, load average: 0.00, 0.01, 0.05 linux-node1.example.com: 07:07:34 up 1 day, 13:28, 1 user, load average: 0.03, 0.04, 0.05
2.4master与minion直接的通信介绍
#使用zeromq的消息队列进行通信,master连到4505端口,把消息发送4506
netstat -lntp (4505,4506)master端口
[root@linux-node1 ~]# lsof -ni:4505
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-mast 15095 root 13u IPv4 38372 0t0 TCP *:4505 (LISTEN)
salt-mast 15095 root 15u IPv4 96773 0t0 TCP 118.190.201.11:4505->118.190.201.12:53336 (ESTABLISHED)
salt-mast 15095 root 16u IPv4 96157 0t0 TCP 118.190.201.11:4505->118.190.201.11:40806 (ESTABLISHED)
salt-mini 17669 root 25u IPv4 96156 0t0 TCP 118.190.201.11:40806->118.190.201.11:4505 (ESTABLISHED)
3.Saltstack入门配置管理
[root@linux-node1 ~]# vim /etc/salt/master #搜索file_roots:/file_roots file_roots: base: - /srv/salt/base dev: - /srv/salt/dev test: - /srv/salt/test prod: - /srv/salt/prod #创建对应目录 [root@linux-node1 ~]# mkdir -p /srv/salt/{base,dev,test,prod} [root@linux-node1 ~]# tree /srv/salt/ /srv/salt/ ├── base #必须目录 ├── dev ├── prod └── test 4 directories, 0 files #重启服务 [root@linux-node1 ~]# systemctl restart salt-master.service #对目录进行操作 [root@linux-node1 ~]# cd /srv/salt/base/ [root@linux-node1 base]# mkdir web #web目录里面可以存放nginx apache tomcat [root@linux-node1 base]# cd web/ [root@linux-node1 web]# vim apache.sls #状态必须以.sls结尾 apache-install: pkg.installed: - name: httpd apache-service: service.running: - name: httpd - enable: True #配置文件详细说明 apache-install:表示key,id不能重复 pkg.installed:(pkg是一个状态模块,salt有两个模块一个远程执行的模块,一个状态的模块,) - name: httpd(安装的包名) apache-service:(key,id不能重复) service.running:(value 状态模块) - name: httpd (模块名称httpd) - enable: True (设置开机启动) pkg模块在centos下调用yum来安装,包管理工具 #文件写入的目录如下 [root@linux-node1 ~]# cd /srv/salt/base/ [root@linux-node1 base]# ls web [root@linux-node1 base]# tree . └── web └── apache.sls 1 directory, 1 file #执行状态文件 [root@linux-node1 ~]# salt 'linux-node2.example.com' state.sls web.apache #命令说明:远程在linux-node2这台机器上执行sls模块的方法,web.apache表示web目录下的apache文件sls省略,这是在默认的base目录下 若是在prod目录下需要后面跟上saltenv=prod linux-node2.example.com: ---------- ID: apache-install Function: pkg.installed Name: httpd Result: True #状态信息 Comment: The following packages were installed/updated: httpd #输出的结果 Started: 10:37:01.399406 Duration: 137316.308 ms Changes: ---------- httpd: ---------- new: 2.4.6-80.el7.centos.1 old: ---------- ID: apache-service Function: service.running Name: httpd Result: True Comment: Service httpd has been enabled, and is running Started: 10:39:18.796944 Duration: 1796.718 ms Changes: ---------- httpd: True Summary #汇总信息 ------------ Succeeded: 2 (changed=2) #成功2个改变了2个 Failed: 0 ------------ Total states run: 2
3.1实现高级状态配置
#vim /etc/salt/master top.sls 实现一对一或一对多的关系,把要求写入top文件去执行,默认在base目录下 [root@linux-node1 ~]# cd /srv/salt/base/ [root@linux-node1 base]# vim top.sls base: '*': - web.apache #远程执行高级状态,无须指定 [root@linux-node1 ~]# salt '*' state.highstate #说明:读取topfile里的内容谁要做什么事情 [root@linux-node1 ~]# salt '*' state.highstate test=True #进行测试不去真正执行
4.Salt数据系统之Grains
Grains存放着salt-minion启动时收集的信息,收集资产信息
[root@linux-node1 ~]# salt '*' grains.items #列出所有grains的名称和内容,key和value [root@linux-node1 ~]# salt '*' grains.ls #只列出名称 [root@linux-node1 ~]# salt '*' grains.get saltversion #获取单独某一个值,grains远程执行的模块get远程执行的方法 [root@linux-node1 ~]# salt '*' grains.get ip4_interfaces:eth0 #查看eth0地址信息 linux-node1.example.com: - 118.190.201.11 linux-node2.example.com: - 118.190.201.12
4.1Grains进行目标匹配
#使用Grains进行目标匹配,使Centos的机器执行命令 [root@linux-node1 ~]# salt -G 'os:CentOS' cmd.run 'uptime' linux-node1.example.com: 06:01:03 up 1:04, 1 user, load average: 0.17, 0.07, 0.06 linux-node2.example.com: 06:01:03 up 1:04, 1 user, load average: 0.00, 0.01, 0.05 [root@linux-node1 ~]# salt -G 'init:systemd' cmd.run 'uptime' #init:systemd 有grains.items列出的key/value #Grains的第二个功能在top_file里面使用 [root@linux-node1 ~]# vim /srv/salt/base/top.sls base: 'os:CentOS': - match: grain - web.apache #配置文件说明:在centos的机器上安装apache [root@linux-node1 ~]# salt '*' state.highstate #Grains配合模板进行判断 [root@linux-node1 ~]# vim /etc/salt/grains #自定义gtains位置固定 [root@linux-node1 ~]# cat /etc/salt/grains test-grains: linux-node2 #重启服务 [root@linux-node1 ~]# systemctl restart salt-minion.service #获取状态 [root@linux-node1 ~]# salt '*' grains.get test-grains #在那个minion上面写就是哪一个 linux-node1.example.com: linux-node2 linux-node2.example.com: #不重启进行获取 [root@linux-node1 ~]# vim /etc/salt/grains test-grains: linux-node2 web: apache [root@linux-node1 ~]# salt '*' saltutil.sync_grains linux-node1.example.com: linux-node2.example.com: [root@linux-node1 ~]# salt '*' grains.get web linux-node1.example.com: apache linux-node2.example.com:
5.Salt数据系统之pillar
#查看key/value
[root@linux-node1 ~]# salt '*' pillar.items #默认为空
linux-node2.example.com:
----------
linux-node1.example.com:
----------
#打开pillar开关master设置
[root@linux-node1 ~]# vim /etc/salt/master
pillar_opts: True
[root@linux-node1 ~]# systemctl restart salt-master.service
[root@linux-node1 ~]# salt '*' pillar.items
linux-node1.example.com:
----------
master:
----------
__role:
master
auth_mode:
1
auto_accept:
False
cache_sreqs:
True
cachedir:
/var/cache/salt/master
cli_summary:
False
client_acl:
----------
client_acl_blacklist:
----------
cluster_masters:
cluster_mode:
paranoid
con_cache:
False
conf_file:
/etc/salt/master
config_dir:
/etc/salt
cython_enable:
False
daemon:
False
default_include:
master.d/*.conf
enable_gpu_grains:
False
enforce_mine_cache:
False
enumerate_proxy_minions:
False
environment:
None
event_return:
event_return_blacklist:
event_return_queue:
0
event_return_whitelist:
ext_job_cache:
ext_pillar:
extension_modules:
/var/cache/salt/extmods
external_auth:
----------
failhard:
False
file_buffer_size:
1048576
file_client:
local
file_ignore_glob:
None
file_ignore_regex:
None
file_recv:
False
file_recv_max_size:
100
file_roots:
----------
base:
- /srv/salt/base
dev:
- /srv/salt/dev
prod:
- /srv/salt/prod
test:
- /srv/salt/test
fileserver_backend:
- roots
fileserver_followsymlinks:
True
fileserver_ignoresymlinks:
False
fileserver_limit_traversal:
False
gather_job_timeout:
10
gitfs_base:
master
gitfs_env_blacklist:
gitfs_env_whitelist:
gitfs_insecure_auth:
False
gitfs_mountpoint:
gitfs_passphrase:
gitfs_password:
gitfs_privkey:
gitfs_pubkey:
gitfs_remotes:
gitfs_root:
gitfs_user:
hash_type:
md5
hgfs_base:
default
hgfs_branch_method:
branches
hgfs_env_blacklist:
hgfs_env_whitelist:
hgfs_mountpoint:
hgfs_remotes:
hgfs_root:
id:
linux-node1.example.com
interface:
0.0.0.0
ioflo_console_logdir:
ioflo_period:
0.01
ioflo_realtime:
True
ioflo_verbose:
0
ipv6:
False
jinja_lstrip_blocks:
False
jinja_trim_blocks:
False
job_cache:
True
keep_jobs:
24
key_logfile:
/var/log/salt/key
keysize:
2048
log_datefmt:
%H:%M:%S
log_datefmt_logfile:
%Y-%m-%d %H:%M:%S
log_file:
/var/log/salt/master
log_fmt_console:
[%(levelname)-8s] %(message)s
log_fmt_logfile:
%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s][%(process)d] %(message)s
log_granular_levels:
----------
log_level:
warning
loop_interval:
60
maintenance_floscript:
/usr/lib/python2.7/site-packages/salt/daemons/flo/maint.flo
master_floscript:
/usr/lib/python2.7/site-packages/salt/daemons/flo/master.flo
master_job_cache:
local_cache
master_pubkey_signature:
master_pubkey_signature
master_roots:
----------
base:
- /srv/salt-master
master_sign_key_name:
master_sign
master_sign_pubkey:
False
master_tops:
----------
master_use_pubkey_signature:
False
max_event_size:
1048576
max_minions:
0
max_open_files:
100000
minion_data_cache:
True
minionfs_blacklist:
minionfs_env:
base
minionfs_mountpoint:
minionfs_whitelist:
nodegroups:
----------
open_mode:
False
order_masters:
False
outputter_dirs:
peer:
----------
permissive_pki_access:
False
pidfile:
/var/run/salt-master.pid
pillar_opts:
True
pillar_roots:
----------
base:
- /srv/pillar
pillar_safe_render_error:
True
pillar_source_merging_strategy:
smart
pillar_version:
2
pillarenv:
None
ping_on_rotate:
False
pki_dir:
/etc/salt/pki/master
preserve_minion_cache:
False
pub_hwm:
1000
publish_port:
4505
publish_session:
86400
queue_dirs:
raet_alt_port:
4511
raet_clear_remotes:
False
raet_main:
True
raet_mutable:
False
raet_port:
4506
range_server:
range:80
reactor:
reactor_refresh_interval:
60
reactor_worker_hwm:
10000
reactor_worker_threads:
10
renderer:
yaml_jinja
ret_port:
4506
root_dir:
/
rotate_aes_key:
True
runner_dirs:
saltversion:
2015.5.10
search:
search_index_interval:
3600
serial:
msgpack
show_jid:
False
show_timeout:
True
sign_pub_messages:
False
sock_dir:
/var/run/salt/master
sqlite_queue_dir:
/var/cache/salt/master/queues
ssh_passwd:
ssh_port:
22
ssh_scan_ports:
22
ssh_scan_timeout:
0.01
ssh_sudo:
False
ssh_timeout:
60
ssh_user:
root
state_aggregate:
False
state_auto_order:
True
state_events:
False
state_output:
full
state_top:
salt://top.sls
state_top_saltenv:
None
state_verbose:
True
sudo_acl:
False
svnfs_branches:
branches
svnfs_env_blacklist:
svnfs_env_whitelist:
svnfs_mountpoint:
svnfs_remotes:
svnfs_root:
svnfs_tags:
tags
svnfs_trunk:
trunk
syndic_dir:
/var/cache/salt/master/syndics
syndic_event_forward_timeout:
0.5
syndic_jid_forward_cache_hwm:
100
syndic_master:
syndic_max_event_process_time:
0.5
syndic_wait:
5
timeout:
5
token_dir:
/var/cache/salt/master/tokens
token_expire:
43200
transport:
zeromq
user:
root
verify_env:
True
win_gitrepos:
- https://github.com/saltstack/salt-winrepo.git
win_repo:
/srv/salt/win/repo
win_repo_mastercachefile:
/srv/salt/win/repo/winrepo.p
worker_floscript:
/usr/lib/python2.7/site-packages/salt/daemons/flo/worker.flo
worker_threads:
5
zmq_filtering:
False
#定义pillar数据
[root@linux-node1 ~]# vim /etc/salt/master
pillar_roots:
base:
- /srv/pillar/base
prod:
- /srv/pillar/prod
[root@linux-node1 ~]# mkdir -p /srv/pillar/{base,prod}
[root@linux-node1 ~]# tree /srv/pillar/
/srv/pillar/
├── base
└── prod
2 directories, 0 files
#重启服务
[root@linux-node1 ~]# systemctl restart salt-master.service
#编写pillar的sls
[root@linux-node1 ~]# vim /srv/pillar/base/apache.sls
{% if grains['os'] == 'CentOS' %}
apache: httpd
{% elif grains['os'] == 'Debian' %}
apache: httpd
{% endif %}
#指定pillar的值谁能使用,pillar必须有topfile才能用
[root@linux-node1 ~]# vim /srv/pillar/base/top.sls
base:
'*':
- apache
#指定在base环境下所有的机器都能访问到apache.sls这个pillar
[root@linux-node1 ~]# salt '*' pillar.items
linux-node1.example.com:
----------
apache: httpd
linux-node2.example.com:
----------
apache: httpd
#修改web/apache.sls使用pillar的形式
[root@linux-node1 ~]# vim /srv/salt/base/web/apache.sls
apache-install:
pkg.installed:
- name: {{ pillar['apache'] }}
apache-service:
service.running:
- name: {{ pillar['apache'] }}
- enable: True
[root@linux-node1 ~]# salt '*' state.highstate #执行
5.Saltstack远程执行模块
[root@linux-node1 ~]# salt 'linux-node1.example.com' service.status sshd #service.status sshd (service模块名称.status方法.sshd参数) linux-node1.example.com: True [root@linux-node1 ~]# salt '*' network.active_tcp #返回所有tcp连接 [root@linux-node1 ~]# salt '*' network.arp [root@linux-node1 ~]# salt '*' network.connect baidu.com 80 #测试是否连通minion #service模块 [root@linux-node1 ~]# salt '*' service.available sshd #判断服务是否正在运行 [root@linux-node1 ~]# salt '*' service.get_all #获取所有正在运行的服务 [root@linux-node1 ~]# salt '*' service.reload sshd #reload服务 [root@linux-node1 ~]# salt '*' service.stop <service name> #state状态模块 [root@linux-node1 ~]# salt '*' state.show_highstate #查看都有什么状态 [root@linux-node1 ~]# salt '*' state.show_top #显示minion-topfile #file模块 [root@linux-node1 base]# salt-cp '*' /etc/passwd /tmp/test_file #copy文件passed到tmp目录下 [root@linux-node1 base]# salt '*' file.access /tmp/test_file f #查看是否有这个文件 [root@linux-node1 base]# salt '*' file.access /tmp/test_file x #查看是否可执行
6.Saltstack远程执行返回
返回是minion放回的,是minion直接写在数据库里面
6.1需要在所有节点安装MySQL-python的安装包
#cmd.run模块 [root@linux-node1 ~]# salt '*' cmd.run 'yum install -y MySQL-python' #pkg.install模块 [root@linux-node1 ~]# salt '*' pkg.install MySQL-python
6.2创建数据库
#node1节点 [root@linux-node1 ~]# yum install -y mariadb-server #启动数据库 [root@linux-node1 ~]# systemctl start mariadb.service #登录数据库 [root@linux-node1 ~]# mysql
#创建表
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE `salt`;
CREATE TABLE `jids` (
`jid` varchar(255) NOT NULL,
`load` mediumtext NOT NULL,
UNIQUE KEY `jid` (`jid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX jid ON jids(jid) USING BTREE;
CREATE TABLE `salt_returns` (
`fun` varchar(50) NOT NULL,
`jid` varchar(255) NOT NULL,
`return` mediumtext NOT NULL,
`id` varchar(255) NOT NULL,
`success` varchar(10) NOT NULL,
`full_ret` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
KEY `id` (`id`),
KEY `jid` (`jid`),
KEY `fun` (`fun`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `salt_events` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL,
`data` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`master_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#授权 MariaDB [salt]> grant all on salt.* to salt@'%' identified by 'salt'; #查看创建的表 MariaDB [salt]> show tables; +----------------+ | Tables_in_salt | +----------------+ | jids | | salt_events | | salt_returns | +----------------+ 3 rows in set (0.00 sec)
6.2配置minion连接数据库
#node2节点配置 [root@linux-node2 ~]# vim /etc/salt/minion #末尾添加如下配置ip为master地址 mysql.host: '118.190.201.11' mysql.user: 'salt' mysql.pass: 'salt' mysql.db: 'salt' mysql.port: 3306 #重启服务 [root@linux-node2 ~]# systemctl restart salt-minion.service #node1节点配置 [root@linux-node1 ~]# vim /etc/salt/minion #末尾添加如下配置ip为master地址 mysql.host: '118.190.201.11' mysql.user: 'salt' mysql.pass: 'salt' mysql.db: 'salt' mysql.port: 3306 #重启服务 [root@linux-node1 ~]# systemctl restart salt-minion.service #测试验证指定返回MySQL [root@linux-node1 ~]# salt '*' test.ping --return mysql MariaDB [salt]> select * from salt_returns\G *************************** 1. row *************************** fun: test.ping jid: 20181018032515037759 return: true id: linux-node1.example.com success: 1 full_ret: {"fun_args": [], "jid": "20181018032515037759", "return": true, "retcode": 0, "success": true, "fun": "test.ping", "id": "linux-node1.example.com"} alter_time: 2018-10-18 03:25:15 *************************** 2. row *************************** fun: test.ping jid: 20181018032515037759 return: true id: linux-node2.example.com success: 1 full_ret: {"fun_args": [], "jid": "20181018032515037759", "return": true, "retcode": 0, "success": true, "fun": "test.ping", "id": "linux-node2.example.com"} alter_time: 2018-10-18 03:25:15 2 rows in set (0.00 sec) [root@linux-node1 ~]# salt '*' cmd.run 'uptime' --return mysql
6.3修改Master配置直接返回MySQL
[root@linux-node1 ~]# vim /etc/salt/master master_job_cache: mysql #配置master直接返回MySQL不需要在minion安装MySQL-python包 mysql.host: '118.190.201.11' mysql.user: 'salt' mysql.pass: 'salt' mysql.db: 'salt' mysql.port: 3306 [root@linux-node1 ~]# systemctl restart salt-master.service [root@linux-node1 ~]# salt '*' cmd.run 'uptime' -v #-v参数显示jid [root@linux-node1 ~]# salt '*' cmd.run 'uptime' -v Executing job with jid 20181018034301860750 ------------------------------------------- linux-node1.example.com: 03:43:01 up 22:46, 4 users, load average: 0.00, 0.10, 0.12 linux-node2.example.com: 03:44:58 up 22:48, 2 users, load average: 0.00, 0.01, 0.05 [root@linux-node1 ~]# salt-run jobs.lookup_jid 20181018034301860750 linux-node1.example.com: 03:43:01 up 22:46, 4 users, load average: 0.00, 0.10, 0.12 linux-node2.example.com: 03:44:58 up 22:48, 2 users, load average: 0.00, 0.01, 0.05
如无特殊说明,文章均为本站原创,转载请注明出处
- 转载请注明来源:自动化运维之一saltstack工具介绍
- 本文永久链接地址:https://www.xionghaier.cn/archives/867.html