saltstack自动化运维

一、Saltstack 
1、简介
•Saltstack是基于python开发的一套C/S架构配置管理工具
• 使用SSL证书签方的方式进行认证管理
•底层使用ZeroMQ消息队列pub/sub方式通信
    – 号称世界上最快的消息队列ZeroMQ能快速在成千上万台主机上进行各种操作
    – 采用RSA Key方式确认身份认证
2、功能
•Saltstack最主要的两个功能是:配置管理与远程执行
•Saltstack不只是一个配置管理工具,还是一个云计算与数据中心架构编排的利器
•Saltstack已经支持Docker相关模块
•在友好地支持各大云平台之后,配合Saltstack的Mine实时发现功能可以实现各种云平台业务的自动扩展
3、特点
•使用命令发送到远程系统上是并行,而不是串行
•使用安全加密协议,
•使用最少最快的网络载荷
•提供简单的编辑接口
salt同样更加细致化的领域控制系统来远程执行,使得系统成为目标,不止可以通过主机名,还可以通过系统属性
4、Saltstack架构
• Saltstack基于C/S架构
    – 服务器端称作Master
    – 客户端称作Minion
•可以实现传统处理方式,即:客户端发送请求给服务器,服务器收到请求后处理请求,再将结果返回
•也可以使用消息队列中的发布与订阅(pub/sub)服务模式
5、工作机制
•Master和Minion都以守护进程的方式运行
•Master监听配置文件里定义的ret_port(接收minion请求),和publish_port(发布消息)的端口
•当Minion运行时,它会自动连接到配置文件里定义的Master地址ret_port端口进行连接认证
•当Master和Minion可以正常通信后,就可以进行各种各样的配置管理工作了
 
二、Saltstack安装与配置
1、环境准备CentOS 7
master服务端        192.168.10.7        tang7
minion客户端        192.168.10.3        tang3
2、SaltStack三种运行模式介绍
Local                        本地
Master/Minion                传统运行方式(server端跟agent端)
SaltSSH                SSH
3、Saltstack启动
•运行Master 节点
•修改Minion节点配置,填入Master节点信息
•启动Minion
•Master节点添加Minion
4、服务器端安装
在主机 tang7上配置安装salt-master
# yum -y installsalt-master                        //安装 salt-master
# systemctl startsalt-master                        //启动 Master
# systemctl enablesalt-master                        //开机自启动
# netstat -lntup|grep-E':4505|:4506'                //验证服务
tcp        0     0 0.0.0.0:4505               0.0.0.0:*                   LISTEN      2484/python2.6     
tcp        0     0 0.0.0.0:4506               0.0.0.0:*                   LISTEN      2496/python2.6
5、客户端安装
在主机 tang3上配置安装salt-minion
# yum -y installsalt-minion                        //安装salt-minion
#sed-e"s/^#\(master:\).*/\1 tang7/" -i /etc/salt/minion -e"s/^#\(id:\).*/\1${HOSTNAME}/" -i /etc/salt/minion   //修改Minion配置文件,使其可以与Master通信
# systemctl startsalt-minion.service                //启动Minion
# systemctl enablesalt-minion                        //开机自启动
6、Master与Minion互信:
•Minion上线后先与Master端联系,把自己的pubkey发过去
•Master接受Minion的公钥后,互信建立完成
• 服务器端密钥管理:
# salt-key -h
    -L: 列出密钥
    -a: 接受一个密钥
    -A: 接受全部密钥
    -D: 删除全部密钥
    ... ...
• 服务器端查看密钥信息:
# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
tang3
Rejected Keys:
• 服务器端接受密钥,完成互信:
# salt-key -A -y
The following keys aregoing to be accepted:
Unaccepted Keys:
tang3
Key for minion tang3accepted.
 
三、saltstack
1、远程执行命令:
salt命令使用方法如下
• salt [options]'<target>' <function> [arguments]
•target指的是在哪些Minion上执行,如果在全部Minion上运行,可以采用通配符 '*’
-L列表
-E正则
-N分组
-SCIDR
•function一般采用python的模块、方法、样式
• arguments是传递给方法的参数
2、salt远程执行命令详解
• salt '*' test.ping 命令
# salt '*'test.ping                 ##salt命令  test.ping的含义是,test是一个模块,ping是模块内的方法
tang3:
    True
