首页 » 系统搭建 » 正文

NFS(Network File System)介绍与应用(双httpd + php-fpm + nfs + mysql 搭建discuz论坛)

NFS相关介绍

一、NFS简介

1. NFS(Network File System): NFS是一个文件共享协议, 也是是在类Unix系统中在内核中实现的文件系统。

   2. 起源: 最早是由SUN公司研发,非常古老,只是实现文件共享,安全控制方面比较简陋。 版本有, NFSv1, NFSv2,NFSv3,NFSv4. v4版开始支持kerberos 认证。

3. RPC(Remote Procedure Call):NFS协议是基于PRC(远程过程调用)实现的。

基本过程如下图,客户端某程序发起过程请求–>rpc客户端接过请求–>通过套接字通信交给服务器端–>服务器端接过请求交给某程序执行–>执行后把结果或者状态返回客户端

RPC守护进程rpcbind监听: 111/tcp 和 111/udp

RPC远程调用进程rpc.mount 监听: 2049/tcp 和 2049/udp

rpc.png

4. 关于NFS的安全设置,原生的NFS服务只能基于IP认证。 NFSv4可以基于以下两种认证方式认证

NIS: Network Information Service

Kerberos
 5. 安装配置: nfs-utils包, NFS为内核实现,所以只需要工具包

6. 三个关键进程:

mountd: 挂载搜索进程,负责客户端源认证的进程

nfsd:文件读写

idmapd:id映射进程

 7. 配置文件/etc/exports: 

1
2
3
4
5
6
7
8
9
10
11
12
配置格式: 
文件系统   客户端1(文件系统导出属性)     客户端2(文件系统导出属性)
/var/www/htdocs/Discuz/upload   192.168.98.128/24(rw,async,no_root_squash) 192.168.98.129/24(rw,async,no_root_squash)
文件导出属性: 
    rw
    async
    sync
    root_squash: 压缩root用户,基于imapd,将root通过网络访问时转换为nfsnobody用户
    no_root_squash: 不压缩root用户;
    all_squash: 压缩所有用户;
    anonuid, anongid: 指定匿名用户映射为的UID和GID;

8. 相关命令

1
2
3
4
5
6
7
8
9
10
    showmount
    -e: 在nfs客户端执行,探查某主机所导出的nfs文件系统;使用格式“showmount -e Server_IP”;
    -d: 在nfs服务器端执行,显示哪个导出的文件系统已经被至少一个客户挂载使用了;
    -a: 在nfs服务器端显示所有的挂载会话;
    exportfs:用户不重启服务重新导出目录
    -a: 操作所有文件系统
    -ra: 重新导出所有文件系统
    -ua: 取消导入的所有文件系统
    -v: 显示详细信息

9. 由于nfs辅助进程mountd默认监听随机端口,有可能会占用一些重要端口,例如80,所以有时需要锁定端口

在/etc/sysconfig/nfs 中实现

1
2
# Port rpc.mountd should listen on.
MOUNTD_PORT=892

NFS实践

双web服务器 + php-fpm + nfs + mysql 搭建discuz论坛,实现双web服务器共享后端数据。

nfs实验构架.png

nfs实验构架.pngnfs实验构架.png在四台主机上,需要搭建五个服务。 

    1) 两台主机担任前端httpd1和httpd2服务器。具有同样域名不同ip,负责简单负载均衡

    2) 一台主机担任php-fpm服务器,接受前端web服务对于php页面的反向代理请求。 NFS服务器负责为前端两个web服务器导出论坛安装目录。

    3) 最后一台主机存放mysql服务器, 为前端论坛提供数据库服务。

    以下配置过程,从后往前配置,先从mysql服务器开始 

一、 配置mysql服务器 (主机192.168.98.131)

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
1. 使用二进制文件,安装mysql 
# tar -xf mysql-5.6.25-linux-glibc2.5-x86_64.tar.gz -C /usr/local 
# ln -s /usr/local/ mysql-5.6.25-linux-glibc2.5-x86_64 /usr/local/mysql 
2. 创建mysql用户用户组 
# groupadd -r mysql 
# useradd -g mysql -r -s /sbin/nologin mysql 
3. 创建逻辑卷和挂载位置 (事先创建一块硬盘sdb)
# fdisk /dev/sdb 
    Command (m for help): n
    Command action
       e   extended
       p   primary partition (1-4)
    p
    Partition number (1-4): 1
    First cylinder (1-13054, default 1): 
    Using default value 1
    Last cylinder, +cylinders or +size{K,M,G} (1-13054, default 13054): +10G
    Command (m for help): t
    Hex code (type L to list codes): 8e
    Command (m for help): w
    The partition table has been altered!
     
