zoukankan      html  css  js  c++  java
  • saltstack--史上最细致安装攻略!亲测无坑

    准备一台虚拟机node1:

    [root@linux-node1 pillar]# ifconfig
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.88.137  netmask 255.255.255.0  broadcast 192.168.88.255
            inet6 fe80::20c:29ff:fe77:92aa  prefixlen 64  scopeid 0x20<link>
            ether 00:0c:29:77:92:aa  txqueuelen 1000  (Ethernet)
            RX packets 28126  bytes 23077587 (22.0 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 13213  bytes 10010104 (9.5 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            inet6 ::1  prefixlen 128  scopeid 0x10<host>
            loop  txqueuelen 0  (Local Loopback)
            RX packets 4692  bytes 6061530 (5.7 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 4692  bytes 6061530 (5.7 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    配置网卡

    cd /etc/sysconfig/network-scripts
    vim ifcfg-eno16777736
    TYPE="Ethernet"
    BOOTPROTO="static"
    DEFROUTE="yes"
    PEERDNS="yes"
    PEERROUTES="yes"
    IPV4_FAILURE_FATAL="no"
    IPV6INIT="yes"
    IPV6_AUTOCONF="yes"
    IPV6_DEFROUTE="yes"
    IPV6_PEERDNS="yes"
    IPV6_PEERROUTES="yes"
    IPV6_FAILURE_FATAL="no"
    NAME="ens33"
    # UUID="d283cefc-7d4c-427e-8c5d-245cf481e494"
    DEVICE="ens33"
    ONBOOT="yes"
    IPADDR=192.168.88.137
    NETMASK=255.255.255.0
    GATEWAY=192.168.88.2
    systemctl restart network
    systemctl disable firewalld
    systemctl disable NetworkManager

    设置主机名
    vim /etc/hostname
    linux-node1.example.com

    设置主机域名解析

    vim /etc/hosts

    192.168.88.137  linux-node1 linux-node1.example.com
    192.168.88.138  linux-node2 linux-node2.example.com

    设置DNS

    vim /etc/resolv.conf

    # Generated by NetworkManager
    search localdomain example.com
    nameserver 192.168.88.2

    安装最新 epel yum 源

          rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

    yum安装 一些基础包

           yum -y install net-tools vim lrzsz tree screen lsof tcpdump nc mtr nmap

    关闭selinux:vim /etc/selinux/config 

    SELINUXTYPE=targeted
    SELINUX=disabled
    setenforce 0
    systemctl stop firewalld

    重启系统

          yum update -y && reboot          # 升级所有包同时也升级软件和系统内核, 并重启

    确认是否一些服务是否已按计划关闭

          getenforce          # selinux是否关闭

     

    对node1进行克隆:node2

    对node2的操作:

      设置主机名:vim /etc/hostname

    linux-node1.example.com

      修改网卡配置:vim /etc/sysconfig/network-scripts/ifcfg-eno16777736

    IPADDR=192.168.88.138

      重启:

      reboot

    在linux-node1 中安装saltstack master 和 minion

            yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm 

            yum -y install salt-master salt-minion

    在linux-node2 中安装saltstack minion

            yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm 

            yum -y install salt-minion

    在linux-node1中配置 salt-minion

             vim /etc/salt/minion

    master: 192.168.88.137
    id: linux-node1.example.com

    在linux-node2中配置 salt-minion     

             vim /etc/salt/minion

    master: 192.168.88.137
    id: linux-node2.example.com

    启动linux-node1中salt-maser 和 salt-minion

            systemctl start salt-master       # 启动salt-master

            systemctl enable salt-master       # 设置salt-master开机自启动

            systemctl start salt-minion        # 启动

            systemctl enable salt-minion     # 开机自启动

    启动linux-node2中salt-minion

            systemctl start salt-minion        # 启动

            systemctl enable salt-minion      # 开机自启动

    认证(node1):(在这里遇到了关于ascii编码的错误,解决办法已经记录到博客:https://www.cnblogs.com/lutt/p/11253487.html)

            salt-key             # 在master中查看所有key的状态

            salt-key -a linux-node1.example.com      # 认证 linux-node1.example.com的key

            salt-key -A          # 一次性认证所有key

    远程执行测试(node1)

             salt  *  test.ping         # 测试saltstack minion与master的连通性

             salt * cmd.run 'df -h'     # 在所有minion中批量执行 df -h 命令

             salt '*'   cmd.run 'free -m'     实现远程命令执行

    cp模块(node1)

          功能: 实现远程文件、目录复制,下载Url文件等操作

    # 1、master配置同步根目录(YAML语法,1. 每一级使用两个空格 2. 短横线表示列表)
    vim /etc/salt/master
    
    file_roots:
      base:
        - /srv/salt
      dev:
        - /srv/salt/dev
    
    systemctl restart salt-master  # 需要重启master
        
    # 2、创建同步目录文件夹,和测试文件 /srv/salt/test.sh
    mkdir -p /srv/salt/dev
    vim /srv/salt/test.sh   #创建测试文件
    
    # 3、将 /srv/salt/ 下的test.sh文件同步到所有minion
    salt '*' cp.get_file salt://test.sh /tmp/test.sh
    
    
    # 4、创建目录 makedirs(当分发的位置在目标主机上不存在时,自动创建该目录)
    salt '*' cp.get_file salt://test.sh /aaa/test.sh makedirs=True
    
    # 5、将 /srv/salt 中的testdir 目录复制到所有minion
    mkdir /srv/salt/testdir/
    salt '*' cp.get_dir salt://testdir /aaa/
    
    # 6、下载百度首页内容保存到所有minion中
     salt '*' cp.get_url http://www.baidu.com /tmp/index.html

    状态管理(node1)(神笔马良)

        1)修改 /etc/salt/master 文件

    # 1、master配置同步根目录(YAML语法,1. 每一级使用两个空格 2. 短横线表示列表)
    vim /etc/salt/master
    
    file_roots:
      base:
        - /srv/salt
      dev:
        - /srv/salt/dev
    
    systemctl restart salt-master  # 需要重启master

        2)在 /srv/salt/ 下配置状态管理

            [root@linux-node1 /]#  vim /srv/salt/web/apache.sls

    # 1.描述了要装一个httpd服务
    apache-install:  # 这个是一个名称,可以随便写
      pkg.installed:  # pkg是状态模块,installed是状态模块中的方法
        - name: httpd  # 描述了我在里要装一个httpd包
    
    # 2.描述了httpd服务是启动状态,并且是开机自启动状态
    apache-service:  # 这个是一个名称,可以随便写
      service.running:  # 描述了httpd服务是运行的状态
        - name: httpd
        - enable: True  # 描述httpd服务开机自动启动

        3)在 salt-master中执行命令让 linux-node2按照描述完成按照

            [root@linux-node1 web]# salt   linux-node2.example.com  state.sls  web.apache

    Service模块(node1)

          salt '*' service.reload nginx

    安装(master和minion中都需要安装)

           yum -y install salt-ssh

    配置花名册,配置要管理的机器

           vim /etc/salt/roster

    # 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
    
    
    linux-node1.example.com:
      host: 192.168.88.137
      user: root
      passwd: chnsys@2016
      port: 22
    
    linux-node2.example.com:
      host: 192.168.88.138
      user: root
      passwd: chnsys@2016
      port: 22

    自定义grains:需要重启 minion(这一步报错Minion did not return. [No response] ERROR: Minions returned with non-zero exit code,解决方案:node1和node2都需要执行配置文件)

    # 1、编辑 minion 文件,配置角色名
    vim /etc/salt/minion
    
    grains:
      roles: apache
    
    
    # 2、重启minion
    systemctl restart salt-minion
    
    # 3、查看所有机器都有哪些roles
    [root@linux-node1 ~]# salt '*' grains.item roles
    linux-node1.example.com:
        ----------
        roles:
            apache
    linux-node2.example.com:
        ----------
        roles:
    
    # 4、让所有角色为apache的机器执行命令'w',-G表示以grains进行目标选择
    salt -G 'roles:apache' cmd.run 'w'  

    自定义grains:无需重启minion

    # 1、在minion中新建文件/etc/salt/grains,添加一个 key value
    vim /etc/salt/grains
    
    test-grains: test-grains-value
    
    
    # 2、让minion到所有grains中读取配置
    salt '*' saltutil.sync_grains
    
    # 3、查看所有 key为test-grains的minion
    [root@linux-node1 ~]# salt '*' grains.item test-grains
    linux-node1.example.com:
        ----------
        test-grains:
            test-grains-value
    linux-node2.example.com:
        ----------
        test-grains:
        
    # 4、让所有key=test-grains value=test-grains-value 的机器执行命令'w',-G表示以grains进行目标选择
    salt -G 'test-grains:test-grains-value' cmd.run 'w' 

    在master配置文件中指定pillar位置(node1):

    vim /etc/salt/master
    pillar_roots:
      base:
        - /srv/pillar

    systemctl restart salt-master
    mkdir /srv/pillar
    cd /srv/pillar

    vim /srv/pillar/apache.sls     # 编辑一个pillar文件
    {% if grains['os'] == 'CentOS' %}
    apache: httpd
    {% elif grains['os'] == 'Debian' %}
    apache: apache2
    {% endif %}
    vim top.sls   # 指定这个pillar文件给那个minion使用
    base:
      'linux-node2.example.com':
      - apache

    确认 pillar中配置的items是否生效(node1)

    [root@linux-node1 pillar]# salt '*' pillar.items       
    linux-node1.example.com:
        ----------
    linux-node2.example.com:
        ----------
        apache:
            httpd

    安装salt-api,并设置开机启动(node1)

          yum -y install salt-api pyOpenSSL

          systemctl enable salt-api

    配置自签名证书(node1)

          cd /etc/pki/tls/certs/

          make testcert

     

    Enter pass phrase:    ===>  输入加密短语,这里我使用salt2017
    Verifying - Enter pass phrase:    ===>  确认加密短语
    umask 77 ; 
    /usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
    Enter pass phrase for /etc/pki/tls/private/localhost.key:    ===>  再次输入相同的加密短语
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:BeiJing
    Locality Name (eg, city) [Default City]:BeiJing
    Organization Name (eg, company) [Default Company Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []:
    Email Address []:

    解密key文件,生成无密码的key文件

          注:过程中需要输入key密码,该密码为之前生成证书时设置的密码

          cd /etc/pki/tls/private/

          openssl rsa -in localhost.key -out localhost_nopass.key

    修改文件权限

          chmod 755 /etc/pki/tls/certs/localhost.crt 
          chmod 755 /etc/pki/tls/private/localhost.key 
          chmod 755 /etc/pki/tls/private/localhost_nopass.key

    添加用户

           注:生产环境请使用密码复杂度高的密码,这里我使用 chnsys@2016

          useradd -M -s /sbin/nologin saltapi          # 创建用户 saltapi

          passwd saltapi                                    # 为用户saltapi设置密码

            # 这里我设置的密码也是saltapi

    配置salt-api

          sed -i '/#default_include/s/#default/default/g' /etc/salt/master

    创建/etc/salt/master.d/目录    

          mkdir -p /etc/salt/master.d/
          cd /etc/salt/master.d/
          touch eauth.conf
          touch api.conf

    vim eauth.conf

    external_auth:
      pam:
        saltapi:   # 用户
          - .*     # 该配置文件给予saltapi用户所有模块使用权限,出于安全考虑一般只给予特定模块使用权限

    vim api.conf

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

    启动salt-api

          systemctl restart salt-master
          systemctl start salt-api
          ps -ef|grep salt-api
          netstat -lnput|grep 8001

    测试获取token

          curl -k https://192.168.88.137:8001/login -H "Accept: application/x-yaml"  -d username='saltapi'  -d password='saltapi'  -d eauth='pam'

    调用test.ping

          curl -k https://192.168.88.137:8001/ -H "Accept: application/x-yaml" -H "X-Auth-Token: 87cbb68e0babf3d0ad6b3741795667dbe62b3c11" -d client='local' -d tgt='*' -d fun='test.ping'

    在window环境下使用python简单测试接口执行命令

    # _*_ coding:utf-8 _*_
    
    # 使用python简单测试接口执行命令
    __author__ = 'junxi'
    
    
    import requests
    import json
    try:
        import cookielib
    except:
        import http.cookiejar as cookielib
    
    # 使用urllib2请求https出错,做的设置
    import ssl
    context = ssl._create_unverified_context()
    
    # 使用requests请求https出现警告,做的设置
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    
    
    salt_api = "https://192.168.88.137:8001/"
    
    
    class SaltApi:
        """
        定义salt api接口的类
        初始化获得token
        """
        def __init__(self, url):
            self.url = url
            self.username = "saltapi"
            self.password = "saltapi"
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
                "Content-type": "application/json"
            }
            self.params = {'client': 'local', 'fun': '', 'tgt': ''}
            self.login_url = salt_api + "login"
            self.login_params = {'username': self.username, 'password': self.password, 'eauth': 'pam'}
            self.token = self.get_data(self.login_url, self.login_params)['token']
            self.headers['X-Auth-Token'] = self.token
    
        def get_data(self, url, params):
            send_data = json.dumps(params)
            request = requests.post(url, data=send_data, headers=self.headers, verify=False)
            response = request.json()
            result = dict(response)
            return result['return'][0]
    
        def salt_command(self, tgt, method, arg=None):
            """远程执行命令,相当于salt 'client1' cmd.run 'free -m'"""
            if arg:
                params = {'client': 'local', 'fun': method, 'tgt': tgt, 'arg': arg}
            else:
                params = {'client': 'local', 'fun': method, 'tgt': tgt}
            print('命令参数: ', params)
            result = self.get_data(self.url, params)
            return result
    
    def main():
        salt = SaltApi(salt_api)
        salt_client = '*'
        salt_test = 'test.ping'
        result1 = salt.salt_command(salt_client, salt_test)
        print(result1)
        # 返回结果:{u'linux-node1.example.com': True, u'linux-node2.example.com': True}
    
    if __name__ == '__main__':
        main()
    “”“
    命令参数:  {'client': 'local', 'fun': 'test.ping', 'tgt': '*'}
    {'linux-node1.example.com': True, 'linux-node2.example.com': True}
    ”“”

    使用requests模块获取基本信息

    # -*- coding: utf-8 -*-
    import requests
    import json
    import logging
    logging.captureWarnings(True)  # 屏蔽由于访问https时没有证书警告问题
    
    SALT_BASE_URL = 'https://192.168.88.137:8001/'
    SALT_USER = 'saltapi'
    SALT_PWD = 'saltapi'
    
    
    class SaltAPI(object):
        __token_id = ''
    
        def __init__(self):
            self.__url = SALT_BASE_URL
            self.__user = SALT_USER
            self.__password = SALT_PWD
    
        def token_id(self):
            """
                用户登陆和获取token
            :return:
            """
            params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
            content = self.postRequest(self.__url + '/login', data=params)
            try:
                self.__token_id = content[0]['token']
            except Exception as e:
                print('**** Failed to get token, {} ****'.format(str(e)))
    
        def postRequest(self, url, data=None):
            headers = {"X-Auth-Token": self.__token_id}
            ret = requests.post(url=url, data=data, json='json', headers=headers, verify=False)
            if ret.status_code == 200:
                return ret.json()['return']
            return ret.text
    
        def remote_execution_module(self, tgt, fun, arg):
            """
                远程执行模块,有参数
            :param tgt: minion list
            :param fun: 模块
            :param arg: 参数
            :return: dict, {'minion1': 'ret', 'minion2': 'ret'}
            """
            params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
            self.token_id()
            return self.postRequest(self.__url, params)
    
        def salt_alive(self, tgt):
            '''
            salt主机存活检测
            '''
            params = {'client': 'local', 'tgt': tgt, 'fun': 'test.ping'}
            self.token_id()
            return self.postRequest(self.__url, params)
    
    
    if __name__ == '__main__':
        salt = SaltAPI()
        minions_list = [
            'cloud:type',
            'cluster:domain',
            'cluster:name',
            'cpu_model',
            'fqdn_ip4',
            'hospital:type',
            'kernelrelease',
            'nodename',
            'os',
            'osmajorrelease',
            'osrelease',
            'saltversion',
            'serialnumber',
            'virtual',
            'num_cpus',
            'mem_total',
            'cloud:region',
            'ipv4',
        ]
        ret = salt.remote_execution_module('*', 'grains.item', minions_list)
        print(json.dumps(ret, ensure_ascii=False))
    “”“
    [{"linux-node1.example.com": {"osrelease": "7.2.1511", "fqdn_ip4": ["192.168.88.137"], "saltversion": "2019.2.0", "nodename": "linux-node1.example.com", "kernelrelease": "3.10.0-327.el7.x86_64", "cloud:type": "", "num_cpus": 1, "serialnumber": "VMware-56 4d 55 21 2f 96 95 44-0b 50 ca d3 bc 77 92 aa", "cpu_model": "Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz", "virtual": "VMware", "cluster:name": "", "cluster:domain": "", "mem_total": 977, "osmajorrelease": 7, "hospital:type": "", "os": "CentOS", "ipv4": ["127.0.0.1", "192.168.88.137"], "cloud:region": ""}, "linux-node2.example.com": {"osrelease": "7.2.1511", "fqdn_ip4": ["192.168.88.137"], "saltversion":
    "2019.2.0", "nodename": "linux-node1.example.com", "kernelrelease": "3.10.0-327.el7.x86_64", "cloud:type": "", "num_cpus": 1, "serialnumber": "VMware-56 4d 79 5a 39
    fd 5a 16-6c 12 59 28 02 73 fe 04", "cpu_model": "Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz", "virtual": "VMware", "cluster:name": "", "cluster:domain": "", "mem_total": 977, "osmajorrelease": 7, "hospital:type": "", "os": "CentOS", "ipv4": ["127.0.0.1", "192.168.88.138"], "cloud:region": ""}}]
    ”“”

     

     

    原文链接:

    https://www.cnblogs.com/xiaonq/p/10233439.html#i3
    https://www.cnblogs.com/xiaonq/p/10316525.html

     

  • 相关阅读:
    python 复杂一点的装饰器
    python 装饰器
    python 歌词解析
    ATX 免越狱调试IOS和Android
    OpenCV库文件介绍
    NetEaseGame/ATX 的MD
    带你玩转Visual Studio——带你高效开发
    python 图像识别
    fatal: Authentication failed for又不弹出用户名和密码 解决办法
    lua luna工具库
  • 原文地址:https://www.cnblogs.com/lutt/p/11260822.html
Copyright © 2011-2022 走看看