• salt '*' cmd.run'uptime' 命令
# salt '*' cmd.runuptime
tang3:
     11:10:28 up  1:27, 1 user,  load average: 0.00, 0.01,0.00
• 所有minion安装ftp服务
# salt '*' pkg.installftp                Pkg是一个执行模块,Install是一个模块下面的参数,ftp是函数的参数(arg),有的函数需要参数,有的则不需要.
• 使用列表 -L
# salt -L 'tang3'cmd.run 'uptime'
tang3:
     11:10:28 up  1:27, 1 user,  load average: 0.00, 0.01,0.00
• 使用正则表达式 -E
# salt -E 'tang\d'cmd.run 'uptime'
tang3:
     11:20:48 up  1:37, 1 user,  load average: 0.00, 0.00,0.00
• 使用分组  -N
    定义分组
    # vim /etc/salt/master
    //1085 行
nodegroups:
#  group1:'L@foo.domain.com,bar.domain.com,baz.domain.com and bl*.domain.com'
#  group2: 'G@os:Debian and foo.domain.com'
  test: 'L@tang[0-9]'                             //注意空格!!!!前面空两格
# salt -N 'test'test.ping
tang3:
    True
3、传输文件
# vim /etc/salt/master
file_roots:
 base:                                //注意空格,前面两个空格
    -/srv/salt                        //master的默认根目录,前面四个空格,- 后面空一格。
# mkdir /srv/salt-p                   //创建根目录
# cp /etc/passwd/srv/salt/users           //添加测试文件
# salt '*' cmd.run'mkdir /test'                   //远程主机创建目录
# salt -N 'test'cp.get_file salt://users/test/user                //传输文件
tang3:
    /test/user
4、模块及功能:
• 列出所有可用模块
salt '随便一台主机名'sys.list_modules
• 查看模块所有功能
salt '随便一台主机名'  sys.list_functions 模块名
• 查看模块用法
salt '随便一台主机名' sys.doc模块名
salt '随便一台主机名' sys.doc模块名.方法
# salt '*'sys.list_modules
- acl - aliases -alternatives - archive - artifactory - at - blockdev - bridge - btrfs -buildout - cloud - cmd - composer - config
- container_resource -cp - cron - data - defaults - devmap - dig - disk - django - dnsmasq - dnsutil- drbd - elasticsearch - environ
- etcd - event - extfs- file - gem - genesis - git - grains - group - grub - hashutil - hg - hipchat- hosts
- http - img - incron -ini - introspect - ip - iptables - jboss7 - jboss7_cli - key - kmod - locale -locate - logrotate
- lowpkg - lvm - match- mine - modjk - mount - network - nfs3 - openstack_config - pagerduty -partition - pillar - pip - pkg
- pkg_resource -postfix - publish - puppet - pyenv - quota - raid - random - random_org - rbenv- ret - rsync - runit - rvm
- s3 - saltutil -schedule - scsi - sdb - seed - serverdensity_device - service - shadow - slack- smtp - sqlite3 - ssh - state
- status - supervisord- svn - sys - sysctl - syslog_ng - system - test - timezone - user - vbox_guest- virtualenv - xfs
 
四、YAML
什么是YAML:
• YAML:YAML Ain'tMarkup Language
• YAML的结构通过空格来展示
• 项目使用"-"来表示
• 键值对使用":"来表示
•Master和Minion的配置文件均采用YAML语法
•YAML使用一个固定的缩进风格表示数据层级结构关
• 一般每个缩进级别由两个空格组成
• 注意不要使用tab
• 缩进是初学者容易出错的地方之一
• YAML的键值对采用冒号分隔
• YAML键值对应python的字典
• YAML表示形式
    name: test
    或
    name:
      test
• Python字典
    {'name': 'test'}
• 字典可以嵌套
    hosts:
        name: test
• 字典表示形式为
    {
        'hosts': {
       'name': 'test'
       }
    }
