自动化运维工具Saltstack学习笔记(salt-ssh/salt-api/salt-syndic)

从磁盘使用统计中排除部分文件示例:

[root@foundation5 ~]# du -h --exclude "*.rpm" Downloads/
1.8M    Downloads/
[root@foundation5 ~]# du -h Downloads/
2.9M    Downloads/

找出指定目录中最大的 10 个文件

[root@foundation5 Pictures]# find -type f -exec du -k {} \; |sort -nrk 1 |head -n 3

一、编写saltstack的python扩展模块(以df -h为例)

1.创建模块目录

[root@rhel65-lockey1 ~]mkdir /srv/salt/_modules

2.创建模块文件

[root@rhel65-lockey1 _modules]# cat getDisk.py 
#!/bin/usr/env python

def df():
    cmd = 'df -h'
    return __salt__['cmd.run'](cmd)
[root@rhel65-lockey1 _modules]# pwd
/srv/salt/_modules

3.同步模块(用主机rhel65-lockey5做实验)

[root@rhel65-lockey1 salt]# salt rhel65-lockey5 saltutil.sync_modules

4.rhel65-lockey5端查看改变

[root@rhel65-lockey5 ~]# cd /var/cache/salt/minion && tree
.
├── accumulator
├── extmods
│   ├── grains
│   │   ├── my_grains.py
│   │   └── my_grains.pyc
│   └── modules
│       └── getDisk.py##############
├── files
│   └── base
│       ├── _grains
│       │   └── my_grains.py
│       ├── haproxy
│       │   ├── files
│       │   │   ├── haproxy
│       │   │   ├── haproxy-1.6.11.tar.gz
│       │   │   └── haproxy.cfg
│       │   ├── install.sls
│       │   └── service.sls
│       ├── _modules
│       │   └── getDisk.py##############
。。。

5.模块调用(master端)

[root@rhel65-lockey1 salt]#  salt rhel65-lockey5 getDisk.df
rhel65-lockey5:
    Filesystem                    Size  Used Avail Use% Mounted on
    /dev/mapper/VolGroup-lv_root   18G  2.1G   15G  13% /
    tmpfs                         246M   32K  246M   1% /dev/shm
    /dev/sda1                     485M   34M  426M   8% /boot

二、将数据存储到mysql服务器

master端执行命令,minion端将结果存入远程数据库并发送一份到master端

1. 在minion端安装MySQL-python 以及 mysql客户端

[root@rhel65-lockey1 salt]# salt rhel65-lockey5 cmd.run "yum install MySQL-python mysql -y"

2. 设置数据存储(minion端)

[root@rhel65-lockey5 minion]# vim /etc/salt/minion#添加以下内容

mysql.host: '172.25.5.91'
mysql.user: 'salt'
mysql.pass: 'lockey23'
mysql.db: 'salt'
mysql.port: 3306

[root@rhel65-lockey5 minion]# /etc/init.d/salt-minion restart

3. 在另外一台主机安装mysql-server

[root@rhel65-lockey1 salt]# yum install mysql-server -y
[root@rhel65-lockey1 salt]# /etc/init.d/mysqld start
[root@rhel65-lockey1 salt]# mysql_secure_installation#安全设置

建表授权

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;

mysql> grant all on salt.* to salt@’172.25.5.%’ identified by ‘lockey23’;

4. 在master端执行命令,然后在数据库中验证返回结果是否已经存储

[root@rhel65-lockey1 salt]# salt '*' grains.item --return mysql

通过master将minion发送过来的数据写入数据库

关闭minion端的mysql新加参数并且重新启动服务

master端安装MySQL-python并且在/etc/salt/master文件中写入一下内容:

master_job_cache: mysql
mysql.host: '172.25.5.91'
mysql.user: 'salt'
mysql.pass: 'lockey23'
mysql.db: 'salt'
mysql.port: 3306

重新启动服务,然后执行任意命令如:salt ‘*’ grains.items
检查数据库中是否有新数据写入

mysql> select * from salt_returns;

三、salt-syndic拓展

master(master172.25.5.91;syndic_master:172.25.5.92)

[root@rhel65-lockey1 salt]# yum install salt-syndic -y
[root@rhel65-lockey1 salt]# cat /etc/salt/master |grep syndic_master

syndic_master: 172.25.5.92###此配置需要改为你的超级master的ip
#syndic_master_port: 4506

[root@rhel65-lockey1 salt]# /etc/init.d/salt-syndic start
Starting salt-syndic daemon: [ OK ]

[root@rhel65-lockey1 salt]# salt-key -L

Accepted Keys:
rhel65-lockey3
rhel65-lockey4
rhel65-lockey5
Denied Keys:
Unaccepted Keys:
Rejected Keys:

[root@rhel65-lockey2 minion]# salt-key -L

Accepted Keys:
rhel65-lockey1
Denied Keys:
Unaccepted Keys:
Rejected Keys:

[root@rhel65-lockey2 minion]# vim /etc/salt/master#开启以下选项

pillar_roots:
  base:
    - /srv/pillar
file_roots:
  base:
    - /srv/salt

[root@rhel65-lockey2 minion]# salt ‘*’ test.ping#测试

rhel65-lockey3:
    True
rhel65-lockey5:
    True
rhel65-lockey4:
    True

四、salt-ssh

不需要salt-master或者salt-minino进程

[root@rhel65-lockey1 salt]# yum install salt-ssh -y
[root@rhel65-lockey1 salt]# cat /etc/salt/roster ##做salt-ss认证配置

