fightclub

saltstack中的设计模式(六)

在今天我们介绍使用pillar进行参数化sls的方法,以及pillar数据结构设计的一般模式。
案例如下:

为通过saltstack部署的mariadb提供个性化配置

在salt中,主要使用pillar来存储动态信息。在sls中,在第一次渲染中提取出动态信息的值,编译成sls的执行指令进行第二道程序执行。

/srv/salt/services/mariadb/init.sls

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{% from "macros/setrole.sls" import setrole %}
{{ setrole("mariadb") }}
include:
- system.pkgrepos.mariadb
- .zabbix
mariadb:
pkg.installed:
- allow_updates: True
- pkgs:
- MariaDB-server
- MariaDB-client
- MariaDB-shared
- MariaDB-connect-engine
- MariaDB-backup
# - mariadb-Galera-server
# - galera
- require:
- pkgrepo: mariadb-repo
mariadb-datadir:
file.directory:
- name: /data/mariadb/data
- user: mysql
- group: mysql
- dir_mode: 750
- makedirs: True
- require:
- pkg: mariadb
mariadb-tmpdir:
file.directory:
- name: /data/mariadb/tmp
- user: mysql
- group: mysql
- dir_mode: 750
- recurse:
- user
- group
- mode
- makedirs: True
- require:
- pkg: mariadb
mariadb-innodbdir:
file.directory:
- name: /data/mariadb/innodb
- user: mysql
- group: mysql
- dir_mode: 750
- makedirs: True
- require:
- pkg: mariadb
mariadb-file:
file.managed:
- name: /etc/my.cnf.d/server.cnf
- source: salt://{{ slspath }}/templates/server.cnf
- template: jinja
- backup: minion
- require:
- pkg: mariadb
mariadb-install-db:
cmd.run:
- name: "mysql_install_db --user=mysql --defaults-file=/etc/my.cnf.d/server.cnf"
- require:
- file: /etc/my.cnf.d/server.cnf
- unless: "file -f /data/mariadb/innodb/ibdata1"
mariadb-service:
service.running:
- name: mariadb
- enable: True
- restart: True
- require:
- cmd: mariadb-install-db
- watch:
- pkg: mariadb
- file: /etc/my.cnf.d/server.cnf
mariadb-initialization:
cmd.run:
- name: "/usr/bin/mysql_upgrade;echo 'delete from mysql.user where host not in (\"localhost\", \"127.0.0.1\") or user != \"root\";drop database test;flush privileges;' | mysql -u root"
- require:
- service: mariadb-service
- unless: "test -f /var/lib/mysql/initialization.lock"
file.managed:
- name: /var/lib/mysql/initialization.lock
- user: mysql
- contents:
- "This is the Initialization lock file for MariaDB."
- onchanges:
- cmd: mariadb-initialization
/etc/logrotate.d/mysql:
file.managed:
- source: salt://{{ slspath }}/templates/log_rotate

我们把所有mariadb有关的的任务,都放在services.mariadb下面。 如果有其他额外的复杂功能,比如监控相关的,就在include下面直接链接即可。
/etc/my.cnf.d/server.cnf这个文件引用了一个jinja的模版,我们用这个jinja模版实现了动态的配置参数,如下

/srv/salt/services/mariadb/templates/server.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#Initialized by Salt
{%- set conf = salt['pillar.get']('mariadb', {}) -%}
{%- macro kvset(k, v) -%}
{{ k }}={{ conf.get(k, v) }}
{%- endmacro %}
[server]
[galera]
[embedded]
[mariadb]
[mariadb-10.1]
[mysqld]
bind-address=0.0.0.0
{{ kvset("general_log", 1) }}
{{ kvset("general_log_file", "/data/mariadb/general.log") }}
slow_query_log=1
slow_query_log_file=/data/mariadb/slow_query_log.log
slow_launch_time=2
event_scheduler=1
default_storage_engine=InnoDB
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
#read-only=1
{{ kvset('server-id', 1) }}
sync_binlog=1
skip_name_resolve=1
log-bin=mysql-bin
binlog_format = mixed
expire_logs_days = 3
max_binlog_size = 100M
relay-log=relay-log
log-slave-updates=true
max_relay_log_size = 100M
relay_log_purge=0
relay_log_recovery=1
master_verify_checksum = 1
slave_sql_verify_checksum = 1
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-external-locking
key_buffer_size = {{ (salt['grains.get']('mem_total') * 0.05) | int }}M
max_allowed_packet = 64M
table_open_cache = 16384
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 2M
myisam_sort_buffer_size = 64M
thread_cache_size = 32
query_cache_size = 0M
datadir = /data/mariadb/data
tmpdir = /data/mariadb/tmp
innodb_file_per_table=1
innodb_data_home_dir = /data/mariadb/innodb
innodb_data_file_path = ibdata1:256M;ibdata2:256M:autoextend
innodb_autoextend_increment = 64
innodb_log_group_home_dir = /data/mariadb/innodb
innodb_buffer_pool_size = {{ (salt['grains.get']('mem_total') * 0.6) | int }}M
innodb_log_file_size = 256M
innodb_log_buffer_size = 4M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
lower_case_table_names = 1
max_connections = 2048
max_connect_errors = 64
log_bin_trust_function_creators = 1
{{ kvset("interactive_timeout", 720) }}
{{ kvset("wait_timeout", 720) }}
[mysqldump]
quick
max_allowed_packet = 256M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 32M
write_buffer = 32M
[mysqlhotcopy]
interactive-timeout

我们在模版中,我们先从pillar中取出mariadb的嵌套数据,并根据需要的值在其中获取数据。对于每个pillar中的数据,我们都赋予一个默认值,这样在没有额外设置pillar的情况,就和静态版本的一致。

注意到innodb_buffer_pool_size这个键的值,并不是在pillar中决定的,而是取自grains。对于根据系统情况决定的参数,都可以通过grain传进来。

在这个模版做好以后,如果有变化部署的需求。我们可以将mariadb的参数的pillar赋予给对应的主机,来实现主机指定参数。

以下几个实现方案都是不错的。

  1. 用户通过执行salt-call state.sls services.mariadb pillar=”{‘k’: ‘v’}”的方式调用。这适用于一次性的个性化部署,无需salt管理员介入
  2. 假设我们为一个项目或主机部署,那么我们在这台主机的pillar中设置mariadb的子参数
  3. 我们可以使用pillar extension,比如基于rdbms或是etcd等的。可以单独设计UI,并和salt系统集成起来,实现paas平台

无论怎样,我们都需要预留pillar中mariadb的key的位置,保留给该任务使用。假设我们常用的有几套参数,那么我们可以在pillar中按照名称放置几个参数组,例如创建目录/srv/pillar/mariadb/,在这个下面放置parm_group1,parm_group2等参数组,再把特定的参数组同主机关联起来即可实现参数组的享元。

总结

任务设计的模式,主要取决于你想如何使用这个自动化任务。
任务设计的复杂程度,取决于应用场景的复杂成都。

在今天这个场景中,该部署任务主要适用于执行半自动部署,也就是手工调用salt xx state.sls services.mariadb或者salt-call state.sls services.mariadb或者在其他自动化任务中通过include该任务执行部署的场景。