• 列表项使用一个短横杠加一个空格
    - test1
    - test2
• 列表可以作为一个键值对的value
    pkg-http:
      - httpd
      - php
• Python语法
    {'pkg-http': ['httpd', 'php']}
 
五、Grains
•Grains是saltstack最重要的组件之一
•存储minion端的基本信息,这些信息一般都是静态的,如CPU、内核、操作系统等
• Grains存储在minion本地
•管理员可以在minion端进行grains值的修改,如增加、删除等
Grains基础应用
• 获取minion端所有grains信息
        # salt '随便一台主机名' grains.items
•通过grains.item获取minion端的fqdn信息
        # salt '随便一台主机名' grains.item fqdn
••••••通过minion定义grains
# vim /etc/salt/minion
grains:
    web:
      apache
# systemctl restartsalt-minion.service
# salt '*'saltutil.sync_grains
tang3:
# salt -G 'web:apache'test.ping
tang3:
    True
# salt -N 'test'grains.item web
tang3:
    ----------
    web:
        apache
 
六、Pillar
•Pillar也是saltstack最重要的组件之一
•作用是定义与被控主机相关的任何数据,定义好的数据可以被其他组件使用
•存储在master端,存放需要提供给minion的信息
•常用于敏感信息,每个minion只能访问master分配给自己的pillar信息
• 用于经常动态变化的信息
1、配置pillar
•Pillar需要一个pillar_roots来维护pillar的配置
•默认pillar_roots为/srv/pillar
•pillar_roots在Master配置文件中定义
# vim /etc/salt/master
pillar_roots:
  base:
    - /srv/pillar
# mkdir /srv/pillar
# systemctl restartsalt-master
2、Pillar数据文件
•Pillar执行时需要一个名为top.sls的入口文件
•通过top.sls文件作为入口,组织其它的pillar文件
• sls文件采用YAML格式
# cd /srv/pillar
# vim top.sls
base:                                        #与pillar_roots定义一致
 'L@tang3':                                #过滤目标
     -appweb                                #过滤目标
# vim appweb.sls
appname: web
software:
  - apache
  - nginx
# salt '*'pillar.items                        #获取pillar全部数据
tang3:
    ----------
    appname:
        web
    software:
        - apache
        - nginx
# salt '*'saltutil.refresh_pillar                #将pillar数据同步至minion
tang3:
    True
 
七、Jinja模板
1、Jinja基础
• Jinja是基于Python的模板引擎
•在saltstack中我们使用yaml_jinja渲染器来根据模板生产对应的配置文件
•对于不同的操作系统或者不同的情况,通过jinja可以让配置文件或者操作形成一种模板的编写方式
2、Jinja使用步骤
• 在state文件中使用"-template: jinja"声明
• 在模板文件中使用变量"{{name }}"声明,name为变量,自己定义
• 在state文件中使用"-defautls: name: value"声明
 
八、States
•States是satlstack中的配置语言
•安装软件包、管理配置文件都需要编写一些statessls文件
• states sls使用YAML语法
1、查看所有states模块
salt '随便一台主机'sys.list_state_modules
2、查看states某个模块功能
salt '随便一台主机'sys.list_state_functions 模块名
3、查看states某个模块的某个方法用法
salt '随便一台主机'sys.state_doc  模块名.方法
4、为不同的环境设置不同的文件目录
# vim /etc/salt/master
file_roots:
  base:
    - /srv/salt/
  dev:
    - /srv/salt/dev/services
    - /srv/salt/dev/states
  prod:
    - /srv/salt/prod/services
    - /srv/salt/prod/states
# mkdir -p/srv/salt/dev/{services,states} /srv/salt/prod/{states,services}
# systemctl restartsalt-master.service
 
九、案例:系统初始化
• 配置所有机器的DNS为 223.5.5.5
• 修改所有机器的yum 源为本机器网络yum
• 修改history 能显示命令执行时间
• 开启路由转发功能net.ipv4.ip_forward=1
• 添加用户tang
• 为用户tang 设置默认密码 tang
• 要求tang 在第一次登录是的时候修改密码
# cd /srv/salt
# vim top.sls
base:
  '*':
    - init.dns
    - init.yum
    - init.adduser
    - init.history
    - init.ip_forward
