1. Preface
saltstack is divided into master and slave, which can be used for cluster management
2. Environment
Serr2:172.25.69.2 (main)
Serr3:172.25.69.3 (from)
Serr4:172.25.69.4 (from)
3. Environmental settings
Main: Install saltstack-master, python-setproctitle.x86_64
From: Install salt-minion.noarch
Master: Open the service salt-master
From: Modify the location file / etc/salt/minion
master: 172.25.69.2
Open the service salt-minion
Main: salt-key-L
Salt-key-A adds all keys
Salt-key-D deletes all keys
Test Connection
4. Installing Apache for Nodes
(1) Modify the main node configuration file
/etc/salt/master
file_roots: base: - /srv/salt/
(2) Create apache directory in / srv/salt
(3) Write install.sls file
install-apache: pkg.installed: #Default yum installation - pkgs: - httpd file.managed: - name: /etc/httpd/conf/httpd.conf #Target file - source: salt://apache/files/httpd.conf source file service.running: #When a service starts, a reload is a reload - name: httpd - reload: true - watch: - file: install-apache
5. Install Nginx for nodes
(1) Create nginx directory and pkgs directory in / srv/salt
(2) sls files in nginx directory
#####install.sls include: - pkgs.install install-nginx: file.managed: - name: /mnt/nginx-1.15.8.tar.gz - source: salt://nginx/files/nginx-1.15.8.tar.gz cmd.run: - name: cd /mnt && tar zxf nginx-1.15.8.tar.gz && cd nginx-1.15.8 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install - creates: /usr/local/nginx ######service.sls include: - nginx.install /usr/local/nginx/sbin/nginx: cmd.run: - creates: /usr/local/nginx/logs/nginx.pid /usr/local/nginx/conf/nginx.conf: file.managed: - source: salt://nginx/files/nginx.conf /usr/local/nginx/sbin/nginx -s reload: cmd.wait: - watch: - file: /usr/local/nginx/conf/nginx.conf
(3) sls files in pkgs directory
pkgs-install.sls nginx-make: pkg.installed: - pkgs: - gcc - make - zlib-devel - pcre-devel
(4) Install and start nginx
(5) Settings modification using system D to manage nginx
Write nginx.service file in files directory under nginx directory
[Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
Modify the service.sls file to
include: - nginx.install /usr/local/nginx/conf/nginx.conf: file.managed: - source: salt://nginx/files/nginx.conf service-nginx: file.managed: - name: /usr/lib/systemd/system/nginx.service - source: salt://nginx/files/nginx.service service.running: - name: nginx - reload: True - watch: - file: /usr/local/nginx/conf/nginx.conf
6. Viewing and setting variables
(1) Variable setting method 1:
Server 3 minion configuration file
grains: roles: - apache
minion configuration file for server 4
grains: roles: - nginx
(2) Variable setting method 2:
Create a grain file in the / etc/salt directory
roles:
- nginx
(3) Variable setting method 3:
my_grains.py
def my_grains(): grains = {} grains['hello'] = 'world' grains['salt'] = 'stack' return grains
Sending Policy
Command: salt server 3 saltutil. sync_grains
(4) Variable setting method 4:
Modify the main node configuration file / etc/salt/master
pillar_roots: base: - /srv/pillar
Create directories
top.sls
base: '*': - web.vars
vars.sls
{% if grains['fqdn'] == 'server3' %} webserver: httpd ip: 172.25.0.3 {% elif grains['fqdn'] == 'server4' %} webserver: nginx ip: 172.25.0.4 {% endif %}
wipe cache
Synchronize variable files and view variables
7. Installing keepalived to achieve high availability
(1) Environment
server3: 172.25.69.3(apache,keepalived(master))
server4: 172.25.69.4(nginx,keepalived(backup))
Implementing effect: Local host accesses keepalived virtual ip first by accessing server 3. When server 3 fails to shut down abnormally, virtual ip drifts to server 4.
(1)apache
install.sls
install-apache: pkg.installed: - pkgs: - httpd file.managed: - name: /etc/httpd/conf/httpd.conf - source: salt://apache/files/httpd.conf - template: jinja - context: port: 80 service.running: - name: httpd - reload: true - watch: - file: install-apache
(2)nginx
Configuration as above
(3)keepalived
install.sls
install-keepalived: pkg.installed: - pkgs: - keepalived file.managed: - name: /etc/keepalived/keepalived.conf - source: salt://keepalived/files/keepalived.conf - template: jinja - context: STATE: {{ pillar['state'] }} VRID: {{ pillar['vrid'] }} PRIORITY: {{ pillar['priority'] }} service.running: - name: keepalived - watch: - file: install-keepalived
keepalived.conf
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { state {{ STATE }} interface eth0 virtual_router_id {{ VRID }} priority {{ PRIORITY }} advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.25.69.69 } }
(4) Variables
top.sls
base: '*': - web.vars
var.sls
{% if grains['fqdn'] == 'server3' %} ip: 172.25.0.3 state: MASTER vrid: 100 priority: 100 {% elif grains['fqdn'] == 'server4' %} ip: 172.25.0.4 state: BACKUP vrid: 100 priority: 50 {% endif %}
(5) Overall
Command: salt'*'state. high state
(6) Final results
When keepalived of server 3 closes, vip will be transferred to server 4
8,topmaster syndic+master minion
(1) Environment
server2(syndic+master)
server3(minion)
server4(minion)
server5(topmaster)
Serr2: Install salt-syndic,salt-master
Serr3 installation: salt-minion
Serr4 installation: salt-minion
Serr5 installation: salt-master
(2) Setting up configuration files
Modify server 2 master configuration file
syndic_master: server5
Modify server 5 master configuration file
order_masters: True
Serr2 opens server-master
server-syndic
Serr5 opens server-master
9,salt-ssh
(1) Preparation
Server 3 closes salt-minion
Serr2 Edit / etc/salt/roster, add
server3:
host: 172.25.69.3
user: root
passwd: redhat
(2) Installing salt-ssh
Serr2 installation
(3) Testing
11,salt-api
(1) Preparation
Serr2 installs salt-api
Generate the key. / etc/pki/tls/private/
Generate certificates
(2) Create user saltapi and set password
(3) Modifying configuration files
/etc/salt/master.d/ [root@server2 master.d]# cat api.conf rest_cherrypy: port: 8000 ssl_crt: /etc/pki/tls/certs/localhost.crt ssl_key: /etc/pki/tls/private/localhost.key [root@server2 master.d]# cat auth.conf external_auth: pam: saltapi: - .* - '@wheel' - '@runner' - '@jobs'
(4) Testing
Command: curl-sSk https://localhost:8000/login-H'Accept: application/x-yaml'-d username=saltapi-d password=redhat-d eauth=pam
Command: curl-sSk https://localhost:8000-H'Accept: application/x-yaml'-H'X-Auth-Token: ff6fe100de92eceed 205812a88e49cb0b47799e9'-d client=local-d tgt='*-d fun=test.
saltapi.py
Provided by github
# -*- 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://localhost:8000',username='saltapi',password='redhat') #sapi.token_id() print sapi.list_all_key() #sapi.delete_key('test-01') #sapi.accept_key('test-01') #sapi.deploy('server6','nginx.service') #print sapi.remote_noarg_execution('test-01','grains.items') if __name__ == '__main__': main()