当前位置: 代码迷 >> 综合 >> Linux——Salt Stack自动化部署
  详细解决方案

Linux——Salt Stack自动化部署

热度:73   发布时间:2024-02-11 01:47:00.0

Salt Slack

简介

SaltStack、Ansible、Puppet比较

(1)SaltStack(一般用于大于1000台服务器的公司环境)
saltStack由Python编写,为server-client模式的系统,自己本身支持多master。运行模式为master端下发指令,客户端接收指令执行。saltstack依赖于zeromq消息队列,采用yaml格式编写配置文件,比较简单。支持api及自定义python模块,能轻松实现功能扩展。

(2)Ansible (应用于1000台以下服务器的环境)
类似与saltstack,基于python开发,关注的重点是精简和快速。不需要在节点安装代理软件,通过ssh执行所有功能,安装运行简单。其模块可以用任何语言开发,采用yaml格式编写配置文件。没有客户端,较难扩展。

(3)Puppet(慢慢的被市场淘汰)
puppet由Ruby编写,为server-client模式的系统。运行时由客户端定时去获取自己的配置文件进而应用更改。也可以通过master的push命令即可触发变更。将命令,文件,服务等抽象成资源,概念比较统一,时间悠久,文档较多。就可用操作,模块,用户界面等等功能而言,是三者之中最全面的。安装部署难度一般,配置清单相对于其他工具较复杂。

安装

1.salt软件包需要epel源的支持

[root@master ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@master ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@master ~]# yum clean all #清空缓存
[root@master ~]# yum makecache #生成yum缓存

2.安装salt

[root@master ~]# yum -y install salt-master salt-minion
[root@master ~]# systemctl start salt-master.service 
[root@master ~]# systemctl start salt-minion.service 

salt-master:服务端

salt-minion:被管理端

端口

4505 publish_port 提供远程命令发送功能
4506 ret_port 提供认证,文件服务,结果收集等功能

3.修改配置文件

master

[root@master ~]# grep -v ^# /etc/salt/master |grep -v ^$
interface: 0.0.0.0
#绑定到本地的0.0.0.0地址
publish_port: 4505
#管理端口,命令发送
user: root
#运行salt进程的用户
worker_threads: 5
#salt运行线程数,线程越多处理速度越快,不要超过cpu个数
ret_port: 4506
#执行结果返回端口
pidfile: /var/run/salt-master.pid
#pid文件位置
auto_accept: False
#自动接收minion的key
log_file: /var/log/salt/master
#日志文件地址

PS:在master端/etc/salt/master配置

auto_accept: True #如果对Minion信任,可以配置master自动接受请求

minion

[root@master ~]# grep -v ^# /etc/salt/minion|grep -v ^$
master: 192.168.1.11
#master服务器的ip
master_port: 4506
#master服务器的端口
user: root
#用户
id: node1
#主机名
acceptance_wait_time: 10
log_file: /var/log/salt/minion
#日志文件地址
[root@master ~]# systemctl restart salt-master.service 
[root@master ~]# systemctl restart salt-minion.service

4.查看配置文件

master

[root@master ~]# rpm -ql salt-master
/etc/salt/master  	#salt master主配置文件
/usr/bin/salt		#salt master 核心操作命令
/usr/bin/salt-cp	#salt 文件传输命令
/usr/bin/salt-key	#salt证书管理
/usr/bin/salt-master	#salt master 服务命令
/usr/bin/salt-run		#salt master runner命令
/usr/bin/salt-unity
/usr/lib/systemd/system/salt-master.service
/usr/share/man/man1/salt-cp.1.gz
/usr/share/man/man1/salt-key.1.gz
/usr/share/man/man1/salt-master.1.gz
/usr/share/man/man1/salt-run.1.gz
/usr/share/man/man1/salt-unity.1.gz
/usr/share/man/man7/salt.7.gz

minion

[root@master ~]# rpm -ql salt-minion 
/etc/salt/minion 	#minion配置文件
/usr/bin/salt-call 	#拉取命令
/usr/bin/salt-minion	#minion服务命令
/usr/lib/systemd/system/salt-minion.service	#minion启动脚本
/usr/share/man/man1/salt-call.1.gz
/usr/share/man/man1/salt-minion.1.gz