# pvcreate /etc/sdb1
# vgcreate database /dev/sdb1 
# lvcreate -L 6G -n mysqlData database 
# mke2fs -t ext4 /dev/database/mysqlData
# mkdir -p /data/mysqldata
## vim /etc/fstab 添加 
/dev/database/mysqldata /data/mysqlData ext4    defaults,acl    0 0 
# mount -a 
4. 初始化数据库
# /usr/local/mysql/mysql_install_db --basedir=/usr/local/mysql --datadir=/data/mydata/ --usr=mysql
# cp /usr/local/mysql/my.cnf /etc/
添加一下两行 
[mysqld]
datadir=/data/mydata
basedir=/usr/local/mysql
user=mysql
# cp /usr/local/mysql/mysql.server /etc/rc.d/init.d/mysqld 
修改一下两行 
datadir=/data/mydata
basedir=/usr/local/mysql
启动服务 
# service mysql start 
5. 在mysql服务器的准备工作,以及添加discuz数据库。 
## 删除匿名用户以及设置管理员密码
mysql> DROP USER 'root'@'playground3'
mysql> DROP USER 'root'@'::1';
mysql> DROP USER ''@'localhost';
mysql> DROP USER ''@'playground3';
## 设置管理员密码 
mysql> SET PASSWORD FOR 'root'@'localhost' == PASSWORD('root');
mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('root');
## 创建discuzData数据库和discuz用户,并且赋予discuz数据库操作权限
## 192.168.98.130为存放discuz的服务器
mysql> CREATE USER  'discuz'@'192.168.98.130' IDENTIFIED BY 'discuz' ;
mysql> CREATE DATABASE discuzData ; 
mysql> GRANT ALL ON discuzData.* TO 'discuz'@'192.168.98.130' ;
mysql> flush privileges ;
## 在192.168.98.130上测试连接数据库服务器
# mysql -u'discuz' -h'192.168.98.131' -pdiscuz
mysql> USE discuzData
    Database changed
说明此用户已经拥有操作数据库的权限。

二、配置fpm-php服务器 (主机,192.168.98.130)

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
1. 预备好编译环境,这里不细说。常用开发包组,外加一些特殊包。
2. 编译安装 
# tar -xf php.tar.gz 
# cd php-5.3.27
# ./configure --prefix=/usr/local/php --with-mysql=mysqlnd --with-openssl --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml  --enable-sockets --enable-fpm --with-mcrypt  --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2
# make
# make intall 
# cp php.ini-production /etc/php.ini
安装xcache 
# tar -xf xcache-3.2.0.tar.gz
# cd xcache-3.2.0 
# /usr/local/php/bin/phpize
# ./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config
# make && make install
结束时候出现类似
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-zts-20090626/
整合配置文件 
# mkdir /etc/php.d
# cp xcache.ini /etc/php.d
# vim /etc/php.d/xcache.ini 修改其中一行 
extension =  /usr/local/php/lib/php/extensions/no-debug-zts-20090626/xcache.so
3. 位php-fpm提供SysV init脚本,并将其添加至服务列表:
# cp sapi/fpm/init.d.php-fpm  /etc/rc.d/init.d/php-fpm
# chmod +x /etc/rc.d/init.d/php-fpm
# chkconfig --add php-fpm
# chkconfig php-fpm on
4. 为php-fpm提供配置文件
# vim /usr/local/php/etc/php-fpm.conf
配置fpm的相关选项为你所需要的值,并启用pid文件(如下最后一行):
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pid = /usr/local/php/var/run/php-fpm.pid 
5. 接下来就可以启动php-fpm了:
# service php-fpm start

三、配置NFS服务器(主机192.168.98.130)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. 安装nfs相关包组,还有rpc组件
# yum -y install nfs-utils
# yum -y install rpcbind
2.创建discuz所在目录 
# mkdir -p /var/www/htdocs/Discuz/upload
# 然后使用fdisk命令创建一个新分区,这里是sdb1, 并且自动挂载至/var/www/htdocs/Discuz/upload
/etc/fstab下面添加 
/dev/sdb1   /var/www/htdocs/Discuz/upload   ext4    defaults,acl    0 0
3. 配置nfs导出文件 /etc/exports
## 192.168.98.128 和 192.168.98.129 将被搭建成web服务器,所以目录需要导出到这两台主机 
/var/www/htdocs/Discuz/upload  192.168.98.128/24(rw,async,no_root_squash,no_subtree_check) 192.168.98.129/24(rw,async,no_root_squash,no_subtree_check)
4. 锁定rpc.mount等辅助进程端口 
# vim /etc/sysconfig/nfs 添加下面一行
MOUNTD_PORT=892
5. 启动服务 
# service nfs start 
Starting NFS services:                                     [  OK  ]
Starting NFS mountd:                                       [  OK  ]
Starting NFS daemon:                                       [  OK  ]
Starting RPC idmapd:                                       [  OK  ]

