准备一台虚拟机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

 

saltstack--史上最细致安装攻略!亲测无坑的更多相关文章

  1. centos安装zabbix集群监控(亲测无坑版)

    一. 安装lemp环境 下载安装包:wget bbs.linuxtone.org/docs/autoinstall/lemp_auto_v1.0.6.tar.gz 包解压:tar zxvf lemp_ ...

  2. Oracle 11g安装攻略

    Oracle 11g安装攻略 本攻略是以Win7-32位系统中安装Oracle 11g为示例,安装前大家需要确认以下几点: 你的内存足够大且没有问题,因为Oracle非常吃内存. 你的系统已经激活. ...

  3. Linux 系统 pptpd+radius+mysql 安装攻略

    分类: 原文地址:Linux 系统 pptpd+radius+mysql 安装攻略 作者:wfeng .你所需要的软件 内核最好能升级到2.6 如果你是centos的用户,可以通过yum update ...

  4. Upload-labs 文件上传靶场通关攻略(上)

    Upload-labs 文件上传靶场通关攻略(上) 文件上传是Web网页中常见的功能之一,通常情况下恶意的文件上传,会形成漏洞. 逻辑是这样的:用户通过上传点上传了恶意文件,通过服务器的校验后保存到指 ...

  5. Eclipse4.5 Mars版本安装activiti插件 亲测可用

    Eclipse4.5 Mars版本安装activiti插件 亲测可用 学习使用activiti 在线安装一直,国内的网络真心的是 很苦 啊:在茫茫网络上面找到了很多插件的离线包 终于找到一个可以使用的 ...

  6. Upload-labs 文件上传靶场通关攻略(下)

    Upload-Labs靶场攻略(下) Pass-11 GET型传参,上传目录可设置,考虑00截断,在/upload/后添加1.php%00,即可上传 Pass-12 POST型传参,上传目录可设置,P ...

  7. 微软Windows11安卓子系统已支持运行APK 应用(附手把手详细安装攻略)怎么安装安卓/如何安装安卓应用/支持多窗口多任务

    ​​ 10 月 21 日消息,微软博客宣称,Windows 11 上 安卓子系统运行 Android  应用程序的第一个预览版现已提供给美国 Beta 频道的 Windows 内部人员.但现在通过教程 ...

  8. PS CC 破解安装教程(亲测可用)

    PS CC版本新增了一些更高效的切图工具,比如可以直接右击图层转化为PNG图像 下面介绍一种亲测可用的破解安装教程 软件下载地址:https://pan.baidu.com/s/1dFJFqhj 一. ...

  9. 一步一步带你安装史上最难安装的 vim 插件 —— YouCompleteMe

    YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for Vim.参考: https://github ...

随机推荐

  1. CSS 学习手册

    目录 CSS 简介 1.CSS 简介 CSS 概述 层叠次序 2.CSS 基础语法 CSS 语法 值的不同写法和单位 记得写引号 多重声明: 空格和大小写 3.CSS 高级语法 选择器的分组 继承及其 ...

  2. JS高级教程

    JS高级教程 JS高级教程

  3. Android五大布局详解——FrameLayout(帧布局)

    FrameLayout 这个布局相对前面两节介绍的布局就简单了很多,因此它的应用场景也就特别的少.这种布局没有方便的定位方式,所有的控件都会默认摆放在布局的左上角.新建UILayoutTestThre ...

  4. C#&.Net干货分享- 构建Spire-Office相关Helper操作Word、Excel、PDF等

    先下载好如下的组件: 直接使用完整源码分享: namespace Frame.Office{    /// <summary>    /// Spire_WordHelper    /// ...

  5. Mac中 pip3 install mysqlclient 报错

    主要错误提示如下: ld: library not found for -lssl clang: error: linker command failed with exit code 1 (use ...

  6. 用iText5-2-其他类型PDF

    //设置文件属性的PDF package com.wf.zhang.test; import java.io.FileOutputStream; import com.itextpdf.text.Ba ...

  7. linux 常用命令及软件

    命令基于ubuntu 18.04 修改网卡配置 /etc/netplan/50-cloud-init.yaml #修改 netplan apply #应用修改 修改计算机名 sudo hostname ...

  8. Python 一键获取百度网盘提取码

    该 GIF 图来自于官网,文末有给出链接. 描述 依托于百度网盘巨大的的云存储空间,绝大数人会习惯性的将一些资料什么的存储到上面,但是有的私密链接需要提取码,但是让每个想下载私密资源的人记住每一个提取 ...

  9. In .net 4.8,calculate the time cost of serialization in BinaryFormatter,NewtonSoft.json,and System.Text.Json.JsonSerializer.Serialize

    using ConsoleApp390.Model; using Newtonsoft.Json; using System; using System.Collections.Generic; us ...

  10. Implement Dependent Reference Properties 实现从属引用属性 (XPO)

    In this lesson, you will learn how to implement properties whose values can depend on other properti ...