文章目录
实验环境:
172.25.0.1 作为master
172.25.0.2 作为minion
172.25.0.3 作为minion
1.saltstack 介绍
saltstack是一个配置管理系统,能够维护预定义状态的远程节点。
saltstack是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据。
saltstack是运维人员提高工作效率、规范业务配置与操作的利器。
Salt的核心功能:
命令发送到远程系统是并行的而不是串行的
使用安全加密的协议
使用最小最快的网络载荷
提供简单的编程接口
Salt同样引入了更加细致化的领域控制系统来远程执行,使得系统成为目标不止可以通过主机名,还可以通过系统属性。
Salt的通信机制:
SaltStack 采用 C/S模式,minion与master之间通过ZeroMQ消息队列通信,默认监听4505端口。
Salt Master运行的第二个网络服务就是ZeroMQ REP系统,默认监听4506端口。
2.saltstack的安装与配置
2.1 配置yum源
官网:https://www.saltstack.com/
设置官方YUM仓库:
yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm
2.2 配置master
yum install -y salt-master
#安装master端
systemctl enable salt-master --now
#设置master自启动
2.3 配置minion
yum install -y salt-minion
#安装master端
vim /etc/salt/minion 在minion端设置master主机的ip
master: 172.25.0.1
systemctl enable salt-minion --now
#设置master自启动
2.4 配置master验证minion
lsof-key -L查看等待验证的minion
salt-key -a server2添加server2的minion端
salt-key -A添加所有minion端
salt-key -d server2`删除指定minion端
(如果hostname与minion端中minion_id中的名称不符合,需要删除salt-key和minion_id后,重启master重新验证)**
yum install -y python-setproctitle.x86_64
可以在ps中查看更详细的内容
systemctl restart salt-master
配置master
配置minion
配置master验证minion
3.saltstack 远程执行
3.1 salt命令的组成
Salt命令由三个主要部分构成:
salt '<target>' <function>[arguments]
target: 指定哪些minion,默认的规则是使用glob匹配minion id.
salt '*' test.ping
Targets也可以使用正则表达式:
salt -E 'server[1-3]' test.ping
Targets也可以指定列表:
salt -L 'server2,server3' test.ping
funcation是module提供的功能,Salt内置了大量有效的functions.
salt '*' cmd.run 'uname -a'
arguments通过空格来界定参数:
salt 'server2' sys.doc pkg
#查看模块文档
salt 'server2' pkg.install httpd
salt 'server2' pkg.remove httpd
注意:命令由4505端口推送,4506端口接收响应
salt内置的执行模块列表可参考 link
3.2 编写远程执行模块
1.编辑master配置文件:vim /etc/salt/master
file_roots:
base:
- /srv/salt
重启master服务:systemctl restart salt-master
/srv/salt/为salt数据的根目录
2.创建模块目录:
mkdir /srv/salt/_modules
3.编写模块文件:
vim /srv/salt/_modules/mydisk.py
def df():
return __salt__['cmd.run']('df -h')
4.同步模块:
salt server2 saltutil.sync_modules
5.运行模块
salt server2 mydisk.df
3.3 了解Yaml语法
规则一: 缩进
Salt需要每个缩进级别由两个空格组成,不要使用tabs。
规则二: 冒号
字典的keys在YAML中的表现形式是一个以冒号结尾的字符串。
my_key: my_value
规则三: 短横杠
想要表示列表项,使用一个短横杠加一个空格。
-list_value_one
-list_value_two
3.4 配置管理(sls)
1.创建SLS文件
1.SLS表示系统将会是什么样的一种状态,而且是以一种很简单的格式来包含这些数据,常被叫做配置管理。
2.Salt 状态系统的核心是SLS,或者叫SaLt State 文件。
3.sls文件命名:sls文件以”.sls”后缀结尾,但在调用是不用写此后缀。
4.推荐使用子目录来做组织是个很好的选择。
5.init.sls 在一个子目录里面表示引导文件,也就表示子目录本身, 所以apache/init.sls
就是表示apache
.
如果同时存在apache.sls 和apache/init.sls,则 apache/init.sls 被忽略,apache.sls将被用来表示 apache.
创建一个sls文件:
vim /srv/salt/apache.sls
httpd: # ID声明,同时也是软件包的名称
pkg: # 状态声明
-installed # 函数声明
也可以写成这中形式:
vim /srv/salt/apache.sls
httpd: #也可以写成这中形式
pkg.installed
也可以写成这中形式:
vim /srv/salt/apache.sls
web:
pkg.installed:
- pkgs:
- httpd
- php ##也可以装多个包
注意:在安装包时会自动安装依赖性,在卸载时则不会卸载依赖性,只会满足所需要的状态
指定主机执行:
salt server2 state.sls apache
2.创建top文件
top是一个高级状态,可以对应不同的节点有不同的操作
vim /srv/salt/top.sls
base:
'*':
- apache
批量执行:
salt '*' state.highstate
3.使用子目录配置管理
mkdir /var/salt/apache
建立子目录
vim /var/salt/apache/install.sls
salt server2 state.sls apache.install
注意:可以在任意目录下执行
也可以更简单:
mkdir /var/salt/apache
建立子目录
vim /var/salt/apache/init.sls
salt server2 state.sls apache
4.sls示例——配置httpd
vim /srv/salt/apache/init.sls
web:
pkg.installed:
- pkgs:
- httpd
- php
file.managed:
- source: salt://apache/file/httpd.conf
- name: /etc/httpd/conf/httpd.conf
service.running:
- name: httpd
- enable: True
- watch:
- file: web ##触发;注意这样的调用只能有一次
也可以换一种写法:
web:
pkg.installed:
- pkgs:
- httpd
- php
service.running:
- name: httpd
- enable: True
- watch:
- file: /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://apache/file/httpd.conf
mkdir /srv/salt/apache/file
scp server2:/etc/httpd/conf/httpd.conf /srv/salt/apache/file/
salt server2 state.sls apache
sls示例——配置nginx
方法一
mkdir /srv/salt/nginx
mkdir /srv/salt/nginx/files
vim /srv/salt/nginx/files/nginx.service
启动脚本文件
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
vim /srv/salt/nginx/files/nginx.
#user nobody;
worker_processes 2; ##设置work进程数
vim /srv/salt/nginx/init.sls
nginx-install:
pkg.installed:
- pkgs:
- openssl-devel
- pcre-devel
- gcc
file.managed:
- name: /mnt/nginx-1.18.0.tar.gz
- source: salt://nginx/files/nginx-1.18.0.tar.gz
cmd.run:
- name: cd /mnt/ && tar zxf nginx-1.18.0.tar.gz && cd nginx-1.18.0 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx --with-http_ssl_module &> /dev/null && make &> /dev/null && make install &> /dev/null
- creates: /usr/local/nginx
/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- name: /usr/lib/systemd/system/nginx.service
- source: salt://nginx/files/nginx.service
service.running:
- name: nginx
- enable: True
- reload: True
- watch:
- file: /usr/local/nginx/conf/nginx.conf
方法二
vim /srv/salt/nginx/init.sls
include:
- nginx.install
/usr/local/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/files/nginx.conf
nginx-service:
file.managed:
- name: /usr/lib/systemd/system/nginx.service
- source: salt://nginx/files/nginx.service
service.running:
- name: nginx
- enable: True
- reload: True
- watch:
- file: /usr/local/nginx/conf/nginx.conf
vim /srv/salt/nginx/install.sls
nginx-install:
pkg.installed:
- pkgs:
- openssl-devel
- pcre-devel
- gcc
file.managed:
- name: /mnt/nginx-1.18.0.tar.gz
- source: salt://nginx/files/nginx-1.18.0.tar.gz
cmd.run:
- name: cd /mnt/ && tar zxf nginx-1.18.0.tar.gz && cd nginx-1.18.0 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx --with-http_ssl_module &> /dev/null && make &> /dev/null && make install &> /dev/null
- creates: /usr/local/nginx
sls示例——top文件配置不同主机安装不同程序
vim /srv/salt/top.sls
base:
'server2':
- apache
'server3':
- nginx
salt '*' state.highstate
高级状态
3.saltstack的数据系统——grains与pillar
grains与pillar是saltstack的数据系统。
3.1 grains(静态)
1. grains的介绍
Grains是SaltStack的一个组件,存放在SaltStack的minion端。
当salt-minion启动时会把收集到的数据静态存放在Grains当中,只有当minion重启时才会进行数据的更新。
由于grains是静态数据,因此不推荐经常去修改它。
应用场景:
信息查询,可用作CMDB。
在target中使用,匹配minion。
在state系统中使用,配置管理模块
2. grains的信息查询
salt server2 grains.ls
salt server3 grains.item fqdn
查询域名
salt server3 grains.item ipv4
查询IP
3. 自定义grains项
在minion端(方法一)
vim /etc/salt/minion
grains:
roles: apache
systemctl restart salt-minion.service
在master端查看:salt server2 grains.item roles
在minion端(方法二)
vim /etc/salt/grains
创建grains文件
roles: nginx
在master端同步数据:salt server3 saltutil.sync_grains
在master端查看:salt server3 grains.item roles
在master端
mkdir /srv/salt/_grains
vim /srv/salt/_grains/my_grain.py
def my_grain():
grains = {}
grains['salt'] = 'stack'
grains['hello'] = 'world'
return grains
salt '*' saltutil.sync_grains
salt server2 grains.item salt
查看数据
salt server2 grains.item hello
4.grains匹配运用
target中匹配
salt -G roles:apache cmd.run hostname
-G通过grains
salt -G roles:nginx cmd.run hostname
salt -G salt:stack cmd.run hostname
salt -G hello:world cmd.run hostname
在top文件中匹配
vim /srv/salt/top.sls
在这里插入代码片base:
'roles:apache':
- match: grain
- apache
'roles:nginx':
- match: grain
- nginx
salt '*' state.highstate
3.2 pillar(动态)
1.pillar的介绍
pillar和grains一样也是一个数据系统,但是应用场景不同。
pillar是将信息动态的存放在master端,主要存放私密、敏感信息(如用户名密码等),而且可以指定某一个minion才可以看到对应的信息。
pillar更加适合在配置管理中运用。
2.自定义pillar项
vim /etc/salt/master
(这里是默认设置)
pillar_roots:
base:
- /srv/pillar
mkdir /srv/pillar
定义pillar基础目录
vim /srv/pillar/packages.sls
{% if grains['fqdn'] == 'server2' %}
package: httpd
{% elif grains['fqdn'] == 'server3' %}
package: apache
{% endif %}
vim /srv/pillar/top.sls
base:
'*':
- packages
salt '*' saltutil.refresh_pillar
刷新pillar数据
salt '*' pillar.items
查询pillar数据
salt '*' pillar.item packkages
查询pillar数据
3.pillar的数据匹配
命令行中匹配
salt -I package:httpd cmd.run hostname
state系统中使用
vim /srv/salt/apache/init.sls
web:
pkg.installed:
- pkgs:
- {{ pillar['package'] }}
- php
service.running:
- name: httpd
- enable: True
- watch:
- file: /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://apache/file/httpd.conf
salt server2 state.sls apache
4.Jinja模板
4.1 Jinja模板的介绍
Jinja是一种基于python的模板引擎,在SLS文件里可以直接使用jinja模板来做一些操作。
通过jinja模板可以为不同服务器定义各自的变量。
Jinja模板两种分隔符: {% … %} 和 {{ … }},前者用于执行诸如 for 循环
或赋值的语句,后者把表达式的结果打印到模板上。
4.2 Jinja模板的使用方式
1.使用控制结构包装条件
vim /srv/salt/test.sls
/mnt/testfile:
file.append:
{% if grains['fqdn'] == 'server2' %}
- text: server2
{% elif grains['fqdn'] == 'server3' %}
- text: server3
{% endif %}
salt '*' state.sls test
2.Jinja在普通文件的使用
方法一
vim /srv/salt/apache/init.sls
web:
pkg.installed:
- pkgs:
- {{ pillar['package'] }}
- php
service.running:
- name: httpd
- enable: True
- watch:
- file: /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://apache/file/httpd.conf
- template: jinja
- context:
bind: 172.25.0.2
vim /srv/pillar/packages.sls
{% if grains['fqdn'] == 'server2' %}
package: httpd
{% elif grains['fqdn'] == 'server3' %}
package: apache
{% endif %}
vim /srv/salt/apache/file/httpd.conf
Listen {{ bind }}:80
salt server2 state.sls apache
3.直接引用pillar/grains变量
直接引用pillar变量
vim /srv/pillar/packages.sls
{% if grains['fqdn'] == 'server2' %}
package: httpd
port: 80
{% elif grains['fqdn'] == 'server3' %}
package: apache
{% endif %}
vim /srv/salt/apache/file/httpd.conf
Listen {{ bind }}:{{ pillar['port'] }} ##直接引用pillar变量,必须是有jinja模板的前提
Listen {{ grains['ipv4'][1] }}:{{ pillar['port'] }} ##使用grain变量
salt server2 state.sls apache
直接引用grains变量
vim /srv/salt/apache/file/httpd.conf
Listen {{ bind }}:{{ port }}
vim /srv/salt/apache/init.sls
可以在入口文件中设置变量
web:
pkg.installed:
- pkgs:
- {{ pillar['package'] }}
- php
service.running:
- name: httpd
- enable: True
- watch:
- file: /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf:
file.managed:
- source: salt://apache/file/httpd.conf
- template: jinja
- context:
bind: {{ grains['ipv4'][1] }}
port: {{ pillar['port'] }}
4.使用jinja模板的Import方式
vim /srv/salt/lib.sls
{% set port = 8000 %} ##定义端口
vim /srv/salt/apache/file/httpd.conf
{% from 'lib.sls' import port %} ##在apache配置文件中导入模板文件
4.3 示例:高可用的安装配置
vim /srv/salt/keepalived
建立目录
vim /srv/salt/keepalived/files
建立文件目录
vim /srv/salt/keepalived/files/keepalived.conf
配置keepalived文件
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state {{ STATE }}
interface ens33
virtual_router_id 51
priority {{ PRI }}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.0.100
}
}
vim /srv/salt/keepalived/init.sls
kp-install:
pkg.installed:
- pkgs:
- keepalived
file.managed:
- name: /etc/keepalived/keepalived.conf
- source: salt://keepalived/files/keepalived.conf
- template: jinja
- context:
STATE: {{ pillar['state'] }}
PRI: {{ pillar['pri'] }}
service.runnning:
- name: keepalived
- enable: True
- reload: True
- watch:
- file:kp-install
vim /srv/pillar/packages/init.sls
{% if grains['fqdn'] == 'server2' %}
package: httpd
port: 80
state: MASTER
pri: 100
{% elif grains['fqdn'] == 'server3' %}
package: nginx
state: BACKUP
pri: 50
{% endif %}
salt '*' state.sls keepalived
自动化安装
5.Job管理
5.1 Job介绍
master在下发指令任务时,会附带上产生的jid。
minion在接收到指令开始执行时,会在本地的/var/cache/salt/minion/proc目录下产生该jid命名的文件,用于在执行过程中master查看当前任务的执行情况。
指令执行完毕将结果传送给master后,删除该临时文件
Job缓存默认保存24小时:
vim /etc/salt/master
keep_jobs: 24
master端Job缓存目录:/var/cache/salt/master/jobs
5.2 把job存储到数据库
可参考官网:http://docs.saltstack.cn/topics/jobs/external_cache.html#external-master-cache(缓存的配置)
docs.saltstack.cn/ref/returners/all/salt.returners.mysql.html#module-salt.returners.mysql(数据库的配置)
1.配置数据库
yum install -y mariadb-server
server1也作为数据库
systemctl start mariadb
mysql
**
> grant all on salt.* to salt@localhost identified by 'salt'; ##创建用户并授权
> > grant all on salt.* to salt@'%' identified by 'salt';
vim add.sql
建立数据库表
mysql -p < add.sql 导入数据库
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE `salt`;
--
-- Table structure for table `jids`
--
DROP TABLE IF EXISTS `jids`;
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;
--
-- Table structure for table `salt_returns`
--
DROP TABLE IF EXISTS `salt_returns`;
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;
--
-- Table structure for table `salt_events`
--
DROP TABLE IF EXISTS `salt_events`;
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;
2.把job存储到数据库
在master端配置:
yum install -y MySQL-python.x86_64
使master可以访问数据库
vim /etc/salt/master
修改master端配置
master_job_cache: mysql
mysql.host: 'localhost'
mysql.user: 'salt'
mysql.pass: 'salt'
mysql.db: 'salt'
systemctl restart salt-master
重启salt-master服务:
测试:
*
注意:此方式配置在minion端,配置方法同上。
yum install -y MySQL-python.x86_64
使minion可以访问数据库
vim /etc/salt/minion
修改minion端配置
return mysql ##返回数据到数据库
mysql.host: 'localhost'
mysql.user: 'salt'
mysql.pass: 'salt'
mysql.db: 'salt'
systemctl restart salt-minion
重启salt-minion服务:
5.3 Job管理
salt-run jobs.active
查看所有minion当前正在运行的jobs(在所有minions上运行saltutil.running)
salt-run jobs.list_jobs
列出当前master jobs cache中所有job
salt-run jobs.lookup_jid <jid>
从master jobs cache中查询指定jid的运行结果
6.salt-ssh
6.1 salt-ssh的介绍
salt-ssh可以独立运行的,不需要minion端。
salt-ssh 用的是sshpass进行密码交互的。
以串行模式工作,性能下降。
6.2 配置salt-ssh
yum install -y salt-ssh
在master安装salt-ssh
vim ~/.ssh/config
StrictHostKeyChecking ##可以设置跳过询问
vim /etc/salt/roster
配置roster文件
server2:
host: 172.25.0.2
user: root
password: redhat
server3:
host: 172.25.0.3
user: root
password: redhat
测试:
systemctl stop salt-minion
在minion端关闭客户端
salt-ssh '*' test.ping -i
询问密码加 -i
7.salt-syndic管理
7.1 salt-syndic的介绍
syndic其实就是个代理,隔离master与minion。(类似zabbix proxy)
Syndic必须要运行在master上,再连接到另一个topmaster上。
Topmaster 下发的状态需要通过syndic来传递给下级master,minion传递给master的数据也是由syndic传递给topmaster。topmaster并不知道有多少个minion。
syndic与topmaster的file_roots和pillar_roots的目录要保持一致。
7.2 配置salt-syndic
添加server4:172.25.0.4 作为topmaster
yum install -y salt-master
vim /etc/salt/master
order_masters: True
systemctl enable salt-master --now
在server1配置syndic
yum install -y salt-syndic
vim /etc/salt/master
syndic_master: 172.25.0.4 ##在下级master中指向topmaster
systemctl restart salt-master.service
systemctl start salt-syndic.service
topmaster对下级master连接授权
salt-key -L
salt-key -A
对下级maser连接授权
测试:
salt '*' test.ping
8.salt-api配置
8.1 salt-api的介绍
SaltStack 官方提供有REST、API格式的 salt-api 项目,将使Salt与第三方系统集成变得尤为简单。
官方提供了三种api模块:
rest_cherrypy
rest_tornado
rest_wsgi
可参考官方:https://docs.saltstack.com/en/latest/ref/netapi/all/index.html#all-netapi-modules
8.2 配置salt-api
可参考官网:docs.saltstack.cn/topics/eauth/index.html#acl-eauth
1.安装api
yum install -y salt-api
2.生成证书
cd /etc/pki/tls/private
openssl genrsa 2048 > localhost.key
cd /etc/pki/tls/certs
make testcert
3.创建用户认证文件
vim /etc/salt/master.d/eauth.conf
external_auth:
pam:
saltdev:
- .*
- '@wheel'
- '@runner'
- '@jobs'
useradd -s /sbin/nologin saltdev
passwd saltdev
4.激活rest_cherrypy模块
vim /etc/salt/master.d/api.conf
rest_cherrypy:
host: 172.25.0.1
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
systemctl restart salt-master
systemctl start salt-api
5.获取认证token
curl -sSk https://172.25.0.1:8000/login \
> -H 'Accept: application/x-yaml' \
> -d username=saltdev \
> -d password=redhat \
> -d eauth=pam
6.推送任务
curl -sSk https://172.25.0.1:8000 \
> -H 'Accept: application/x-yaml' \
> -H 'X-Auth-Token: f6c5bbe27c2fd234c5e31595c494c5a52fe8bd74' \
> -d client=local \
> -d tgt='*' \
> -d fun=test.ping