# mkdir init
# cd init/
# vim dns.sls
add_dns:
  file.managed:
    - name: /etc/resolv.conf
    - source: salt://dns.conf
    - user: root
    - group: root
    - mode: 644
    - template: jinja
    - defaults:
        DNS_IP: 223.5.5.5
# vim yum.sls
create_yum:
  file.managed:
    - name: /etc/yum.repos.d/test.repo
    - source: salt://yum.repo
    - user: root
    - group: root
    - mode: 644
unless条件
• 当unless条件不满足时,需要执行命令
onlyif条件
• 当onlyif条件满足时,需要执行命令
# vim adduser.sls
useradd tang:
  cmd.run:
    - unless: id tang
useradd tang:
echo 'tang' | passwd--stdin tang:
  cmd.run:
    - onlyif: id tang
chage -d 0 tang:
  cmd.run:
    - onlyif: id tang
# vim history.sls
history:
  file.append:
    - name: /etc/profile
    - text:
      - export HISTTIMEFORMAT='%F %T'
# vim ip_forward.sls
alter_ip_forward:
  sysctl.present:
    - name: net.ipv4.ip_forward
    - value: 1
# cd /srv/salt
# vim dns.conf
nameserver {{DNS_IP}}
state.highstate会读取所有环境的top.sls文件,并且执行top.sls文件内容里面定义的sls文件,不在top.sls文件里面记录的sls则不会被执行;
state.sls也可以指定读取哪个环境 使用saltenv = 读取环境
test = True 测试执行  不真正执行 
# salt '*'state.highstate saltenv=base test=True
# salt '*'state.highstate saltenv=base
 
十、案例:部署httpd web 服务器
• 在实验的 tang3上自动安装httpd软件包
• 更改httpd监听端口为8080
• 启动httpd 服务
1、pkg模块
• pkg模块可以实现软件包管理
•管理的软件包包括红帽RPM包和Ubuntu的deb包等
• 主要的方法有:
    – pkg.installed:安装软件包
    – pkg.latest:保持软件包为最新版本
    – pkg.remove:卸载软件包
    – pkg.purge:下载软件包,删除配置文件
2、require条件
• 只有httpd安装了才分发配置文件
3、service模块
•软件部署完毕后,需要确保服务处于运行状态,并且能够实现开机自启,这就用到了service模块
    – service.running:确保服务处于运行状态
    – service.enabled:开机自启
    – service.disabled:开机不启动
    – service.dead:确保服务处于未运行状态
4、使用watch
•服务如果能够正常启动,需要确保存在配置文件,设置如果配置文件存在,才启动服务
# cd/srv/salt/prod/services
# vim top.sls
prod:
  'E@tang[0-3]':
    - install_httpd
# vim install_httpd.sls
httpd_pkg_installed:
  pkg.installed:
    - name: httpd
alter_httpd:
  cmd.run:
    - name: sed -i '/Listen 80/s/80/8080/'/etc/httpd/conf/httpd.conf    //也可以使用file.managed 方法 将master的配置文件分发到客户端
    - unless: sed -n '/Listen 80$/p'/etc/httpd/conf/httpd.conf
    - require:
      - pkg: httpd_pkg_installed
running_httpd:
  service.running:
    - name: httpd
    - enable: true
    - restart: true
    - watch:
      - cmd: alter_httpd
# salt '*'state.highstate saltenv=prod test=True
# salt '*'state.highstate saltenv=prod
 
十一、案例:部署nginx 源码包
# cd/srv/salt/dev/services
# vim top.sls
dev:
  'L@tang3':
    - nginx_install
# mkdir nginx_install
# cd nginx_install
# vim init.sls
    include:
      - .initpkg
      - .install
      - .nginx_init
# vim initpkg.sls
    init_pkg_install:
      pkg.installed:
        - names:
          - gcc
          - gcc-c++
          - make
          - autoconf
          - openssl-devel
          - pcre-devel