# Sample salt-ssh config file
#web1:
#  host: 192.168.42.1 # The IP addr or DNS hostname
#  user: fred         # Remote executions will be executed as user fred
#  passwd: foobarbaz  # The password to use for login, if omitted, keys are used
#  sudo: True         # Whether to sudo to root, not enabled by default
#web2:
#  host: 192.168.42.2
rhel65-lockey5:
  host: 172.25.5.95
  user: root
  passwd: redhat

[root@rhel65-lockey1 salt]# salt-ssh rhel65-lockey5 cmd.run ‘ls’ -i#测试(在关闭master与minion的情况下)

rhel65-lockey5:
    anaconda-ks.cfg
    install.log
    install.log.syslog

五、 ###salt-api

[root@rhel65-lockey1 ~]# yum installl python-cherrypy salt-api -y
[root@rhel65-lockey1 ~]# salt-api –version
[root@rhel65-lockey1 ~]# cd /etc/pki/tls/private
[root@rhel65-lockey1 ~]# openssl genrsa 2048 > localhost.key
[root@rhel65-lockey1 ~]# cd /etc/pki/tls/certs
[root@rhel65-lockey1 ~]# make testcert

自动化运维工具Saltstack学习笔记(salt-ssh/salt-api/salt-syndic)_第1张图片
[root@rhel65-lockey1 ~]# vim /etc/salt/master
default_include: master.d/*.conf
[root@rhel65-lockey1 ~]# useradd saltapi
[root@rhel65-lockey1 ~]# passwd saltapi
[root@rhel65-lockey1 ~]# cat /etc/salt/master.d/api.conf

rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost.key

[root@rhel65-lockey1 ~]# cat /etc/salt/master.d/eauth.conf

external_auth:
  pam:
    saltapi:
      - .*
      - '@wheel'
      - '@runner'
      - '@jobs'

[root@rhel65-lockey1 ~]# /etc/init.d/salt-master restart
[root@rhel65-lockey1 ~]# /etc/init.d/salt-api start
[root@rhel65-lockey1 ~]# python saltapi.py

# -*- coding: utf-8 -*-

import urllib2,urllib
import time

try:
    import json
except ImportError:
    import simplejson as json

class SaltAPI(object):
    __token_id = ''
    def __init__(self,url,username,password):
        self.__url = url.rstrip('/')
        self.__user = username
        self.__password = password

    def token_id(self):
        ''' user login and get token id '''
        params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
        encode = urllib.urlencode(params)
        obj = urllib.unquote(encode)
        content = self.postRequest(obj,prefix='/login')
        try:
            self.__token_id = content['return'][0]['token']
        except KeyError:
            raise KeyError

    def postRequest(self,obj,prefix='/'):
        url = self.__url + prefix
        headers = {'X-Auth-Token'   : self.__token_id}
        req = urllib2.Request(url, obj, headers)
    opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        return content

    def list_all_key(self):
        params = {'client': 'wheel', 'fun': 'key.list_all'}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        minions = content['return'][0]['data']['return']['minions']
        minions_pre = content['return'][0]['data']['return']['minions_pre']
        return minions,minions_pre

    def delete_key(self,node_name):
        params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        ret = content['return'][0]['data']['success']
        return ret

    def accept_key(self,node_name):
        params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        ret = content['return'][0]['data']['success']
        return ret
   def remote_noarg_execution(self,tgt,fun):
        ''' Execute commands without parameters '''
        params = {'client': 'local', 'tgt': tgt, 'fun': fun}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        ret = content['return'][0][tgt]
        return ret

    def remote_execution(self,tgt,fun,arg):
        ''' Command execution with parameters '''
        params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        ret = content['return'][0][tgt]
        return ret

    def target_remote_execution(self,tgt,fun,arg):
        ''' Use targeting for remote execution '''
        params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        jid = content['return'][0]['jid']
        return jid

    def deploy(self,tgt,arg):
        ''' Module deployment '''
        params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        return content

    def async_deploy(self,tgt,arg):
        ''' Asynchronously send a command to connected minions '''
        params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        jid = content['return'][0]['jid']
        return jid

    def target_deploy(self,tgt,arg):
        ''' Based on the node group forms deployment '''
        params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
        obj = urllib.urlencode(params)
        self.token_id()
        content = self.postRequest(obj)
        jid = content['return'][0]['jid']
        return jid

def main():
    sapi = SaltAPI(url='https://172.25.5.91:8000',username='saltapi',password='lockey23')
    sapi.token_id()

    print sapi.list_all_key()
    #sapi.delete_key('test-01')
    #sapi.accept_key('test-01')
    sapi.deploy('rhel65-lockey5','httpd.web')
    print 'httpd deployed'
    #print sapi.remote_noarg_execution('test-01','grains.items')

if __name__ == '__main__':
    main()

[root@rhel65-lockey1 httpd]# cat /srv/salt/httpd/web.sls

apache:
  pkg.installed:
    - pkgs:
      - httpd
      - php
  service.running:
    - name: httpd
    - enable: true
    - reload: true
    - watch:
      - file: apache
  file.managed:
    - name: /etc/httpd/conf/httpd.conf
    - source: salt://httpd/files/httpd.conf
    - mode: 644
    - user: root
    - group: root

[root@rhel65-lockey1 ~]# python saltapi.py

([u'rhel65-lockey3', u'rhel65-lockey4', u'rhel65-lockey5'], [])
httpd deployed

你可能感兴趣的:(运维,运维开发,实用工具)