return and job management of SaltStack

Posted by john1704 on Fri, 05 Nov 2021 18:55:33 +0100

1. return of saltstack component

The return component can be understood as the SaltStack system stores or returns the data returned by Minion to other programs. It supports a variety of storage methods, such as MySQL, MongoDB, Redis, Memcache, etc. through return, we can record each operation of SaltStack and provide a data source for future log audit. At present, 30 return data storage and interfaces are officially supported. We can easily configure and use it. Of course, it also supports self-defined returns. Custom returns need to be written in python. After selecting and configuring the return to use, just specify return after the salt command.

//View the list of all return s
[root@master ~]# salt 'minion1' sys.list_returners
minion1:
    - carbon
    - couchdb
    - etcd
    - highstate
    - local
    - local_cache
    - mattermost
    - multi_returner
    - pushover
    - rawfile_json
    - slack
    - slack_webhook
    - smtp
    - splunk
    - sqlite3
    - syslog
    - telegram

Official return: https://docs.saltproject.io/en/latest/ref/returners/index.html

1.1 return process

Return is to trigger the task on the Master side, and then Minion accepts the processing task, directly establishes a connection with the return storage server, and then saves the data return to the storage server. It must be noted that the Minion side operates the storage server in this process, so it is necessary to ensure that the configuration and dependency package of the Minion side are correct, which means that we must install the specified return mode dependency package on each Minion. If Mysql is used as the return storage mode, we will install Python Mysql module on each Minion.

1.2 use mysql as the return storage method

Install MySQL Python module on all minion s

[root@master ~]# salt 'minion1' pkg.install python3-PyMySQL
minion1:
    ----------
    python3-PyMySQL:
        ----------
        new:
            0.10.1-2.module_el8.5.0+761+faacb0fb
        old:
    python3-cffi:
        ----------
        new:
            1.11.5-5.el8
        old:
    python3-cryptography:
        ----------
        new:
            3.2.1-5.el8
        old:
    python3-ply:
        ----------
        new:
            3.9-9.el8
        old:
    python3-pycparser:
        ----------
        new:
            2.14-14.el8
        old:

Deploy a mysql server as a storage server. Here, deploy it directly on the host 192.168.47.158

[root@mysql ~]# yum -y install mariadb mariadb-server
[root@mysql ~]# systemctl enable --now mariadb
[root@mysql ~]# ss -antl
State    Recv-Q   Send-Q     Local Address:Port       Peer Address:Port   Process   
LISTEN   0        128              0.0.0.0:22              0.0.0.0:*                
LISTEN   0        80                     *:3306                  *:*                
LISTEN   0        128                 [::]:22                 [::]:*  




//Create database and table structures
[root@mysql ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.28-MariaDB MariaDB Server #There is no need to copy here. Start from below

CREATE DATABASE  `salt`
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

USE `salt`;

--
-- Table structure for table `jids`
--

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;

--
-- Table structure for table `salt_returns`
--

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,
  `alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  KEY `id` (`id`),
  KEY `jid` (`jid`),
  KEY `fun` (`fun`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Table structure for table `salt_events`
--

DROP TABLE IF EXISTS `salt_events`;
CREATE TABLE `salt_events` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL,
`data` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`master_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


//After the above copy is completed, view the table
MariaDB [salt]> show tables;
+----------------+
| Tables_in_salt |
+----------------+
| jids           |
| salt_events    |
| salt_returns   |
+----------------+
3 rows in set (0.001 sec)

MariaDB [salt]> desc jids;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| jid   | varchar(255) | NO   | PRI | NULL    |       |
| load  | mediumtext   | NO   |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.001 sec)
//to grant authorization
MariaDB [salt]> grant all on salt.* to 'salt'@'%' identified by 'salt';
Query OK, 0 rows affected (0.000 sec)
//Refresh
MariaDB [salt]> flush privileges;
Query OK, 0 rows affected (0.000 sec)


Configure minion

//Can log in and store
[root@minion1 ~]# yum -y install mariadb
[root@minion1 ~]# mysql -usalt -psalt -h192.168.47.158
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> quit
Bye


[root@minion1 ~]# vim /etc/salt/minion
......province
#  - slack
mysql.host: '192.168.47.158' #The host is a MySQL storage server host
mysql.user: 'salt'
mysql.pass: 'salt'
mysql.db: 'salt'
mysql.port: 3306
[root@minion1 ~]# systemctl restart salt-minion
[root@master ~]# salt minion1 test.ping
minion1:
    True

Store the test in mysql on the Master