# vim install.sls
    nginx_src_install:
      file.managed:
        - name:/usr/local/src/nginx-1.9.12.tar.gz
        - source:salt://nginx_install/files/nginx-1.9.12.tar.gz
        - user: root
        - group: root
        - mode: 644
      cmd.script:
        - source:salt://nginx_install/files/build.sh
        - cwd: /usr/local/src
        - user: root
        - unless: test -d /usr/local/nginx
        - require:
          - file: nginx_src_install
          - pkg:  init_pkg_install
# vim nginx_init.sls
    nginx_init:
      file.managed:
        - name:/usr/lib/systemd/system/nginx.service
        - source:salt://nginx_install/files/nginx.service
        - user: root
        - group: root
        - mode: 644
    nginx_service:
      service.running:
        - name: nginx
        - enable: true
        - restart: true
# mkdir files
# cd files
# vim build.sh
    #!/bin/bash
    useradd -s /sbin/nologin nginx
    tar xzf nginx-1.9.12.tar.gz
    cd nginx-1.9.12
    ./configure --prefix=/usr/local/nginx--user=nginx --group=nginx
    make
    make install
# ls
    build.sh                      // 源码安装脚本
    nginx-1.9.12.tar.gz      // nginx 源码包
    nginx.service                // nginx systemctl 系统启动文件
# vim nginx.service
    [Unit]
    Description=nginx - high performance webserver
    Documentation=http://nginx.org/en/docs/
    After=network.target remote-fs.targetnss-lookup.target
   
    [Service]
    Type=forking
    PIDFile=/usr/local/nginx/logs/nginx.pid
    ExecStartPre=/usr/local/nginx/sbin/nginx -t-c /usr/local/nginx/conf/nginx.conf
    ExecStart=/usr/local/nginx/sbin/nginx -c/usr/local/nginx/conf/nginx.conf
    ExecReload=/usr/local/nginx/sbin/nginx -sreload
    ExecStop=/usr/local/nginx/sbin/nginx -squit
    PrivateTmp=true
   
    [Install]
    WantedBy=multi-user.target
# salt '*'state.highstate saltenv=dev test=True
# salt '*'state.highstate saltenv=dev
 
