代码发布基本流程

1. 安装saltstack

1. 安装salt-master
    yum install salt-master
2. 修改配置文件:/etc/salt/master
    interface: 0.0.0.0    # 表示Master的IP 
3. 启动
    service salt-master start
master
1. 安装salt-minion
    yum install salt-minion

2. 修改配置文件 /etc/salt/minion
    master: 10.211.55.4           # master的地址
    或
    master:
        - 10.211.55.4
        - 10.211.55.5
    random_master: True

    id: c2.salt.com                    # 客户端在salt-master中显示的唯一ID
3. 启动
    service salt-minion start
minion
master:
    salt-master -l debug 
minion:
    以日志形式打开:
        salt-minion -l debug 

master防火墙需要关闭:
    firewall-cmd --state #查看默认防火墙状态
    systemctl stop firewalld.service

2. 授权

salt-key -L                    # 查看已授权和未授权的slave
salt-key -a  salve_id      # 接受指定id的salve
salt-key -r  salve_id      # 拒绝指定id的salve
salt-key -d  salve_id      # 删除指定id的salve
View Code

3. 执行命令

salt 'c2.salt.com' cmd.run  'ifconfig'
View Code
import salt.client
local = salt.client.LocalClient()
result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])
View Code

4. grains

    静态值:最开始执行一次后,默认永远是当前值。

            - SSDs
            - biosreleasedate
            - biosversion
            - cpu_flags
            - cpu_model
            - cpuarch
            - disks
            - dns
            - domain
            - fqdn
            - fqdn_ip4
            - fqdn_ip6
            - gid
            - gpus
            - groupname
            - host
            - hwaddr_interfaces
            - id
            - init
            - ip4_gw
            - ip4_interfaces
            - ip6_gw
            - ip6_interfaces
            - ip_gw
            - ip_interfaces
            - ipv4
            - ipv6
            - kernel
            - kernelrelease
            - kernelversion
            - locale_info
            - localhost
            - lsb_distrib_codename
            - lsb_distrib_id
            - machine_id
            - manufacturer
            - master
            - mdadm
            - mem_total
            - nodename
            - num_cpus
            - num_gpus
            - os
            - os_family
            - osarch
            - oscodename
            - osfinger
            - osfullname
            - osmajorrelease
            - osrelease
            - osrelease_info
            - path
            - pid
            - productname
            - ps
            - pythonexecutable
            - pythonpath
            - pythonversion
            - saltpath
            - saltversion
            - saltversioninfo
            - selinux
            - serialnumber
            - server_id
            - shell
            - swap_total
            - systemd
            - uid
            - username
            - uuid
            - virtual
            - zfs_support
            - zmqversion
内置grains
自定义:minion
                vim /srv/salt/_grains/xx.py

                    import time
                    def xxo():
                        s = {}
                        s['xkkkkkkkkkkkkk1'] = str(time.time())
                        s['xkkkkkkkkkkkkk2'] = 123
                        return s

                PS: 在master上执行 salt '*' saltutil.sync_grains 同步创建granins
自定义:master
        salt '*' grains
        salt '*' grains.ls
        salt '*' grains.get 'xkkkkkkkkkkkkk1'

5. pillar

        内置pillar
            vim /etc/salt/master
                pillar_opt: True

            PS: 重启生效
内置pillar
            vim /srv/pillar/top.sls
                base:
                  'c*':
                    - apache

            vim /srv/pillar/apache.sls
                x1:
                {% if grains['os_family'] == 'Debian' %}
                  apache: apache_1
                  {% elif grains['os_family'] == 'RedHat' %}
                  apache: httpd_2
                  {% elif grains['os'] == 'Arch' %}
                  apache: apache_3
                {% endif %}
                x2:
                {% if grains['ip_interfaces'].get('eth0')[0].startswith('10.10') %}
                  nameservers: ['10.10.9.31','10.10.9.135']
                  zabbixserver: ['10.10.9.234']
                {% else %}
                  nameservers: ['10.20.9.75']
                  zabbixserver: ['10.20.9.234']
                {% endif %}


            PS: 刷新 salt '*' saltutil.refresh_pillar
