之前我们进行了安装vim包的讲解,下面我们继续借助salt深入学习软件安装。此篇文章,大量借鉴天斯的blog,所以有很多相似的地方,如果笔误,敬请见谅,现在我们假设有两组应用 一组web环境的应用 和一组是DB应用,两组不同的应用,环境需要各不相同,我们先来看一下web环境的应用
一、环境结构(web组的主机名,其中YQD_2014_12_06_57_67安装master和minion):
YQD_2014_12_06_57_120:
YQD_2014_12_06_57_68:
YQD_2014_12_06_57_93:
YQD_2014_12_06_57_67:
YQD_2014_12_06_57_69:
YQD_2014_12_06_57_120: YQD_2014_12_06_57_68: YQD_2014_12_06_57_93: YQD_2014_12_06_57_67: YQD_2014_12_06_57_69: |
我们看到有两台服务器需要安装web应用环境,我们这里采用nginx的web环境部署
二、配置说明:
1、master配置说明:
nodegroups:
web_group: [email protected]_2014_12_06_57_120,YQD_2014_12_06_57_69,YQD_2014_12_06_57_67,YQD_2014_12_06_57_93'
db_group: 'YQD_2014_12_06_57_68'
nodegroups: web_group: [email protected]_2014_12_06_57_120,YQD_2014_12_06_57_69,YQD_2014_12_06_57_67,YQD_2014_12_06_57_93' db_group: 'YQD_2014_12_06_57_68' |
在master配置文件中我们先对服务器进行分组:web_group和db_group
2、树型结构如下所示:
salt/
├── code
│ └── update
├── conf_file
│ ├── mysql
│ │ └── my.cnf
│ ├── nginx
│ │ ├── nginx.conf
│ │ └── vhosts
│ │ └── vhost.conf
│ └── tomcat
├── _grains
│ └── nginx.py
├── init.d
│ ├── mysqld
│ ├── nginx
│ └── tomcat
├── memory
│ ├── jemalloc
│ │ ├── jemalloc-3.6.0.tar.bz2
│ │ └── jemalloc_install.sls
│ └── tcmalloc
│ ├── gperftools-2.1.tar.gz
│ ├── libunwind-1.1.tar.gz
│ └── tcmalloc_install.sls
├── soft
│ ├── jdk
│ │ ├── java_install.sls
│ │ └── jdk-6u45-linux-x64-rpm.bin
│ ├── mysql
│ │ ├── mysql_install.sls
│ │ └── Percona-Server-5.5.34-rel32.0.tar.gz
│ ├── nginx
│ │ ├── nginx-1.6.2.tar.gz
│ │ ├── nginx_config.sls
│ │ ├── nginx_install.sls
│ │ └── tengine-2.0.3.tar.gz
│ └── tomcat
│ ├── install_pkgs
│ │ └── apache-tomcat-7.0.41.tar.gz
│ ├── tomcat_config.sls
│ └── tomcat_install.sls
├── sys_init_sls
│ └── pkgs.sls
└── top.sls
pillar/
├── mysql
│ └── init.sls
└── top.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 |
salt/ ├── code │ └── update ├── conf_file │ ├── mysql │ │ └── my.cnf │ ├── nginx │ │ ├── nginx.conf │ │ └── vhosts │ │ └── vhost.conf │ └── tomcat ├── _grains │ └── nginx.py ├── init.d │ ├── mysqld │ ├── nginx │ └── tomcat ├── memory │ ├── jemalloc │ │ ├── jemalloc-3.6.0.tar.bz2 │ │ └── jemalloc_install.sls │ └── tcmalloc │ ├── gperftools-2.1.tar.gz │ ├── libunwind-1.1.tar.gz │ └── tcmalloc_install.sls ├── soft │ ├── jdk │ │ ├── java_install.sls │ │ └── jdk-6u45-linux-x64-rpm.bin │ ├── mysql │ │ ├── mysql_install.sls │ │ └── Percona-Server-5.5.34-rel32.0.tar.gz │ ├── nginx │ │ ├── nginx-1.6.2.tar.gz │ │ ├── nginx_config.sls │ │ ├── nginx_install.sls │ │ └── tengine-2.0.3.tar.gz │ └── tomcat │ ├── install_pkgs │ │ └── apache-tomcat-7.0.41.tar.gz │ ├── tomcat_config.sls │ └── tomcat_install.sls ├── sys_init_sls │ └── pkgs.sls └── top.sls pillar/ ├── mysql │ └── init.sls └── top.sls |
在这两个树型结构里面,我们有salt和pillar两个父目录,salt目录下面则有很多目录,每个目录放置的都是我们今后部署需要一些软件和配置文件等等,我们在后面将继续介绍;_grains则是自定义的grains,conf_file目录放置了nginx的配置文件及vhost的配置文件,然后则是我们的安装所需要的各类sls文件;pillar目录则是我们的自定义的一些pillar,具体见pillar定义部分。
三、定义grains模块
什么是grains?
salt用一个接口用于收集系统信息。这个接口称为grains,grains收集到的信息是minion第一次启动的时候获取的信息,所以必须认识到grains收集到信息是静态的,是minion第一次启动的时候获取的,不同的grains.ls则可以列出目标机器上可用的grains的名称。这可以自定义,可以在客户端定义,汇报上来;也可以在服务端定义,然后推送下去。
1、我们先看一下从master端定义,推送下去的效果,创建_grains/nginx.py
# cat /srv/salt/_grains/nginx.py
import os
import sys
import commands
def NginxGrains():
'''
return Nginx config grains value
'''
grains = {}
max_open_file=65536
#Worker_info={'cpus2':'01 10','cpus4':'1000 0100 0010 0001','cpus8':'10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001'}
try:
getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')
except Exception,e:
pass
if getulimit[0] == 0:
max_open_file = int(getulimit[1])
grains['max_open_file'] = max_open_file
return grains
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import os import sys import commands def NginxGrains(): ''' return Nginx config grains value ''' grains = {} max_open_file=65536 #Worker_info={'cpus2':'01 10','cpus4':'1000 0100 0010 0001','cpus8':'10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001'} try: getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n') except Exception,e: pass if getulimit[0] == 0: max_open_file = int(getulimit[1]) grains['max_open_file'] = max_open_file return grains |
2、同步grains模块
# salt '*' saltutil.sync_all
YQD_2014_12_06_57_69:
----------
grains:
- grains.nginx
modules:
outputters:
renderers:
returners:
states:
# salt '*' saltutil.sync_all YQD_2014_12_06_57_69: ---------- grains: - grains.nginx modules: outputters: renderers: returners: states: |
3、重新加载模块(让minion编译模块)
# salt '*' sys.reload_modules
YQD_2014_12_06_57_69:
True
YQD_2014_12_06_57_120:
True
YQD_2014_12_06_57_93:
True
YQD_2014_12_06_57_68:
True
# salt '*' sys.reload_modules YQD_2014_12_06_57_69: True YQD_2014_12_06_57_120: True YQD_2014_12_06_57_93: True YQD_2014_12_06_57_68: True |
4、验证max_open_file(查看效果)
# salt '*' grains.item max_open_file
YQD_2014_12_06_57_68:
max_open_file: 65536
YQD_2014_12_06_57_120:
max_open_file: 1024
YQD_2014_12_06_57_93:
max_open_file: 1024
YQD_2014_12_06_57_69:
max_open_file: 1024
YQD_2014_12_06_57_67:
max_open_file: 65536
# salt '*' grains.item max_open_file YQD_2014_12_06_57_68: max_open_file: 65536 YQD_2014_12_06_57_120: max_open_file: 1024 YQD_2014_12_06_57_93: max_open_file: 1024 YQD_2014_12_06_57_69: max_open_file: 1024 YQD_2014_12_06_57_67: max_open_file: 65536 |
你可以看到这里的max_open_file已经成取得了系统的ulimit -n里面的值。
四、配置pillar
什么是pillar?
pillar也是一种接口是salt部署里面一个非常重要的组件,pillar接口为指定的minion产生任意的数据。在pillar里,产生的数据提供给salt的每一个组件,并用于多种目的。传输的信息通过pillar是保证只颁发给有针对性的minions,pillar可以包含任何基本的数据结构,一个数值列表或一个key/vlaue存储被定义,因此在sls公式里很容易遍历一组值。
1、在pillar中也需要定义top.sls
[[email protected] pillar]# cat /srv/pillar/top.sls
base:
web_group:
- match: nodegroup
- web
db_group:
- match: nodegroup
- db
base: web_group: - match: nodegroup - web db_group: - match: nodegroup - db |
2、pillar的入口我们定义了,下面我们定义私有配置,本例只配置web_root的数据(db的配置后续我们将介绍)当然可以根据不同需求进行定制,格式为python的字典形式,即”key:value”。
[[email protected] pillar]# cat /srv/pillar/web.sls
nginx:
root: /data/www
nginx: root: /data/www |
3、验证配置通过下列命令可取得:
# salt '*' pillar.data nginx
# salt '*' pillar.data nginx |
五、配置states
1、定义入口top.sls,里面调用nginx.sls
[[email protected] salt]# cat /srv/salt/top.sls
base:
'*':
- soft.nginx.nginx_install
- soft.nginx.nginx_config
base: '*': - soft.nginx.nginx_install - soft.nginx.nginx_config |
2、定义nginx安装的sls文件,其中salt://conf_file/nginx/nginx.conf为配置模板文件位置。
[[email protected] salt]# cat /srv/salt/soft/nginx/nginx_install.sls
nginx:
pkg:
- installed
service.running:
- enable: True
- reload: True
nginx_reload:
cmd.wait:
- name: /etc/init.d/nginx reload
/data/nginx/conf/nginx.conf:
file.managed:
- source: salt://nginx/nginx.conf
- user: root
- group: root
- mode: 644
- template: jinja
- backup: minion
- watch_in:
- cmd: nginx_reload
/data/nginx/conf/vhosts:
file.recurse:
- source: salt://nginx/vhosts
- user: root
- group: root
- file_mode: 644
- dir_mode: 755
- makedirs: True
- include_empty: True
- template: jinja
- backup: minion
- watch_in:
- cmd: nginx_reload
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 |
nginx: pkg: - installed service.running: - enable: True - reload: True nginx_reload: cmd.wait: - name: /etc/init.d/nginx reload /data/nginx/conf/nginx.conf: file.managed: - source: salt://nginx/nginx.conf - user: root - group: root - mode: 644 - template: jinja - backup: minion - watch_in: - cmd: nginx_reload /data/nginx/conf/vhosts: file.recurse: - source: salt://nginx/vhosts - user: root - group: root - file_mode: 644 - dir_mode: 755 - makedirs: True - include_empty: True - template: jinja - backup: minion - watch_in: - cmd: nginx_reload |
3、Nginx配置文件(引用jinja模板)
功能点:
A、worker_processes参数采用grains[‘num_cpus’]上报上来的值(与设备CPU核数一致);
B、worker_cpu_affinity分配多核CPU根据当前设备核数进行匹配,分别为248其它核;
C、worker_rlimit_nofile参数与grains[‘max_open_file’] 获取的系统ulimit -n一致;
D、worker_connections 参数理论上为grains[‘max_open_file’];
E、 root参数为定制的pillar[‘nginx’][‘root’]值。
cat /srv/salt/conf_file/nginx/nginx.conf
user nobody;
worker_processes {{ grains['num_cpus'] }};
{% if grains['num_cpus'] == 2 %}
worker_cpu_affinity 01 10;
{% elif grains['num_cpus'] == 4 %}
worker_cpu_affinity 1000 0100 0010 0001;
{% elif grains['num_cpus'] == 8 %}
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
{% else %}
#worker_cpu_affinity 1000 0100 0010 0001;
{% endif %}
worker_rlimit_nofile {{ grains['max_open_file'] }};
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections {{ grains['max_open_file'] }};
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
server_tokens off;
sendfile on;
tcp_nopush on;
fastcgi_intercept_errors on;
keepalive_timeout 65;
gzip on;
gzip_comp_level 5;
gzip_http_version 1.0;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_types text/plain application/x-javascript text/css application/xml;
client_max_body_size 50M;
client_header_buffer_size 8k;
large_client_header_buffers 4 16k;
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffers 32 512k;
fastcgi_busy_buffers_size 512k;
fastcgi_buffer_size 512k;
# The following includes are specified for virtual hosts
include vhosts/*.conf;
}
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 |
user nobody; worker_processes {{ grains['num_cpus'] }}; {% if grains['num_cpus'] == 2 %} worker_cpu_affinity 01 10; {% elif grains['num_cpus'] == 4 %} worker_cpu_affinity 1000 0100 0010 0001; {% elif grains['num_cpus'] == 8 %} worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; {% else %} #worker_cpu_affinity 1000 0100 0010 0001; {% endif %} worker_rlimit_nofile {{ grains['max_open_file'] }}; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections {{ grains['max_open_file'] }}; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; server_tokens off; sendfile on; tcp_nopush on; fastcgi_intercept_errors on; keepalive_timeout 65; gzip on; gzip_comp_level 5; gzip_http_version 1.0; gzip_min_length 1024; gzip_buffers 4 8k; gzip_types text/plain application/x-javascript text/css application/xml; client_max_body_size 50M; client_header_buffer_size 8k; large_client_header_buffers 4 16k; fastcgi_connect_timeout 600; fastcgi_send_timeout 600; fastcgi_read_timeout 600; fastcgi_buffers 32 512k; fastcgi_busy_buffers_size 512k; fastcgi_buffer_size 512k; # The following includes are specified for virtual hosts include vhosts/*.conf; } |
vhost配置:
[[email protected] salt]# cat /srv/salt/conf_file/nginx/vhosts/vhost.conf
server {
listen 80;
server_name 127.0.0.1;
root {{ pillar['nginx']['root'] }};
index index.php index.htm index.html;
# charset gb2312;
charset utf-8;
access_log logs/www.test.com_access.log main;
#access_log off;
if (-d $request_filename)
{
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ .+.(php|do)?$
{
fastcgi_pass 127.0.0.1:9000;
# fastcgi_pass unix:/usr/local/webserver/fastcgi/sock/fastcgi.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ .+.(dat|sql|tgz|gz|tar|zip)?$
{
deny all;
}
location ~ /.ht {
deny all;
}
}
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 |
server { listen 80; server_name 127.0.0.1; root {{ pillar['nginx']['root'] }}; index index.php index.htm index.html; # charset gb2312; charset utf-8; access_log logs/www.test.com_access.log main; #access_log off; if (-d $request_filename) { rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; } #error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ .+.(php|do)?$ { fastcgi_pass 127.0.0.1:9000; # fastcgi_pass unix:/usr/local/webserver/fastcgi/sock/fastcgi.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ .+.(dat|sql|tgz|gz|tar|zip)?$ { deny all; } location ~ /.ht { deny all; } } |
执行(salt ‘*’ state.highstate):
验证结果:
进入期中一台web服务器查看nginx安装情况,nginx已经安装成功,并且配置文件也修改完成。我们可以看到grains和pillar是非常有用的两个功能,我们可以分析应用需求,预先定义grains和pillar以便相同应用场景,一次性取值,并部署到minion上面,这是效率的一种提升,不需要你在登陆每台服务器进行修改,后面我们将继续通过案例学习grains和pillar的定义,这是非常实用的接口,需要不断的学习和练习,下面是minion配置文件的截图:
最后编辑:2014-12-10