十二、扩展
• • • • • • Saltstack Master  配置
Master主配置文件是/etc/salt/master,常用的配置选项与具体功能相关,所以,当应用到相关功能时再做调整,目前保持默认就好
• • • • • • 通用配置项:
1. interface:监听的IPv4地址
#interface: 0.0.0.0
2. IPv6:监听的IPv6的地址
#ipv6: False
3.PUBLISH_PORT:与Minion通信的端口
#publish_port: 4505
4.MASTER_ID:当前Master节点的ID
5. USER:启动Master服务的用户
#user: root
6.MAX_OPEN_FILES:每一个连接到Master的Minion ,Master都会打开一个文件描述符,改选项定义打开的最大文件数。可能报错:Toomany open files
#max_open_files: 100000
7.WORKER_THREADS:最大工作线程数
#worker_threads: 5
8.RET_PORT:获取Minion返回结果的端口
#ret_port: 4506
9.PIDFILE:Master进程的pid文件 比如要杀进程时可用
#pidfile:/var/run/salt-master.pid
10.ROOT_DIR:Master运行的根目录
#root_dir: /
11.CONF_FILE:Master配置文件路径
#conf_file:/etc/salt/master
12.PKI_DIR:pki验证密钥存放路径
#pki_dir:/etc/salt/pki/master
13.MODULE_DIR:Salt模版搜索路径
#module_dirs: <nodefault>
#   - /var/cache/salt/minion/extmods
14.CACHEDIR:默认缓存路径
#cachedir:/var/cache/salt/master
15.KEEP_JOBS:旧的任务信息保留多少个小时
#keep_jobs: 24
16.GATHER_JOB_TIMEOUT:Minion获取任务超时时间
#gather_job_timeout: 10
17.TIMEOUT:SaltAPI,command执行的超时时间
#timeout: 5
18.OUTPUT_FILE:SaltStackcommand输出文件 比如日志
#output_file: None
19.CLI_SUMMARY:显示客户端的概要信息,目标的Minion数,返回的数目,没返回的数目
#cli_summary: False
20.MAX_MINIONS:最大管理的Minions数
21.TRANSPORT:通信模块
22.TRANSPORT:通信模块的参数
23.MAX_EVENT_SIZE:最大的事件数
#max_event_size:1048576
• • • • • • 安全配置项:
1.OPEN_MODE:开发模式,如果设置为true,则任何minion都能连上Master,无需验证很危险
#open_mode: False
2.AUTO_ACCEPT:接听所有客户端的公钥
#auto_accept: False
3.TOKEN_EXPIRE:Master新生成token的存活时间
#token_expire: 43200
4.AUTOSIGN_TIMEOUT:如果Minion的keyid出现在pki_dir/minion_autosign/keyid中,Master会自动接受该Minion的链接,这个配置项,定义这个自动接受的持续时间,超时的要重新验证接受。
# autosign_timeout: 120
5.AUTOSIGN_FILE:自动接受Minionkeyid存放文件 白名单
#autosign_file:/etc/salt/autosign.conf
6.AUTOREJECT_FILE:于AUTOSIGN_FILE相反        黑名单
#autoreject_file:/etc/salt/autoreject.conf
7.PUBLISHER_ACL:对指定Minion可执行指定的命令白名单
#publisher_acl:
#  larry:
#    - test.ping
#    - network.*
8.PUBLISHER_ACL_BLACKLIST:与PUBLISHER_ACL相反 黑名单
#publisher_acl_blacklist:
#  users:
#    - root
#    - '^(?!sudo_).*$'   #  allnon sudo users
#  modules:
#    - cmd
9.EXTERNAL_AUTH:指定验证方法
#external_auth:
#  pam:
#    fred:
#      - test.*
10.FILE_RECV:允许minion向master发送文件一个特别危险的配置项
#file_recv: False
11.FILE_RECV_MAX_SIZE:允许minion向master发送最大文件(MB)
#file_recv_max_size:100
12.ROTATE_AES_KEY:轮换AESkey
13.MASTER_SIGN_PUBKEY,
   MASTER_SIGN_KEY_NAM,
   MASTER_PUBKEY_SIGNATURE,
   MASTER_USE_PUBKEY_SIGNATURE,  网络通信签名相关
• • • • • • Saltstack Minion  配置
• • • • • • 通用配置项:
1.MASTER:master的hostname,可以是多个  ip也行 域名也行
#master:
2.MASTER_TYPE:str,一对一 ;failover,容错的,这种情况下,master必须是多个,minion会逐个通信,func:动态生成的
# master_type: str
3.MAX_EVENT_SIZE:最多接受master推送过来的事件数目
#max_event_size:1048576
4.MASTER_FAILBACK:回滚,如果设置为true,此时master_type必须是failover
#master_failback: False
5.MASTER_ALIVE_INTERVAL:心跳检测
#master_alive_interval:30
6.RANDOM_MASTER:如果master是多个,则选择算法是否是随机的
#random_master: False
7.MASTER_PORT:Master端口
#master_port: 4506
8.USER:SaltStack启动用户
#user: root
9.SUDO_USER:可以获取sudo权限的用户
#sudo_user: root
10.ID:Minion的ID,会出现的Master的连接Minion的列表中
#id:
11.MASTER_TRIES:重连Master的次数
#master_tries: 1
12.AUTH_TRIES:auth 重试次数
#    auth_tries: 10
13.AUTH_TIMEOUT:auth超时
#auth_tries: 7
14.TCP_PUB_PORT:发布消息端口
#tcp_pub_port: 4510
15.TCP_PULL_PORT:获取消息端口
#tcp_pull_port: 4511
• • • • • • 安全配置项:
1.open_mode:可以用来清理master key,修改为true,重启,修改为false,重启 通过这些步骤来清理master key
#open_mode: False
2.MASTER_FINGER:master指纹,用来验证master,在master上运行salt-key-Fmaster获取
#master_finger: ''
3.VERIFY_MASTER_PUBKEY_SIGN:是否验证PUBKEY的签名文件
4.MASTER_SIGN_KEY_NAME:签名文件
5.ALWAYS_VERIFY_SIGNATURE:是否必须验证