四、配置最前端的两台web 服务器 (192.168.98.128 和 192.168.98.129)

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
1. 同样安装编译环境。
2. 安装apache运行环境apr和apr-util 
# tar xf apr-1.5.2.tar.gz
# cd apr-1.5.2
# ./configure --prefix=/usr/local/apr
# make && make install
# tar xf apr-util-1.5.4.tar.gz
# cd apr-util-1.5.4
# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
# make && make install
3. 编译安装httpd 
# tar -xf httpd-2.4.16.tar.gz
# cd httpd-2.4.16
# ./configure --prefix=/usr/local/httpd24 --sysconfdir=/etc/httpd24 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --enables-modules=most --enable-mpms-shared=all --with-mpm=event
# make && make install
4. 提供服务脚本 
# vim /etc/rc.d/init.d/httpd24 复制粘贴一下内容,通常把yum源安装的httpd服务脚本,稍加修改即可
#!/bin/bash
#
# httpd        Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
# description: Apache is a World Wide Web server.  It is used to serve \
#        HTML files and CGI.
# processname: httpd
# config: /etc/httpd/conf/httpd.conf
# config: /etc/sysconfig/httpd
# pidfile: /var/run/httpd.pid
# Source function library.
/etc/rc.d/init.d/functions
if [ -f /etc/sysconfig/httpd ]; then
        /etc/sysconfig/httpd
fi
# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}
# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""
# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.
# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/local/httpd24/bin/apachectl
httpd=${HTTPD-/usr/local/httpd24/bin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd24.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd24}
RETVAL=0
start() {
        echo -n $"Starting $prog: "
        LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}
stop() {
  echo -n $"Stopping $prog: "
  killproc -p ${pidfile} -d 10 $httpd
  RETVAL=$?
  echo
  [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
reload() {
    echo -n $"Reloading $prog: "
    if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/nullthen
        RETVAL=$?
        echo $"not reloading due to configuration syntax error"
        failure $"not reloading $httpd due to configuration syntax error"
    else
        killproc -p ${pidfile} $httpd -HUP
        RETVAL=$?
    fi
    echo
}
# See how we were called.
case "$1" in
  start)
  start
  ;;
  stop)
  stop
  ;;
  status)
        status -p ${pidfile} $httpd
  RETVAL=$?
  ;;
  restart)
  stop
  start
  ;;
  condrestart)
  if [ -f ${pidfile} ] ; then
    stop
    start
  fi
  ;;
  reload)
        reload
  ;;
  graceful|help|configtest|fullstatus)
  $apachectl $@
  RETVAL=$?
  ;;
  *)
  echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
  exit 1
esac
exit $RETVAL
# chmod +x /etc/rc.d/init.d/httpd
# chkconfig --add httpd24
5. 配置httpd
## 创建网页文件目录
# mkdir -p /var/www/htdocs/Discuz/upload/
## 查看192.168.98.130主机是否成功导出目录 
# showmount -e 192.168.98.130 
    Export list for 192.168.98.130:
    /var/www/htdocs/Discuz/upload 192.168.98.129/24,192.168.98.128/24
    
## 在/etc/fstab中添加自动挂载项 
192.168.98.130:/var/www/htdocs/Discuz/upload    /var/www/htdocs/Discuz/upload   nfs     auto,acl        0 0
# mount -a 
6. 配置虚拟主机,设置反向代理
# vim /etc/httpd24/httpd.conf 添加或者开启
## 反向代理支持模块
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so  
## 虚拟主机,需要注释掉原主机
#DocumentRoot "/usr/local/httpd24/htdocs/Discuz/upload"
<VirtualHost *:80>
    DocumentRoot "/var/www/htdocs/Discuz/upload"
    DirectoryIndex index.php index.html home.html default.html
    ServerName www.discuz.com
    ProxyRequests Off
    ProxyPassMatch ^/(.*\.php)$ fcgi://192.168.98.130:9000/var/www/htdocs/Discuz/upload/$1
    <Directory "/var/www/htdocs/Discuz/upload">
        Options none
        AllowOverride none
        Require all granted
    </Directory>
</VirtualHost>
## 启动服务 
# service httpd24 start

五、安装discuz论坛并测试 。

windows 测试

1
2
3
修改C:\Windows\System32\drivers\etc\hosts 文件,添加如下两行 
192.168.98.128      www.discuz.com 
192.168.98.129      www.discuz.com

浏览器输入域名后,即可进行安装,数据库安装时,输入预先在192.168.98.131数据库服务器上设置的认证信息

discuz.png

关闭192.168.98.129 web服务器,上传一个图片

TESTING_UPLOAD.png

关闭192.168.98.128后,启动192.168.98.129,刷新浏览器依然可以看到附件,说明负载均衡生效了

upload_testing2.png