自定义pillar
            vim /etc/salt/master
                ext_pillar:
                    - wupeiqi:
                    或
                    - wupeiqi:{api:http://www.oldbody.com}
            vim /usr/lib/python2.7/site-packages/salt/pillar/wupeiqi.py
                import time
                import commands
                import salt.client

                def ext_pillar(minion_id,pillar,*args,**kwargs):

                    local = salt.client.LocalClient()
                    result = local.cmd(minion_id, 'cmd.run', ['ifconfig'])
                    return {'ifconfig':result.get(minion_id)}

            PS: 修改配置文件后,需要重启
自定义ext_pillar

6. state

state是Saltstack最核心的功能,通过预先定制好的sls(salt state file)文件对被控制主机进行状态管理,支持包括程序包(pkg)、文件(file)、网络配置(network)、系统服务(service)、系统用户(user)等。

/data/lvue:
  file:
    - managed
    - source: salt://luffy_vue/files/lvue
    - user: root
    - makedirs: True
    - mode: 644
/srv/salt/模块名称/init.sls
xxxxxx:
  file.recurse:
    - name: /data/codes
    - source: salt://luffy_vue/files/video
    - user: root
    - makedirs: True
    - file_mode: 644
    - dir_mode: 755
/srv/salt/模块名称/init.sls
# 执行top.sls
    salt "*" state.highstate

# 执行单独模块
    salt 'c1.com' state.sls 模块名称
    salt 'c1.com' state.sls saltenv='prod' 模块名称

7. 基于git发布流程:

    1. 在master上拉代码
        如果文件存在,pull;否则clone
        subprocess.check_call('git clone https://gitee.com/wupeiqi/video.git', cwd='/Users/wupeiqi/PycharmProjects/sansa', shell=True)

    2. build
        使用编译器进行编译

    3. 软连接到saltstack

        ln -s /data/codes/video /srv/salt/luffy_vue/files/video
    3. 将代码推送到指定机器
        xxxxxx:
          file.recurse:
            - name: /data/codes
            - source: salt://luffy_vue/files/video
            - user: root
            - makedirs: True
            - file_mode: 644
            - dir_mode: 755

        salt 'c1.com' state.sls luffy_vue

    4. 将代码推送到所有机器
        salt '*' state.sls luffy_vue

8. 代码同步

在master上编写如下state:

code/
├── files
│   ├── code_publisher.py
│   └── luffy(程序目录)
│          └── run.py
└── init.sls

sync_file:
  file.recurse:
    - name: /data/new/{{pillar['appname']}}
    - source: salt://s7code/files/{{pillar['appname']}}
    - user: root
    - makedirs: True
    - file_mode: 644
    - dir_mode: 755
sync_online_script:
  file.managed:
    - name: /data/script/code_publisher.py
    - source: salt://s7code/files/code_publisher.py
    - user: root
    - makedirs: True
    - file_mode: 644

run_online_script:
  cmd.run:
    - name: /usr/bin/python /data/script/code_publisher.py {{pillar['appname']}}


xxxxxxxx:
  cmd.run:
    - name: nohup /usr/bin/python run.py >/dev/null 2>&1 &
    - cwd: /data/{{pillar['appname']}}
/srv/salt/code/init.sls
# 程序目录
/srv/salt/code/files/
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
1. salt state进行文件同步
2. 线上代码移动到 程序-4 名称
3. 新代码移动到线上目录
4. 杀掉原进程
5. 修改文件名
"""
import os
import sys
import signal
import shutil
from subprocess import check_output, CalledProcessError


def online_to_backup4(app_name):
    """
    线上代码移动到备份4
    :return:
    """

    # 检查是否存在线上代码(新服务器没有)
    online_path = '/data/%s' % app_name
    if not os.path.exists(online_path):
        return

    # 创建备份目录
    backup_path = "/data/backup/%s/" % app_name
    if not os.path.exists(backup_path):
        os.makedirs(backup_path)

    # 线上代码移动到备份4
    shutil.move('/data/%s' % app_name, '/data/backup/%s/%s-4' % (app_name, app_name,))


def new_to_online(app_name):
    """
    新代码移动到线上
    :return:
    """
    # 检查是否有线上目录,没有则创建
    online_path = "/data"
    if not os.path.exists(online_path):
        os.makedirs(online_path)
    # 新代码移动到线上
    os.rename('/data/new/%s' % app_name, '/data/%s' % (app_name,))
    # shutil.move(('/data/new/%s' % app_name, '/data/%s' % (app_name,))


def rename_backup_name(app_name):
    """
    备份文件命名:备份-1、备份-2、备份-3
    :param app_name:
    :return:
    """
    base_path = "/data/backup/%s" % app_name
    for i in range(1, 5):
        # 1/2/3/4
        folder_name = "%s-%d" % (app_name, i,)
        folder_path = os.path.join(base_path, folder_name)

        if not os.path.exists(folder_path):
            continue
        if i == 1:
            # 删除 xx-1
            shutil.rmtree(folder_path)
            continue
        # 2/3 都减1
        new_folder_name = "%s-%d" % (app_name, i - 1,)
        new_folder_path = os.path.join(base_path, new_folder_name)

        shutil.move(folder_path, new_folder_path)


def get_pid_list(name):
    """
    获取指定进程PID
    :param name:
    :return:
    """
    try:
        output = check_output("pgrep -f '%s'" % (name), shell=True)
    except CalledProcessError as ex:
        output = None
    if not output:
        return []
    return map(int, output.split())


def kill_9(name):
    """
    杀死指定进程
    :param name:
    :return:
    """
    for pid in get_pid_list(name):
        try:
            os.kill(pid, signal.SIGKILL)
        except OSError as e:
            pass


def run():
    app_name = sys.argv[1]

    # 拷贝
    online_to_backup4(app_name)
    new_to_online(app_name)

    # 杀进程
    kill_9('/usr/bin/python run.py')

    # 删除第一备份
    rename_backup_name(app_name)


if __name__ == '__main__':
    run()
/srv/salt/code/code_publisher.py

执行上下的命令:

salt '*' state.sls code  pillar='{"appname": "luffy"}'

import salt.client
local = salt.client.LocalClient()
returns = local.cmd_batch('*', 'state.highstate', batch='10%')
print(returns)

  

 

 

 

posted @ 2016-06-12 10:32  武沛齐  阅读(1066)  评论(0编辑  收藏  举报