5.master上接收minion秘钥

? 在minion启动后连接master会请求master为其签发证书,等待证书签发完成后,master可以信任minion,并且minion和master之间的通信是加密的。

常用参数

参数 解释
-L 查看KEY状态
-A 允许所有
-D 删除所有
-a 认证指定的key
-d 删除指定的key
-r 注销掉指定key(该状态为未被认证)
[root@master ~]# salt-key -L
Accepted Keys:   #已经接受的key
Denied Keys:     #拒绝的key
Unaccepted Keys: #未加入的key
node1 
Rejected Keys:   #吊销的key#此时slave已经出现在unaccepted keys中,说明minion已经和master联系,并且master已经获取了minion的公钥,等待下一步指令。
[root@master ~]# salt-key -f node1
Unaccepted Keys:
node1:  a1:e9:9e:d1:d6:fd:7c:5a:4e:31:37:c3:76:41:6e:44#在master上查看minion的秘钥
[root@slave ~]# salt-call --local key.finger
local:a1:e9:9e:d1:d6:fd:7c:5a:4e:31:37:c3:76:41:6e:44#在minion上获取minion的秘钥
[root@master ~]# salt-key -a node1
The following keys are going to be accepted:
Unaccepted Keys:
node1
Proceed? [n/Y] y
Key for minion node1 accepted.#在master上接收秘钥
[root@master ~]# salt-key -L
Accepted Keys:
node1
Denied Keys:
Unaccepted Keys:
Rejected Keys:#查看master有没有获取到minion的秘钥日常

日常命令

1.test

[root@master ~]# salt '*' test.ping
node1:True
  • salt 是一个命表示目标主机, 在这里代表所有目标主机

  • test.ping是salt远程执行的一个模块下面的方法。这是条很简单的探测minion主机存活命令,也是远程执行命令,我们通过master发送消息给"*"所有的minion,并且告诉他们运行salt内置的命令(也是python模块中的一个函数),返回true表示slave机器监控存活。

test的其他函数:

test.echo

[root@master ~]# salt '*' test.echo 'heel linux'
node1:heel linux

test.fib生成斐波那契数列

[root@master ~]# salt '*' test.fib 10
node1:|_- 0- 1- 1- 2- 3- 5- 8- 3.81469726562e-06

PS:菲波那切数列定义是第0项是0,第1项是1,数列从第3项开始,每一项等于前两项之和。

2.命令组成结构

(1)完整的五部分命令

–summary参数显示salt命令的概要

[root@master ~]# salt --summary '*' cmd.run 'hostname'
node1:master-------------------------------------------
Summary
-------------------------------------------
# of Minions Targeted: 1
# of Minions Returned: 1
# of Minions Did Not Return: 0
-------------------------------------------

(2)列出所有salt的sys模块

PS:与系统交互的sys模块

[root@master ~]# salt 'node1' sys.list_modules
node1:- acl- aliases- alternatives- archive- artifactory
......

案例

环境

主机Ip 主机名
192.168.1.11 master(node1)
192.168.1.10 minion(node2)

PS:服务端安装salt-master,被管理端安装salt-minion,修改配置文件,关闭防火墙和SElinux

远程执行模块

1.cmd是超级模块,所有shell命令都能执行

[root@master ~]# salt 'node2' cmd.run 'pwd'
node2:/root

2.远程安装nginx

[root@master ~]# salt 'node2' pkg.install "nginx"
#安装nginx
[root@master ~]# salt 'node2' pkg.version "nginx"
node2:
#查看nginx版本
[root@master ~]# salt 'node2' pkg.remove "nginx"
#卸载nginx

3.远程管理服务模块

? 管理服务是系统管理员的重要任务,通过salt管理minion服务会很简单,使用service模块

PS:确保以安装nginx