//Look at the table. There was nothing at first,
MariaDB [salt]> show tables;
+----------------+
| Tables_in_salt |
+----------------+
| jids           |
| salt_events    |
| salt_returns   |
+----------------+
3 rows in set (0.000 sec)

MariaDB [salt]> select * from salt_returns; #Cache all data to salt_returns, so check this table
Empty set (0.000 sec)

Store the test in mysql on the Master

//Test, add something
[root@master ~]# salt 'minion1' test.ping --return mysql #There is no uncomment in minion, so you have to specify return here
minion1:
    True

Query in database

MariaDB [salt]> select * from salt_returns\G
*************************** 1. row ***************************
       fun: test.ping
       jid: 20211105144353897141
    return: true
        id: minion1
   success: 1
  full_ret: {"success": true, "return": true, "retcode": 0, "jid": "20211105144353897141", "fun": "test.ping", "fun_args": [], "id": "minion1"}
alter_time: 2021-11-05 22:43:54
1 row in set (0.000 sec)


2. job cache

2.1 job cache process

When returning, the Minion directly interacts with the storage server. Therefore, it is necessary to install modules with specified storage methods on each Minion, such as Python mysql. Can we directly store the returned results on the Master to the storage server?

The answer is yes. This method is called job cache. It means that after Minion returns the results to the Master, the Master caches the results locally, and then stores the cached results to the specified storage server, such as mysql.

Open the master on the master side_ job_ cache
Note: turn off return before starting the job cache

//This is the location where the default data is stored on the master. The default storage time is 24 hours
[root@master ~]# ls /var/cache/salt/master/jobs/
00  0c  15  1e  30  3a  4f  60  6c  76  86  8f  a4  b4  c1  cd  d6  df  e9  f8
01  0d  16  23  31  42  50  63  6d  77  87  90  a6  b7  c3  ce  d7  e3  ef  fb
02  0e  17  24  32  45  5a  64  70  78  8a  98  a7  b8  c4  cf  d8  e4  f1  fc
03  0f  19  2a  33  47  5b  68  71  7b  8b  9c  ab  b9  c8  d0  db  e5  f4  ff
06  10  1a  2c  34  4b  5c  69  73  82  8c  9d  ac  bc  c9  d2  dc  e6  f5
07  14  1d  2d  35  4c  5f  6a  75  84  8d  a0  b0  c0  cc  d5  dd  e8  f7

[root@master ~]# vim /etc/salt/master
#job_cache: True #This is where the default data storage is turned on
master_job_cache: mysql  #It is equivalent to the one without comments on the return above. After adding this item, the data is saved to MySQL by default
mysql.host: '192.168.47.158'
mysql.user: 'salt'
mysql.pass: 'salt'
mysql.db: 'salt'
mysql.port: 3306

Test whether the master can connect to the mysql storage side

[root@master ~]# yum -y install mariadb
[root@master ~]# which mysql
/usr/bin/mysql
[root@master ~]# mysql -usalt -psalt -h192.168.47.158
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 14
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

be careful

//When using return, you need all minion s to install the python3 mymsql package, but when using job, you only need to install it on the master. Don't forget that an error will be reported
[root@master ~]# yum -y install python3-PyMySQL

Empty table contents in database server

MariaDB [salt]> delete from salt_returns;
Query OK, 1 row affected (0.001 sec)

MariaDB [salt]> select * from salt_returns\G
Empty set (0.000 sec)


Test again on the master to see if it can be stored in the database

[root@master ~]# salt 'minion1' cmd.run 'cat /root/aaa'
minion1:
    The world is splendid and grand
    Welcome home

Query in database

MariaDB [salt]> select * from salt_returns\G
*************************** 1. row ***************************
       fun: cmd.run
       jid: 20211105152851491993
    return: "The world is splendid and grand\n Welcome home"
        id: minion1
   success: 1
  full_ret: {"cmd": "_return", "id": "minion1", "success": true, "return": "The world is splendid and grand\n Welcome home", "retcode": 0, "jid": "20211105152851491993", "fun": "cmd.run", "fun_args": ["cat /root/aaa"], "_stamp": "2021-11-05T15:28:51.687976"}
alter_time: 2021-11-05 23:28:52
1 row in set (0.000 sec)

2.2 job management

Gets the jid of the task

[root@master ~]# salt 'minion1' cmd.run 'uptime' -v
Executing job with jid 20211105153026292134
-------------------------------------------

minion1:
     23:30:26 up  2:37,  2 users,  load average: 0.12, 0.08, 0.05

Get the return result of this task through jid

[root@master ~]# salt-run jobs.lookup_jid 20211105153026292134
minion1:
     23:30:26 up  2:37,  2 users,  load average: 0.12, 0.08, 0.05

Topics: saltstack