之前,我写过一个基于Windows平台运行VMware Server虚拟机的服务器托管方案。一直在朋友的服务器上运行了4年多。后来慢慢接触了Linux系统,经过一段时间的学习,发现Linux系统的性能及稳定性比Windows要强很多。所以,我打算将原来的服务器虚拟化方案转到Linux系统平台下。
经过近段时间的研究和测试,最后成功的将朋友的服务器迁移到了Linux平台,使用Linux系统和一些开源软件使服务器托管利用虚拟化技术和免费开源软件、系统再次降低成本,同时又提高了系统的性能。
此方案中实现的功能及特点:
1、 共享一个公网IP地址,发布多个虚拟机中的各种服务。
2、 多个虚拟机中的web站点共享80端口,实现通过域名访问虚拟机中的站点。
3、 宿主机上全部使用免费开源的操作系统及软件,节省软件费用。
4、 利用Linux下强大的iptables来保护服务器,相比Windows下的防火墙性能更优秀。
5、 Nginx超强的高并发处理能力、低系统资源开销,使服务器能够处理更多的并发web访问请求。
6、 利用Nginx的反向代理缓存功能,为Windows虚拟机站点加速。(新加入的一个优化配置)
CentOS中配置支持NTFS文件系统格式(宿主机)
添加此节内容,是为一些需要将Windows下的数据导入到Linux平台的用户方便。
CentOS系统默认情况下并不支持挂载ntfs分区,需要我们单独安装ntfs的驱动才能对ntfs分区进行读写操作,用uname –r命令查看系统内核版本信息,并下载相应的NTFS驱动。本例中版本是kernel-module-ntfs-2.6.18-128.el5。
安装命令:
rpm -ivh kernel-module-ntfs-2.6.18-128.el5-2.1.27-0.rr.10.11.i686.rpm
运行/sbin/modprobe ntfs加载内核模块,检查是否加载成功。
[root@localhost ~]# dmesg | grep NTFS
NTFS driver 2.1.27 [Flags: R/W MODULE].
如果出现上面的信息,说明已经可以对ntfs分区进行读写操作了。也可以运行cat /proc/filesystems命令进行查看。
接下来就是将要迁移的磁盘分区挂载到CentOS系统下,然后迁移数据。挂载NTFS分区(/dev/hda6为原Windows系统下的C盘分区)命令如下:
mount -t ntfs /dev/hda6 /mnt/c
系统配置环境
下表中列出了本方案的各种配置信息:
操作系统 | 相关软件 | 网络配置 | 备注 |
CentOS/Linux(版本自选)此为宿主机,安装到物理服务器上 | Vmware Server 2.0(用于虚拟化的实现) | Eth0:192.168.10.5/24 Eth1:10.10.5.254 (此ip为实验环境,实际应用时要修改此IP) | 后文对物理主机上的操作系统称为宿主机 宿主机的eth0:内网网卡(与虚拟机相连的虚拟网卡vmnet1) 宿主机eth1 :外网网卡(此网卡绑定了公网IP地址) 虚拟机系统,对外提供各种服务 虚拟机网卡的连接方式选Host-only |
CentOS/Linux(版本根据需要可自选) | 安装相关应用程序Apache、FTP、Mysql | Etho0:192.168.10.20/24 网关:192.168.10.5 | |
Windows操作系统 | IIS、FTP、MSSql、Mail | 本地连接:192.168.10.10/24 网关:192.168.10.5 | |
其他虚拟机系统 |
虚拟机和宿主机的拓扑图如下:
安装配置Nginx 0.8.35(宿主机)
1、 安装Nginx所需的pcre库:
到http://www.pcre.org/去下载最新版
tar zxvf pcre-8.01.tar.gz
cd pcre-8.01/
./configure
make && make install
cd ../
2、 安装Nginx清理缓存模块
使用此模块可以实现缓存的清理任务
wget http://labs.frickle.com/files/ngx_cache_purge-1.0.tar.gz
tar zxvf ngx_cache_purge-1.0.tar.gz
只要将模块解压出来即可,在编译Nginx时同时编译此模块。
3、 安装Nginx
到http://www.nginx.org/en/download.html下载最新版
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
tar zxvf nginx-0.8.35.tar.gz
cd nginx-0.8.35/
./configure --user=www --group=www --add-module=../ngx_cache_purge-1.0 --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module
make && make install
cd ../
4、 修改Nginx全局配置文件
worker_processes 2;
access_log off;
error_log off;
events {
use epoll;
worker_connections 65535;
}
#charset gb2312;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi相关配置可以删除不使用,仅做记录暂不使用.
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
5、 配置开机自动启动Nginx
修改/etc/rc.local文件,在最后加入如下命令
ulimit -SHn 65535
/usr/local/nginx/sbin/nginx
优化Linux内核参数(宿主机)
修改/etc/sysctl.conf文件,在最后加入以下内容:
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
#net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535
使配置立即生效:
/sbin/sysctl –p
设置Web站点的域名请求转发及缓存加速(宿主机)
相对于之前的转发方法,感觉这个方法比较直观也比较简单、容易理解。
下面是整个nginx的配置文件内容,里边包括了Nginx的反向代理设置和缓存配置方法。
[root@localhost conf]# cat nginx.conf
#user nobody;
worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
#access_log logs/access.log;
error_log logs/error.log;
events {
use epoll;
worker_connections 65535;
}
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"';
log_format test '$remote_addr - $uri'
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
proxy_temp_path /var/proxy_temp_dir;
proxy_cache_path /var/proxy_cache_dir levels=1:2 keys_zone=cache_one:300m inactive=1d max_size=5g;
proxy_cache_valid 200 304 12h;
add_header X-Cache Nginx-X;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_key $host$uri$is_args$args;
server
{
listen 80;
server_name www1.duxt.net www2.duxt.net;
access_log off;
#limit_conn crawler 20;
location / {
proxy_cache cache_one;
proxy_pass http://192.168.10.10:80;
}
location ~ /p(/.*)
{
allow 127.0.0.1;
allow 10.10.5.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}
location ~* .*\.(php|jsp|cgi|asp|aspx)$ {
proxy_pass http://192.168.10.10:80;
}
}
server #每个虚拟机对应一个 server 配置,用来做判断和转发对站点的请求。
{
listen 80;
server_name ~www[34]\.duxt\.net; #虚拟机中绑定的域名全部写到这里,可以用正则表达式
access_log off; #关闭日志,避免访问日志过大占用大量磁盘空间.
location / {
proxy_cache cache_one;
proxy_pass http://192.168.10.20:80; #虚拟机的IP地址
}
location ~ /p(/.*) #清缓存连接地址
{
allow 127.0.0.1;
allow 10.10.5.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}
location ~* .*\.(php|jsp|cgi|asp|aspx)$ { #不缓存动态页面文件,如果有其他动态页面扩展名可以写到这里
proxy_pass http://192.168.10.20:80;
}
}
}
以上测试环境配置中涉及到的域名www1.duxt.net和www2.duxt.net是虚拟机192.168.10.10上的站点域名,www3.duxt.net和www4.duxt.net是虚拟机192.168.10.20上的站点域名。
同样,与之前的方法一样,server name指令也是支持利用正则表达式对域名进行匹配的,域名之间用空格隔开。
防火墙策略设置部分(宿主机)
对宿主机的iptables进行基本的初始化配置,设置防火墙策略的默认配置。首先要开启防火墙的路由功能,使用以下命令实现:
echo 1 > /proc/sys/net/ipv4/ip_forward
允许访问宿主机SSH
/sbin/iptables -t filter -I INPUT -s 0.0.0.0/0 -p tcp --dport 22 -j ACCEPT
设置默认策略
/sbin/iptables -P INPUT Drop
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -t nat -P PREROUTING ACCEPT
/sbin/iptables -t nat -P OUTPUT ACCEPT
/sbin/iptables -t nat -P POSTROUTING ACCEPT
允许内网虚拟机系统访问外网
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.10.0/24 -j SNAT --to 10.10.5.254
利用iptables来发布虚拟机中的各种服务(宿主机)
设置IIS FTP连接端口为10000。被动模式的端口范围(10001-10005),使用以下vbs脚本命令进行修改
cscript.exe adsutil.vbs set /MSFTPSVC/PassivePortRange "10001-10005" (在Windows虚拟机中执行)
发布内网虚拟机192.168.6.100的10000-10005端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 10000:10005 -j DNAT --to 192.168.10.10
发布内网虚拟机192.168.6.100的远程桌面端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 3389 -j DNAT --to 192.168.10.10:3389
发布内网虚拟机192.168.6.100的MSsql端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 1433 -j DNAT --to 192.168.10.10:1433
发布内网虚拟机192.168.6.200的20000-20005端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 20000:20005 -j DNAT --to 192.168.10.20
发布内网虚拟机192.168.6.200的SSH端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 19222 -j DNAT --to 192.168.10.20:22
发布内网虚拟机192.168.6.200的Mysql端口
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 3306 -j DNAT --to 192.168.10.20:3306
发布宿主机的Nginx,用于转发对虚拟机web的请求。
iptables -t filter -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -s 192.168.10.0/24 -p tcp -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -p tcp --dport 80 -j ACCEPT
保存防火墙规则
service iptables save
解决虚拟机中网站日志中客户端真实IP问题(虚拟机)
通过Nginx转发一次http请求到虚拟机系统后,网站的日志文件中记录的都是宿主机的内网IP,影响网站日志的访问统计。为了让虚拟机系统中的网站日志能够记录客户端真实IP地址,需要做相关的修改。
解决虚拟机中Apache日志中客户端IP问题
Apache的修改相对比较简单
修改Apache的配置文件httpd.conf,找到LogFormat将后边的%h替换成%{X-Forwarded-For}i 并重启Apache.
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" Forwarded
CustomLog logs/test2.com1.log Forwarded
解决虚拟机中IIS日志中客户端IP问题
Windows的IIS比较麻烦一些,不能直接修改IIS日志中的参数。
实现日志记录真实客户端IP,需要借助F5提供的一个客户端软件F5XforwardedFor。可以到F5网站下载到(我的博客地址也有下载http://www.duxt.net/article.asp?id=92)。
下载后,会得到一个F5XforwardedFor.dll文件,将此文件解压到IIS目录或者自己创建一个目录。
打开IIS,打开网站属性,如下图1、2:
图1
图2
选择ISAPI筛选器,添加一个新的筛选器,就是刚才解压的F5XforwardedFor.dll文件。相关配置如图3、4。
图3
图4
添加完成后,需要重启IIS才能生效。
图5
如果重启后不生效,打开IIS web服务扩展,设置 所有未知ISAPI扩展 为 允许,如图6。
图6
最后,将域名www1.duxt.net解析到宿主机的公网地址上,然后访问此域名,如图7。
图7
访问几次后,就可以到虚拟机上去查看站点的IIS日志了。
图8
总结
本文中涉及到的iptables配置,只是用于实现对虚拟机中各种服务及端口的发布,未涉及到宿主机及虚拟机中的安全配置。可根据个人的需要,参考其他iptables相关的安全文档进行设置。
另外,可以将相关的iptables命令编写成shell脚本,设置开机启动运行。
有关宿主机中的Nginx作为一个转发代理,可以将它的日志功能关闭,避免不必要的日志占用大量磁盘空间。
使用iptables发布各种服务器,在本文档中只是简单举了几个比较典型的实例,可以根据个人的需要参照本文档中的命令,可以实现所有服务及端口的发布。需要注意的是,如果你使用的防火墙规则过多,要注意规则的顺序,iptables对规则的顺序是有要求的。出现设置防火墙策略不生效时,要仔细检查一下顺序是否正常。
宿主机的CentOS系统可以根据个人需要,有选择的添加组件。建议最小化安装CentOS,保留yum用于以后宿主机的补丁升级或者安装各种所需要的组件。不推荐在宿主机系统中安装过多的服务。
在解决根据域名来发布web站点问题时,也曾经使用squid来实现,但是后来经过多次试验发现,无论从配置的简易程度及效率上,还是nginx比较优秀。如果你对squid比较熟悉或者热衷于squid也可以使用squid来做网站的发布。
最后,此方案中没有提到服务器硬件的配置,这个可以根据不同的需求配置硬件。我个人建议增加内存和提高磁盘IO是关键。因为运行的虚拟机多了,磁盘IO就会成为瓶颈。
补充
1、宿主机使用32位系统后,对于大内存(4GB以上)支持问题。默认情况下如果是CentOS一般会自动启用PAE来支持大内存,如果你用的是其他发布版本,可能默认情况下不会启用PAE。手动安装PAE命令如下:
yum install kernel-PAE
yum remove kernel
安装完成后,重启系统即可。
如果服务器内存超过4GB,建议最好还是使用64位的系统,毕竟PAE方式做了一次地址映射,速度还是会受到影响。
2、(未完待续)
转载于:https://blog.51cto.com/duxt123/328799