[root@master ~]# salt 'node2' service.start "nginx"
node2:True#开启nginx
[root@master ~]# salt 'node2' service.status "nginx"
node2:True#查看nginx状态
[root@master ~]# salt 'node2' service.stop "nginx"
node2:True#关闭nginx

4.小实验

#开启nginx
[root@master ~]# salt 'node2' service.start "nginx"
node2:True
#用cmd查看nginx的状态
[root@master ~]# salt 'node2' cmd.run 'systemctl status nginx'
node2:* nginx.service - The nginx HTTP and reverse proxy serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)Active: active (running) since Wed 2020-08-12 20:29:37 CST; 46s agoProcess: 17355 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)Process: 17352 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)Process: 17350 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)Main PID: 17357 (nginx)CGroup: /system.slice/nginx.service|-17357 nginx: master process /usr/sbin/ngin|-17358 nginx: worker proces`-17359 nginx: worker procesAug 12 20:29:37 minion systemd[1]: Starting The nginx HTTP and reverse proxy server...Aug 12 20:29:37 minion nginx[17352]: nginx: the configuration file /etc/nginx/nginx.conf syntax is okAug 12 20:29:37 minion nginx[17352]: nginx: configuration file /etc/nginx/nginx.conf test is successfulAug 12 20:29:37 minion systemd[1]: Started The nginx HTTP and reverse proxy server.

out命令的用法

PS:out与标准的Linux、salt的命令一样用法

  • –out控制salt命令结果输出的格式

JSON

[root@master ~]# salt --out=json '*' cmd.run_all 'hostname'
{"node2": {"pid": 17373, "retcode": 0, "stderr": "", "stdout": "minion"}
}
{"node1": {"pid": 19729, "retcode": 0, "stderr": "", "stdout": "master"}
}

YAML

[root@master ~]# salt --out=yaml '*' cmd.run_all 'hostname'
node2:pid: 17379retcode: 0stderr: ''stdout: minion
node1:pid: 29762retcode: 0stderr: ''stdout: master

编写States

States简称SLS文件。这个文件遵循YAML语法。

json xml yaml 数据序列化格式,yaml容易被解析,应用于配置文件。

salt的配置文件是yaml配置文件,不能用tab,saltstack,k8s,ansible都用的yaml格式配置文件

语法规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时禁止tab键,只能空格
  • 缩进的空格数不重要,相同层级的元素左侧对其即可
  • #号表示注释行

yaml支持的数据结构

  • 对象: 键值对,也称作映射 mapping 哈希hashes 字典dict 冒号表示 key: value key冒号后必须有空格
  • 数组: 一组按次序排列的值,又称为序列sequence 列表list 短横线 - list1
  • 纯量: 单个不可再分的值

对象:键值对

yamlfirst_key:second_key:second_valuepython{'first_key':{'second_key':'second_value',}}

? YAML是YAML Ain’t Markup Language的首字母缩写,YAML的语法简单,结构体通过空格展示项目使用 ‘-’ 代表,键值对通过 ‘:’ 分割。
? YAML语法遵循固定的缩进风格,表示数据层级结构关系,saltstack需要每个缩进级别由2个空格组成,禁止用tabs!!!
? Python中的字典是简单的键值对,go语言中称作哈希表map字典的key通过冒号分割。

? key在YAML中表现形式是一个冒号结果的字符串 my_key: my_value转化到python语法中,上述命令为{‘my_key’:‘my_value’}

? value还可以通过缩进和key关联,四个空格!!my_key: my_value 转化为python语法同样的{‘my_key’:‘my_value’}

? YAML语法中字典是可以嵌套的one_dict_key: two_dict_key:value_dict转化为python语法

{'one_dict_key':{'two_dict_key':'value_dict'}
}

短横杠

? YAML语法表示列表,使用一个横杠加一个空格多个项使用同样的缩进级别作为同一个列表的部分,列表可以作为一个键值对的value,例如一次性要安装多个软件

my_dict:- l1- l2- l3
转化为python代码理解就是
{'my_dict':['l1','l2',;l3]
}

state模块

? 之前执行的远程命令,都是一个过程式的,类似一段shell或者python脚本执行,执行一次触发一次相同的功能。那么大量的minion上运行远程命令就必须使用salt提供的“状态管理”了,状态是对minion的一种描述和定义,运维不需要关心部署是如何完成的,只需要描述minion需要达到什么状态。

state模块部署nginx

(1)master端

[root@master ~]# vim /etc/salt/master 
file_roots:base:- /srv/salt/basedev:- /srv/salt/devtest:- /srv/salt/testprod:- /srv/salt/prod
[root@master ~]# systemctl restart salt-master.service 

(2)master、minion都执行

[root@master ~]# mkdir -p /srv/salt/{base,dev,test,prod}
[root@minion ~]#  mkdir -p /srv/salt/{base,dev,test,prod}
#master
[root@minion ~]# vim /srv/salt/base/nginx.sls
nginx-install:pkg.installed:- name: nginxnginx-service:service.running:- name: nginx- enable: True
#minion
[root@master ~]# cat /srv/salt/base/nginx.sls
nginx-install:pkg.installed:- name: nginxnginx-service:service.running:- name: nginx- enable: True

? sls配置文件都遵循YAML语言描述,第一条命令使用了pkg.install安装命令,相对于运行了yum install,而此时state模块会判断nginx是否安装了,如果没有安装就进行安装,安装了就什么都不做。状态描述都会遵循这个原则,只有检测到真实状态和所需状态不一就会执行此功能,这种性质叫做幂等性。此时用state模块部署nginx软件,通过我们编写的nginx.sls描述性配置文件,命令行调用state模块的sls函数。

(3)启动命令

[root@master ~]# salt 'node2' state.sls nginx
node2:
----------ID: nginx-installFunction: pkg.installedName: nginxResult: TrueComment: Package nginx is already installed.Started: 20:53:28.178139Duration: 545.41 msChanges:   
----------ID: nginx-serviceFunction: service.runningName: nginxResult: TrueComment: Service nginx has been enabled, and is in the desired stateStarted: 20:53:28.724378Duration: 382.476 msChanges:   ----------nginx:TrueSummary
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2

PS:如果直接安装过nginx,可以客户端关闭nginx,删除nginx,重新执行命令,一样可以安装启动nginx

(4)查看nginx状态

[root@master ~]# salt 'node2' cmd.run 'systemctl status nginx'
node2:* nginx.service - The nginx HTTP and reverse proxy serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)Active: active (running) since Wed 2020-08-12 20:29:37 CST; 25min agoMain PID: 17357 (nginx)CGroup: /system.slice/nginx.service|-17357 nginx: master process /usr/sbin/ngin|-17358 nginx: worker proces`-17359 nginx: worker procesAug 12 20:29:37 minion systemd[1]: Starting The nginx HTTP and reverse proxy server...Aug 12 20:29:37 minion nginx[17352]: nginx: the configuration file /etc/nginx/nginx.conf syntax is okAug 12 20:29:37 minion nginx[17352]: nginx: configuration file /etc/nginx/nginx.conf test is successfulAug 12 20:29:37 minion systemd[1]: Started The nginx HTTP and reverse proxy server.

