• 学习saltstack (一)


    salt介绍

    Salt是一个基础平台管理工具
    
    Salt是一个配置管理系统,能够维护预定义状态的远程节点
    
    Salt是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据
    

    salt的核心功能

    是命令发送到远程系统,而且是并行发送不是串行的
    
    使用安全加密协议
    
    对网络要求比较低,使用最小最快的网络载荷
    
    提供简单的编程接口(salt使用python开发)
    

    salt的优点

    saltstack使用python语言编写,相当轻量级。 http://www.python.org
    
    saltstack通讯层采用ZeroMQ PUB-SUB pattern实现,使得它很快速。http://www.zearmq.org
    
    saltstack是开源的,通过python可以自己编写模块。
    

    salt端口说明

    salt-master启动时会启动两个端口
    
    4505:为salt的消息发布专用端口 
    4506:位客户端与服务端通信的端口。  ---监控此端口可以监控哪些minion收到的消息,并回复了结果。
    

    实验图解

    安装saltstack

    1、安装指定epel源
        baseurl=http://repo.saltstack.com/yum/redhat/6.7/x86_64/
    2、安装master
        yum -y install salt-master
    3、安装minion
        yum -y install salt-minion
    

    配置saltstack

    1、修改minion配置文件
        vim /etc/salt/master 
        #master: salt         默认master配置的为salt,需在/etc/hosts中增加映射,也可以修改为master的IP地址或域名
        #id:              指定minion的标识, id要是唯一的,默认为主机名
        vim /etc/hosts
        192.168.4.16 salt        master端ip       
    2、修改master配置文件
        vim /etc/salt/master        
        log_level: debug      调试过程日志级别修改为debug级别,生产系统可根据实际情况配置
    3、启动服务
        /etc/init.d/salt-master start    先启动master端     
        /etc/init.d/salt-minion start
      ping salt 测试与master主机是否连通 备注:master端修改配置文件不用重启,默认直接生效

    服务端master命令

    salt-key        
                -a          #添加指定id
                -A          #添加全部
                -r          #拒绝指定id
                -R          #拒绝全部
                -d          #删除指定id
                -D          #删除全部
                -y          #去除每步操作确认的一步。
           -L      #列出所有的minion端的key
           -l      #列出特定minion端发过来的请求
    提示:无论是accept还是delete都支持Linux的shell通配符。

    SaltStack认证

                1、minion在第一次启动时,会在/etc/salt/pki/minion/下自动生成minion.pem(private key)和minion.pub(public key),然后将minion.pub发送给master。
                2、master在第一次启动时,会在/etc/salt/pki/master下自动生成master.pem。在接收到minion的public key后,
             通过salt-key命令accept minion public key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion id命名的public key,
             客户端会保存一份master的public key,在/etc/salt/pki/minion_master.pub 3、通过两个步骤的验证,master就能对minion发送指令了。

    实验一:修改主机名

    1、minion端:
    hostname salt-client-01
    sed -i 's#HOSTNAME=*#HOSTNAME=salt-client-01#g' /etc/sysconfig/network
    rm -rf /etc/salt/minion_id   /etc/salt/pki/*   
    /etc/init.d/salt-minion   restart
    2、master端:
    salt-key  -d  salt-client01 -y
    salt-key  -L
    salt-key  -A -y
    salt '*' test.ping    
    3、如果再master不删除minion的key,有可能minion程序启动后,会自动杀死自己。原因是:minion启动后,会生成自己的key(主机名、IP地址和一些其它信息联合生成的),
      当向master注册后,会保存一个master的key。当主机名修改后自己的key会改变,如果master不删除之前minion的key,不仅会注册失败,minion还会杀死自己的进程;
    4、minion的主机名会缓存到/etc/salt/minion_id文件里面,修改主机名后需要删除这个文件;
    

    实验二:迁移master主机

    思路(原理):
    1、对minion而言只认master服务器上的的key与minion自己保存的master的key是否有冲突,没有冲突就不会有问题
    2、minion要执向新的master的地址
    操作步骤:
    第一步:将masterold上的所有key文件打包上传到masternew服务器上,解压,然后重启master
        tar -zcvf pki.tar.gz /etc/salt/pki/
        scp pki.tar.gz 192.168.4.18:/etc/salt/pki/
        cd /etc/salt/;tar -xf  pki.tar.gz
        /etc/init.d/salt-master restart
        salt-key -L
    第二步:修改所有minion配置文件,将master执向新的地址
        salt '*' cmd.run "sed -i 's/16/18/g' /etc/hosts"
    第三步:验证是否修改成功
        salt '*' cmd.run 'grep salt /etc/hosts'
    第四步:重启所有minion服务
         salt '*' service.restart salt-minion
    第五步:在masternew上验证是否接管了所有minion
        salt '*' test.ping

    returnner (日志输出)

    默认情况下,发送给salt minion的命令执行结果将返回给salt master,Saltstack Returner的接口允许将结果发送给任意系统。
    可做minion的监控使用
    
    

    内置的returnner模块列表

            carbon_return       将结果返回给carbon接收器
                cassandea_return    将结果返回给Cassandra ColumnFamily
                local               将结果返回给本地的测试returner接口,即打印当前的结果
                mongo_future_return 将结果返回给mongodb
                mongo_return        将结果返回给mongodb
                mysql               将结果返回给MySQL
                postgres            将结果返回给postgres
                redis_return        将结果返回给redis
                sentry_return       将结果返回给sentry
                smtp_return         通过email返回salt数据
                syslog_return       将结果返回给操作系统的syslog facility

    实验三:returnner返回到syslog

    1、在salt-master执行命令:
        salt '*' test.ping --return syslog
    2、在salt-minion查看syslog日志
        tail -f /var/log/messages
    这个log会放在每一个minion中的  /var/log/messages  中 ,根本不是我们想要的结果

    实验四:returnner返回给mysql(单边模式)

     

    1、安装mysql(可以在master也可以在其它服务器)
        yum install –y mysql mysql-server
    2、启动mysql并设置root密码
        service mysqld start
        mysqladmin -u root password '123456'
    3、创建数据库,并授权
    --创建数据库
    CREATE DATABASE `salt`DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; 
    USE `salt`; 
    
    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; 
    
    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,KEY `id` (`id`),KEY `jid` (`jid`),KEY `fun` (`fun`) ) 
    ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --授权
    GRANT ALL PRIVILEGES ON salt.* to 'salt'@'%' identified by 'salt';
    flush privileges;
    4、修改所有minion配置文件,在配置文件结尾添加:
         cat /etc/salt/minion
        mysql.host: '192.168.4.16' 
        mysql.user: 'salt' 
        mysql.pass: 'salt' 
        mysql.db: 'salt' 
        mysql.port: 3306
    5、重启所有minion服务
        salt '*' service.restart salt-minion
    6、所有minion安装MySQL-python模块
         salt '*' cmd.run 'yum install -y MySQL-python'
    7、测试写入mysql
         salt '*' cmd.run 'hostname' --return mysql
    8、查看结果 
        mysql> select * from salt_returns;   

    event介绍

    event是一个本地的ZeroMQ PUB Interace,event是一个开放的系统,用于发送消息通知salt或其它操作系统。
    每个event都有一个标签。时间标签允许快速至顶过滤事件。除了标签之外,每个时间都有一个数据结构。这个数据结构是一个dict类型,其中包含关于事件的信息。
    salt-master发送命令到salt-minion,minion将命令结果发送给event,master从event读取返回结果,然后将结果写入mysql。

    系统结构图

    实验五:读取event接口,并写入到mysql

    event接口测试:
    1、在salt-master  /server/scripts  下新建test.py
        cat test.py
    import salt.utils.event
    event = salt.utils.event.MasterEvent('/var/run/salt/master')
    for data in event.iter_events(full=True):
        print(data)
        print '------'
    2、执行这个测试脚本
        python salt-event.py
    3、然后再开一个新的master终端进行salt操作:
        salt '*' cmd.run 'hostname'
    event-to-mysql测试
    1、安装MySQL软件,创建数据库,并授权,在master安装MySQL-python模块
    2、在master配置文件结尾添加如下配置:
        vi /etc/salt/master
    mysql.host: '192.168.4.18' 
    mysql.user: 'salt' 
    mysql.pass: 'salt' 
    mysql.db: 'salt' 
    mysql.port: 3306
    3、编写自定义returnn脚本
        vim salt_event_to_mysql.py
    #!/bin/env python
    #coding=utf8
    # Import python libs
    import json
    # Import salt modules
    import salt.config
    import salt.utils.event
    # Import third part libs
    import MySQLdb
    __opts__ = salt.config.client_config('/etc/salt/master')
    #create MySQL connect
    #conn = MySQLdb.connect(host=__opts__['mysql.host'],user=__opts__['mysql.user'],passwd=__opts__['mysql.pass'],db=__opts__['mysql.db'],port=__opts__['mysql.port'])
    
    conn = MySQLdb.connect(host='192.168.3.87',user='salt',passwd='salt',db='salt',port=3306)
    cursor = conn.cursor()
    # Listen Salt Master Event System
    event = salt.utils.event.MasterEvent(__opts__['sock_dir'])
    for eachevent in event.iter_events(full=True):
        ret = eachevent['data']
        if "salt/job/" in eachevent['tag']:
            #Return Event
            if ret.has_key('id') and ret.has_key('return'):
                #Ignore saltutil.find_job event
                if ret['fun'] == "saltutil.find_job":
                    continue
                sql = '''INSERT INTO `salt_returns`
                    (`fun`,`jid`,`return`,`id`,`success`,`full_ret` )
                    VALUES (%s,%s,%s,%s,%s,%s)'''
                cursor.execute(sql,(ret['fun'],ret['jid'],
                                    json.dumps(ret['return']),ret['id'],
                                    ret.get('success', False),json.dumps(ret)))
                cursor.execute("COMMIT")
        # Other Event
        else:
            pass
    注意:
    MySQLdb.connect(host=__opts__['mysql.host'],user=__opts__['mysql.user'],passwd=__opts__['mysql.pass'],db=__opts__['mysql.db'],
    port=__opts__['mysql.port']),要换成自己的实际数据库地址、数据库用户、密码,如: conn = MySQLdb.connect(host='10.80.0.162',user='salt',passwd='salt',db='salt',port=3306) python语言是根据缩进来识别语法的,上面脚本不要随意修改缩进,否则可能会出现各种各样的问题。 4、在master的后台执行自定义return脚本   python salt_event_to_mysql.py & 注意:常见报错处理“_mysql_exceptions.OperationalError: (1045, "Access denied for user 'salt'@'saltmaster' (using password: YES)")” #使用mysql-client登录mysql测试 #28000一般为mysql存在空用户导致,需要先删除空用户 5、开一个新的master终端进行测试   salt '*' test.ping 6、在mysql上看是否已经将数据写入数据库   select * from salt.salt_returns;
    官方例子:
    https://github.com/saltstack/salt/tree/develop/salt/returners
    https://docs.saltstack.com/en/latest/ref/returners/all/salt.returners.mysql.html

    分组

    • 当服务器非常多的时候,就需要分组,分组的方法如下,常用分组已标记为红色。
    letter 含义 例子
    G Grains glob匹配 G@os:Centos
    E PCRE正则匹配minion_id E@webd+.(dev|qa|prod).loc
    P PCRE正则匹配Grains P@os:(RedHat|Centos)
    L minion_id列表 L@vas01,vas02,vas03
    I pillar glob匹配 I@pdata:foobar
    S 子网/ip地址匹配 S@192.168.1.0/24 or S@192.168.1.100
    R Range cluster匹配 R@%foo.bar
    D minion data匹配,需要定义data D@key:value
    N 组+组匹配 N@group1 or N@group2

      

    1、修改master配置文件
        vim /etc/salt/master 
    nodegroups:
     test: 'salt0*'
    2、测试结果
     salt -N test   test.ping
    
    分组配置可以在单独的配置文件配置
    分组配置语法遵循YAML语言规范

    yaml语法三大规则

    规则一:缩进
    
      yaml使用一个固定的缩进风格表示数据层结构关系,Saltstack需要每个缩进级别由两个空格组成。一定不能使用tab键
    
    规则二:冒号
    
      yaml:
      mykey: my_value
      每个冒号后面一定要有一个空格(以冒号结尾不需要空格,表示文件路径的模版可以不需要空格)
    
    规则三:短横线
    
     想要表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一个列表的一部分
    
    my_dictionary:
    
    - list_value_one
    
    - list_value_two
    
    - list_value_three
    • 缩进:YAML使用一个固定的缩进风格表示数据层结构关系。Salt需要每个缩进级别由两个空格组成。不要使用tab。
    • 字典:Python的字典是简单的简直对。字典的keys在YAML中表现形式是以冒号结尾的字符串。values的表现形式是冒号下面的每一行,用一个空格隔开。
    • 列表:想要表示列表项,使用一个短横杠加一个控制。多个项使用相同的缩进级别作为同一列表的一部分。

    官方网址:http://docs.saltstack.cn/topics/yaml/index.html

    模块介绍

    1、salt查看帮助文档:
        salt 'salt01' sys.doc
    2、salt查看有哪些模块
        salt 'salt01'  sys.list_modules
    3、由于模块太多了,关于salt的模块可以参考官网:
    https://docs.saltstack.com/en/latest/ref/modules/all/
    http://blog.csdn.net/chengxuyuanyonghu/article/details/64519496

    文件系统

    1、修改配置文件
        vim /etc/salt/master
    file_roots:        默认格式
      base:            基础版
        - /srv/salt    脚本目录
    base:基础版  ---默认使用这个版本
    dev:开发版
    prod:产品版
    2、创建目录并测试脚本
        mkdir /srv/salt/etc/script
        cat test.sh 
    #!/bin/sh
    while true
    do 
        sleep 1
        echo 1 >> /tmp/1.log
    done
    执行脚本
     salt 'salt02' cmd.script salt://etc/script/test.sh
    注意:由于这个脚本会一直执行,master在执行这个脚本的时候命令不会退出,需要ctrl+c退出。minion端会生成一个tmp***.sh的脚本,minion实际运行的是这个脚本。所以master退出后不影响minion的运行。

    创建sls文件

    1、创建top.sls
        cat top.sls 
    base:                                            #与base,prod,dev 对应
      'salt02':                                      #同步的minion_id
        - test                                       #调用的sls文件名
    2、创建test.sls
        cat test.sls 
    syncfile:                                               #名称,可以自定义。如果不写name的话,这里需写成目标地址
      file.managed:                                         #file模块的managed方法
        - source: salt://etc/file/passwd                    #原文件路径
        - user: root                                        #源文件属主
        - group: root                                       #源文件属组
        - mode: 600                                         #源文件权限
        - name: /tmp/passwd                                 #同步目标地址
    3、测试
    salt 'salt02' state.highstate                 执行top.sls
    salt 'salt02' state.sls test                  根目录
    salt 'salt02' state.sls sls.test              相对路径
    salt 'salt02' state.sls sls                   默认init.sls
    4、将所有的sls文件放到一个目录

    # tree
    .
    ├── etc
    │ ├── file
    │ │ └── passwd
    │ └── script
    │ └── test.sh
    ├── sls
    │ └── test.sls
    ├── test.sls
    └── top.sls

    5、默认执行init.sls,程序会自动补充文件后缀(.sls)

    # cat init.sls 
    hostname:
      cmd.run

    # tree
    .
    ├── etc
    │ ├── file
    │ │ └── passwd
    │ └── script
    │ └── test.sh
    ├── sls
    │ ├── init.sls
    │ └── test.sls
    ├── test.sls
    └── top.sls

    # salt 'salt02' state.sls sls

    grains

    grains主要负责采集客户端的一些基本信息,这个也可以完全自定义。可以在客户端自定义,然后自动汇报上来;也可以从服务端定义,然后推下去,采集完后,再汇报上来;pillar根grains比较的话它更灵活。

    grains的使用:

    1、查看
         salt 'salt01' grains.ls                           查看minion所有的grains的名称
        salt 'salt01' grains.items                         列出所有grains名称和对应的值
         salt 'vas01' grains.item os                       列出指定的grains的名称和值
    2、匹配
        salt -G 'uuid:421fa146-86f4-47c1-adc9-0e21d5bad8c8' test.ping
    3、自定义grains,在minion端修改配置文件,在文件结尾增加如下配置:
        vim /etc/salt/minion
    grains:
      roles:
        - webserver
        - memcache
      deployment: datacenter
      cabinet: 13
    4、重启minion
        /etc/init.d/salt-minion restart
    5、查看自定义的grains是否生效
        salt 'study02' grains.items

    STATES

    salt状态系统的核心是sls,或者叫**S** aLState文件,SLS表示系统将会是什么样的一种状态,而且是以一种简单的格式来包含这些数据。这些也被叫做配置管理。

    SLS文件实际上只是一些:词典(dictionaries),列表(lists),字符串和数字。

    官方网址:https://docs.saltstack.com/en/latest/ref/states/all/

    批量安装nginx服务

    1、编写sls文件
        cat /srv/salt/nginx/init.sls
            nginx:                                    #定义top.sls定义的模块
              pkg:                                    #使用pkg模块
                - installed                           #安装nginx软件
              service:                                #服务控制模块
                - running                             #运行状态
                - enable: True                        #权限开启
                - reload: True                        #允许reload重启
                - watch:                              #控制文件
                  - pkg: nginx                        #控制的软件
                  - file: /etc/nginx/nginx.conf              #要控制文件的文件定义名称
                  - file: /etc/nginx/conf.d/default.conf      #要控制文件的文件定义名称
            /etc/nginx/nginx.conf:                   #定义控制文件的名称
              file.managed:                         #格式语句
                - source: salt://etc/nginx/nginx.conf       #具体的文件目录
                - user: root                                #执行的用户
                - group: root                               #执行的用户组
                - mode: 644                                 #文件权限
            /etc/nginx/conf.d/default.conf:            #定义控制文件的名称
              file.managed:                            #格式语句
                - source: salt://etc/nginx/conf.d/default.conf #具体的文件目录
                - user: root                      #执行的用户
                - group: root                     #执行的用户组
                - mode: 644                       #文件权限
    2、复制配置文件到脚本目录 cp /etc/nginx/nginx.conf /srv/salt/etc/nginx/ cp /etc/nginx/conf.d/default.conf /srv/salt/etc/nginx/conf.d 3、使用salt批量安装和并同步配置文件 salt 'salt0*' state.sls sls.nginx 4、客户端验证nginx是否安装,启动成功 salt 'salt0*' cmd.run 'rpm -qa|grep nginx' salt 'salt0*' cmd.run 'netstat -nltup|grep "8080"'

    手动同步nginx配置文件

    1、修改配置文件,将端口改为8080
        cat etc/nginx/conf.d/default.conf 
    server {
        listen       8080 default_server;
    2、使用salt同步配置文件,并重启nginx(方法一)
        salt 'salt0*' state.sls sls.nginx
    3、在minion端执行sls(方法二)
        salt-call state.sls sls.nginx
    4、验证minion的nginx配置文件是否同步成功,端口是否更改
        salt 'salt0*'  cmd.run 'netstat -nltup|grep "8080"'
    5、定时同步方法:
       在minion端将salt-call state.sls sls.nginx 写入到定时任务中去。

    Pillar

    Pillar是salt非常重要的一个组件,它用于给特定的minion定义任何你需要的数据,这些数据可以被salt的其它组件使用。Salt在0.98版本中引入了Pillar。

    Pillar在解析完成后,是一个嵌套的字典结构;最上层的key是minion ID,其value是改minion所拥有的Pillar数据;每一个value也都是key:value。

    这里可以看出一个特点,Pillar数据是与特定minion关联的,也就是说每一个minion都只能看到自己的Pillar数据,所以可以用Pillar传递敏感数据(在salt的设计中,Pillar使用独立的加密session,也是为了保证敏感数据的安全性)

    Pillar使用场景

    1、敏感数据:例如ssh-key,加密证书,由于Pillar使用独立的加密session,可以确保这些敏感数据不给其它minion看到;

    2、变量:可以在Pillar中处理平台差异性,比如针对不同的操作系统设置软件包的名字,然后在State中使用;

    3、其它任何数据:可以在Pillar中添加任何需要用到的数据。比如定义用户和UID的对应关系,minion的角色等等;

    4、target中:Pillar可以用来选择minion,使用-l选项。默认情况下,master的配置文件中的所有数据都添加到Pillar中,且对所有minion可用。如果要禁用这一默认值,可以在master配置文件中添加如下数据,重启服务后生效;

    Pillar示例

    官网地址:http://docs.saltstack.cn/topics/jobs/index.html

    1、修改master配置文件
         vim /etc/salt/master
    pillar_roots:
      base:
        - /srv/pillar
    2、创建top.sls
        cat top.sls 
    base:
      '*':
        - 'nginx.nginx'
    3、创建nginx.sls
        cat nginx/nginx.sls 
    schedule:
      test:
        function: state.sls
        minutes: 3600
        args:
          - 'nginx.nginx'
    4、查看目录结构
        tree pillar/
    pillar/
    ├── nginx
    │   └── nginx.sls
    └── top.sls
    5、下发pillar数据
        salt 'salt0*' pillar.data
    6、刷新pillar数据
       salt 'salt0*'  saltutil.refresh_pillar
    7、验证端口,是否更新
        salt 'salt0*'  cmd.run 'netstat -lntup|grep -E ":80|:8080"'

    Grains、Pillar区别:

    Grains:静态信息,客户端的详细信息,在minion端配置,与远程执行走的近

    Pillar:动态信息,客户端的敏感详细,在master端配置,安全,与配置管理走的近

     

    Syndic(proxy代理master)

           master
          proxy           proxy
    minion端 ............minion端

    syndic接口是一个强大的工具,允许建立salt命令拓扑结构,salt的基本结构是一个salt master指挥一组salt minion,syndic接口是一种特殊的直通minion,它运行在一个master上且连接到另外一个master,然后syndic minion所连接的master就可以控制连接运行到syndic的master上的minion

    1、代理机安装salt-syndic
        yum install salt-maste
        yum install salt-syndic
    2、修改配置文件
        vim /etc/salt/master
    syndic_master: salt-master          更高级别master的IP地址
    syndic_log_file: syndic                 日志文件的路径(绝对路径为佳)
    order_masters:True                     确认转发机制
    3、启动代理服务器
        /etc/init.d/salt-syndic  start

    web管理页面(halite)

    安装halite

     

    方法一:失败,待查原因

    1、安装并启动salt-api

    • yum install salt-api –y
    • service salt-api start
    • chkconfig salt-api on

    2、安装halite及其依赖文件

    • yum install python-pip –y
    • pip install --upgrade pip
    • pip install -U halite
    • pip install cherrypy
    • pip install paste
    • yum install python-devel gcc –y
    • pip install gevent
    • pip install pyopenssl
    • pip install tornado

    创建登录用户

    • useradd   salt
    • echo "salt" |passwd --stdin salt

    3、修改master配置文件

    方法二:

    #yum install git

    下载代码

    #cd /var/www

    #git clone https://github.com/saltstack/halite

    生成index.html

    # cd halite/halite
    # ./genindex.py -C
    

    安装salt-api

    # yum install salt-api
    

    添加登陆用户

    # useradd salt
    # echo salt|passwd –stdin salt
    

    配置salt master文件

    配置salt的master文件,添加:

    rest_cherrypy:
     host: 0.0.0.0
     port: 8080
     debug: true
     static: /root/halite/halite
     app: /root/halite/halite/index.html
    
    external_auth:
       pam:
         salt:
    	 - .*
    	 - '@runner'
    	 - '@wheel'
    

    重启master;

    # /etc/init.d/salt-master restart
    

    启动 salt-api,启动web界面(两种启动方式)

    #cd /var/www/halite/halite
    (1)#nohup python2.6 server_bottle.py -d -C -l debug -s cherrypy &       #不使用nohup的话为前台运行

    (2)# salt-api –d   ---后台运行

    然后打开http://ip:8080/app,通过salt/salt登陆即可。

      

    官方安装教程:

    https://docs.saltstack.com/en/latest/topics/tutorials/halite.htm

     参考博客:https://www.cnblogs.com/snailshadow

      

     

  • 相关阅读:
    信号量Semaphore
    回环屏障CyclicBarrier
    线程同步器CountDownLatch
    vue 类似微信通讯录格式实现网易云音乐的歌手字母查询
    vue使用element的多个表格使用v-if切换,使用 :key="Math.random()" 后,表格排序出现问题
    vue使用pinyin的npm包将文字转为大写首字母字母
    vue中使用better-scroll滚动无效
    vue 移动端 图片懒加载 lazy
    表格配合keepalive缓存
    在保存数据之后,不知道什么时候清空数据,不如试试beforeRouteEnter
  • 原文地址:https://www.cnblogs.com/wuhg/p/9962463.html
Copyright © 2020-2023  润新知