使用自动化运维工具SaltStack安装nginx服务器 - Nginx - 服务器之家

服务器之家

专注于服务器技术!
当前位置:首页 > Web服务器 > Nginx

使用自动化运维工具SaltStack安装nginx服务器

发布时间:2016-07-21 来源:服务器之家

之前我们进行了安装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: 'L@YQD_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: 'L@YQD_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
[root@localhost 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”。
[root@localhost 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

[root@localhost 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为配置模板文件位置。
[root@localhost 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配置:

[root@localhost 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