采集信息

? Grains 是saltstack组件中非常重要之一,在配置部署时候经常使用,Grains记录minion的静态信息,比如常用属性,CPU、内存、磁盘、网络信息等。
Minions的Grains信息是Minion启动时采集汇报给Master的,Grains是以 key value形式存储的数据库,可以看做Host的元数据(metadata),Grains保存着收集到的客户端的详细信息,如果slave机器数据变化,grains就过期了,在生产环境中需要自定义Grains,可以通过:
? Minion配置文件
? Grains相关模块定义
? Python脚本定义

使用系统Grains数据

查看grains的命令用法

[root@master ~]# salt 'node2'  sys.doc grains

列出主机所有Grains数据

[root@master ~]# salt 'node2' grains.items

列出所有grains方法

[root@master ~]# salt 'node2'  grains.ls

.检索某些数据

[root@master ~]# salt 'node2'  grains.item os id host
node2:----------host:minionid:node2os:CentOS
[root@master ~]# salt 'node2'  grains.item key1 key2 key3   # 利用Grains静态信息定位主机
node2:----------key1:key2:key3:

定位Cenots的机器

[root@master ~]# salt -G 'os:Centos' test.ping
node1:True
node2:True

定位操作系统系统是7系列的机器

[root@master ~]# salt -G 'osrelease:7*' test.ping
node1:True
node2:True

找出ip地址

[root@master ~]# salt '*' grains.item fqdn_ip4
node1:----------fqdn_ip4:- 192.168.1.11
node2:----------fqdn_ip4:- 192.168.1.10

自定义设置Grains数据

设置数据

[root@master ~]# salt 'node1' grains.setval cpu_num 8
node1:----------cpu_num:8

查询数据

[root@master ~]# salt 'node1' grains.item cpu_num
node1:----------cpu_num:8

PS:在master端设置Grains静态数据,原理会将此数据添加到minion服务器的配置文件的/etc/salt/grains。

minion端查看

[root@minion ~]# cat /etc/salt/grains 
cpu_num: 8

JSON语法

对于复杂的数据结构,可以添加灵活的JSON语法

[root@master ~]# salt 'node1' grains.setval cpu_info '["Intel","Xeon","10"]'
node1:----------cpu_info:- Intel- Xeon- 10
[root@master ~]# salt 'node1' grains.item cpu_info
node1:----------cpu_info:- Intel- Xeon- 10

此时可以检查minion服务器上的grains文件

[root@minion ~]# cat /etc/salt/grains 
cpu_info:
- Intel
- Xeon
- '10'
cpu_num: 8

PS:Grains数据写入配置文件后,重启salt-minion服务,数据也不会丢失

清空值

? 想要删除可以通过grains.delval命令删除,或者去minion的配置文件删除配置一样完成操作(或者删除文件)

方法一:

[root@master ~]# salt 'node1' grains.delval cpu_info
node1:None
[root@master ~]# salt 'node1' grains.delval cpu_num
node1:None
[root@master ~]# cat /etc/salt/grains 
cpu_info: null
cpu_num: null

方法二:

[root@minion ~]# cat /etc/salt/grains 
cpu_info:
- Intel
- Xeon
- '10'
cpu_num: 8
[root@minion ~]# rm -rf /etc/salt/grains
[root@minion ~]# systemctl restart salt-minion.service 
[root@minion ~]# cat /etc/salt/grains 
cat: /etc/salt/grains: No such file or directory

Pillar

? Pillar也是saltstack组件中非常重要的组件之一,称作数据管理中心,经常配合states在大规模的配置管理中使用。

? Pillar是动态的,存储在master端,提供和给minion端。

? Pillar在SaltStack中主要的作用是存储和定义配置管理中需要的一些数据,比如软件版本号,用户账号密码等,保证敏感数据不被其他minion看到。存储格式与Grains类似,都是YAML格式。

在master配置文件中有一段Pillar settings选项专门定义Pillar的参数

[root@master ~]# vim /etc/salt/master 
#此配置代表pillar的工作根目录,在/srv/pillar下,然后可以新建sls文件
#pillar_roots:
#  base:
#    - /srv/pillar
删除#号
[root@master ~]# mkdir -p /srv/pillar   //建立工作目录

指定环境,标记引用packages.sls和services.sls

[root@master ~]# vim /srv/pillar/top.sls
base:'*':- packages- services
[root@master ~]# vim /srv/pillar/packages.sls
nginx:packages-name: nginxversion: 1.12.2[root@master ~]# vim /srv/pillar/services.sls
nginx:port: 80user: root

检查设置的pillar值

[root@master ~]# salt 'node2'  pillar.item nginx
node2:----------nginx:----------packages-name:nginxport:80user:rootversion:1.12.2

pillar与Grains对比

类型 数据采集方式 应用场景 定义位置
Grains 静态 minion启动时收集 数据查询 目标选择 配置管理 minion
Pillar 动态 master进行自定义 目标选择 配置管理 敏感数据 master
  相关解决方案