搭建一套简单的web服务器,记录实验过程

搭建web服务器

一、实验内容:

  实验要求:

  1、完成一个简单的web服务器,web服务器从mysql里读取数据进行返回
  2、Mysql需要有一个单独的数据盘,每个mysql虚拟机的磁盘挂载方式需要都不一样
  3、公网ip配置在虚拟机上,三个web服务器用snat访问公网
  4、使用dnat把8080端口映射到公网去,访问控制台的8080端口需要能够访问web server
  5、web服务器和mysql服务器需要在不同的子网和vlan里,需要在宿主机上自建一个虚拟路由器
  6、msyql和web server都需要使用keepalived和haproxy做负载均衡
  7、对物理机做使用iptables做安全策略,只允许22和8080进来,并且禁ping

  拓扑图:

搭建一套简单的web服务器,记录实验过程搭建一套简单的web服务器,记录实验过程

二、实验思路 

  刚拿到任务的时候,自己其实是很懵逼的,对于实验中要求实现的内容,绝大部分在之前的运维工作中并没有接触过;

  任务分解:

  完成一个简单的web服务器,web服务器从mysql里读取数据进行返回

  分解:前后端分离,包含数据库和web服务,需要确认使用什么方式实现前后端的联通;

     web主机和mysql主机均为3台,需要使用浮动IP来实现连接;

  mysql需要有一个单独的数据盘,每个mysql虚拟机的磁盘挂载方式需要都不一样

  分解:总共有三台mysql主机,需要使用三种不同的方式来实现挂载;

  公网ip配置在虚拟机上,三个web服务器用snat访问公网

  分解:要做实验就要安装软件,既然没有内网yum源,那么所有6台实验主机都需要能够访问公网,解决软件包安装的问题,通过配置iptables规则来实现;

  使用dnat把8080端口映射到公网去,访问控制台的8080端口需要能够访问web server

  分解:实验环境的网络需要隔离,可以通过ip namespace来实现;需要配置两次DNAT规则(宿主机默认ipns下一次、实验环境ipns中一次),两次衔接,实现外部网络可以通过指定端口访问web服务器

  web服务器和mysql服务器需要在不同的子网和vlan里,需要在宿主机上自建一个虚拟路由器

  分解:网络规划已经做好,不同的vlan可以通过ovs设置tag来实现

  msyql和web server都需要使用keepalived和haproxy做负载均衡

  分解:web服务使用keepalive和haproxy实现负载均衡比较好实现;

     mysql服务使用keepalive和haproxy实现负载均衡要怎样实现?

  对物理机做使用iptables做安全策略,只允许22和8080进来,并且禁ping

  分解:iptables放行端口,初步想到两种方式来实现(设置默认策略为DROP,为22和8080单独添加规则;不更改默认策略,在放行22和8080端口后添加拒绝所有连接的规则)

     iptables设置禁ping规则

  完成思路:

  实验的最终结果是完成一个环境的搭建,包含有多台主机;分析实验内容后发现这个大的任务其实可以被拆分成几个板块来完成,一个部分的实现与否对其他部分的影响并不大:

  1、虚拟机的搭建和基础环境配置;

  2、网络拓扑的实现和配置;

  3、web集群搭建(http+keepalive+haproxy);

  4、mysql集群搭建(galera+keepalive+haproxy);

  5、iptables规则配置,实现DNAT、SNAT功能;

  6、mysql和http前后端联通配置;

  7、iptables配置策略放行22、8080端口,禁ping;

三、实验过程

  说干就干,参照着完成思路开始:

  1、虚拟机的搭建和基础环境配置

   要搭建环境,首先需要有可用的虚拟机环境才行;这里使用的是kvm创建出来的虚拟机,在进行自己的实验前,有几点需要注意:

   a、查看宿主机相应分区的空间是否足够,需要创建6台虚拟机,估算一下大致需要的空间,空间不足则需要进行扩容;

   b、为这个实验单独创建一个项目目录,存放此次实验需要用到的所有文件;

   c、在新创建的目录下新建相应的目录,用于存放虚拟机的各种文件:base存放基础的qcow2文件,已经装好系统、sys存放各台虚拟机的qcow2镜像文件,也即各台虚拟机的实际保存位置、xmlfiles存放的是各台虚拟机创建时使用的xml文件

   新建的项目目录为/home/mission1/,在这目录下包含三个目录/home/mission1/{base,sys,xmlfiles}。

  • 虚拟机镜像文件

   在/home/mission1/base/目录下存放centos7_1503.qcow2,这个是已经安装了CentOS7.1操作系统的磁盘文件;

   虚拟机镜像支持多种类型,包括有raw、qcow2、vmdk、vdi等:

   a、raw:未作任何处理的镜像格式,等同于用dd命令对磁盘做的复制;这种格式的优点是简单,可以很容易的导出到其他硬件模拟器中去,如果自己的文件系统支持稀疏文件,如linux下的ext2/3、windows的ntfs,那只有写入的字段会占用空间。

   b、qcow2:qemu仿真器支持的镜像格式,可以动态扩大,支持写时复制;该格式是最万能的格式,即使是在不支持稀疏文件的文件系统上,也可以获得最小空间的镜像文件,还包含AES加密、zlib压缩、支持虚拟机快照等。

   c、vdi:virtualbox和qemu仿真器支持的磁盘镜像格式。

   d、vmdk:许多hypervisor支持的磁盘镜像格式。

   创建镜像文件的命令示例如下:   

  1 # qemu-img create -f qcow2 -o /home/mission1/sys/test.qcow2 10G

   我们此处使用的是已经安装了CentOS7.1操作系统的磁盘镜像文件,少去安装操作系统的步骤。

  • 虚拟机xml配置文件

   在/home/mission1/xmlfiles/目录下存放有normal-node-define.xml,这个是虚拟机模板的配置文件。

   每台安装完成的虚拟机都有自己的xml文件,保存了这台虚拟机的配置信息,包含有domain名、cpu、内存、磁盘、网络等;我们也可以通过修改模板xml文件来启用一台新的VM。

  • 虚拟机创建

   通过kvm来创建VM有多种方式,以下列举几种常用的方式:

   a、通过网络镜像安装,支持vnc。   

  1 # virt-install --name test01 --ram  --vcpus  -f /home/mission1/sys/test.qcow2 --os-type linux --os-variant rhel7 --network bridge=br-lwr --graphics vnc,listen=0.0.0.0 --location 'http://mirrors.163.com/centos/7.1.1503/os/x86_64/'

   b、通过 iso 镜像本地安装,支持 vnc。   

  1 # virt-install --name test01 --ram  --vcpus  -f /home/mission1/sys/test.qcow2 --os-type linux --os-variant rhel7 --network bridge=br-lwr --graphics vnc,listen=0.0.0.0 --cdrom /home/mission1/base/CentOS-7.1..iso

   c、编辑模板xml文件,直接通过模板文件生成新VM。

   编辑xml文件<略>   

  1 # virsh define /home/mission1/xmlfile1/test1.xml

   我们采用的是第三种方式,有现成的安装了操作系统的qcow镜像文件,直接复制编辑模板xml配置文件即可   

  1 # cp /home/mission1/xmlfiles/{normal-node-define.xml,test.xml}
 2
 3 # vim /home/mission1/xmlfiles/test.xml  
 4
 5    <name>mark_vm_name</name>                  <--设置VM名字
 6
 7    <memory unit='KiB'>mark_vm_mem_in_kb</memory>         <--设置VM内存大小
 8
 9    <currentMemory unit='KiB'>mark_vm_mem_in_kb</currentMemory>
     <vcpu placement='static'>mark_vm_vcpu_count</vcpu>        <--设置CPU个数
 
     <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='mark_vm_sys_disk'/>                <--填写磁盘镜像文件路径
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      </disk>
 
     <interface type='bridge'>
      <!--需要设置虚拟机绑定的内网网桥-->
      <source bridge='mark_cluster_bridge'/>              <--设置VM网卡所属bridge
      <virtualport type='openvswitch'>
      </virtualport>
      <model type='virtio'/>
     </interface>

  编辑完成后,直接使用以下命令创建VM:   

 1 # virsh define /home/mission1/xmlfile1/test1.xml

  开启VM:   

 1 # virsh start domain-name

  查看VM的vnc连接口:   

 1 # virsh vncdisplay domain-name

  使用vnc客户端连接,在VNC Server框中输入:<宿主机IP>:<连接口>

  通过vnc客户端进入VM,完成基础配置(配置IP地址、关闭selinux、关闭iptables、设置时间同步、配置主机名等);同样的方式创建并配置其他5台虚拟机。

  至此,VMs创建及配置完成。

2、网络拓扑的实现和配置

  对于网络架构的实现,刚开始的切入点是直接从实验任务中给出的图考虑的;要完成实验,有几个前提是确认的:

  a、要有自己对外的网桥,用openvswitch来实现(设置VM网卡所需bridge需要填写);

  b、实验网络需要与宿主机网络隔离,使用ip namespace实现;

  c、需要给各台实验虚拟机网络配置vlan,使用openvswitch实现;

  d、实现虚拟机需要联通外部网络,用于软件安装和后期功能实现,需要配置路由和iptables规则;

  实现过程中有过的疑惑和问题:

  1)联通ip namespace内部ip和外网,用什么方式实现?

  2)网桥上新建的网卡类型,为什么要设置成type=internal?

  3)为什么在ip namespace中给各台虚拟机连接的网口设置了vlan,不同vlan的IP地址还是能够ping通?

  4)对各个组件的功能的搭配存在困惑,仍然比较迷糊,veth pair是否能在这个场景下发挥作用?

  问题先不说怎么解决的,先来解决现有的需求。

  • 网桥创建

  在宿主机上执行以下命令,创建一个自己的网桥:  

 1 # ovs-vsctl add-br br-lwr

  查看生成的网桥,网桥创建成功:

 1 # ovs-vsctl show
  Bridge br-lwr
  Port br-lwr
  Interface br-lwr
  type: internal
  • ip namspace创建

  在宿主机上执行以下命令,创建一个自己的ip namespace:

 1 # ip netns add lwr-ns
  • 联通ip namespace中网络和公网

  在网桥上新建两个internal类型的网口

 1 # ovs-vsctl add-port br-lwr web-nw tag=20 -- set Interface web-nw type=interval
  # ovs-vsctl add-port br-lwr myql-nw tag=30 -- set Interface mysql-nw type=interval

  将在网桥上新建的两个网卡增加到新建的ip namespace中

 1 # ip link set mysql-nw netns lwr-ns
  # ip link set web-nw netns lwr-ns

  为两个新加入ip namespace中的网卡配置IP地址

 1 # ip netns exec lwr-ns ip addr add 192.168.0.1/ dev mysql-nw
  # ip netns exec lwr-ns ip addr add 172.16.0.1/ dev web-nw
  # ip netns exec lwr-ns ip link set web-nw up
  # ip netns exec lwr-ns ip link set mysql-nw up
  # ip netns exec lwr-ns ip link set lo up

  新增了ip namespace后,命名空间隔离了网络,内部的主机无法联通外网,需要再进行配置。

  再br-lwr上新增一个网口,增加完成后加入到lwr-ns中去,在ip namespace中为该网口配置一个IP地址192.168.100.2

 # ovs-vsctl add-port br-lwr con-wm -- set Interface con-wm type=internal
# ip link set con-wm netns lwr-ns
# ip netns exec lwr-ns ifconfig con-wm 192.168.100.2/
# ip netns exec lwr-ns ip link set con-wm up

  为br-lwr配置一个IP地址,用于联通ip namespace和宿主机网络

 1 # ifconfig br-lwr 192.168.100.1 netmask 255.255.255.0 up

  此时在ip namespace仍然无法ping通外网,需要在宿主机上配置一条iptables规则

 # iptables -t nat -A POSTROUTING -s 192.168.100.0/ ! -d 192.168.100.0/ -j MASQUERADE

  设置默认路由规则,用于ip namespace联通外网

 # ip netns exec lwr-ns ip route add default via 192.168.100.1 
  • 为各台虚拟机网络配置vlan

  在创建虚拟机的时候,xml文件中已经设定了网口是连接到哪个网桥上的;

  当虚拟机创建成功后,相应的网桥上会有网口出现,数量对应这台虚拟xml文件中的配置数目;

  设置vlan就是通过openvswitch对相应的网口打上tag,在进行这步操作前,我们需要先确认各台虚拟机网口的的名字,再对相应的网口打上tag  

 # virsh dumpxml <domain-name> | grep vnet
<target dev='vnet18'/>
# ovs-vsctl set port vnet18 tag=

  对其他五台虚拟机进行同样的操作,配置前需要确认清楚各台虚拟机的vlan及网卡名

  • 配置虚拟机联通外网

  虚拟机的网络配置已在前面完成,接下来要安装软件,但此时仍无法联通外网;我们需要在ip namespace中配置相应的iptables规则,使其能够访问外部网络

 # iptables -t nat -A POSTROUTING -s 192.168.200.0/ ! -d 192.168.200.0/ -j MASQUERADE
# iptables -t nat -A POSTROUTING -s 172.16.200.0/ ! -d 172.16.200.0/ -j MASQUERADE

  执行上两步的操作目的为配置转发,来自192.168.200.0和172.16.200.0网段的请求通过SNAT联通到ip namespace中;

  进入ip namespace后,通过默认路由转到宿主机,宿主机再通过SNAT将请求发送出去,联通外部网络。

  至此,网络配置基本完成。

3、web集群搭建(http+keepalive+haproxy)

  web集群搭建相对简单,采取的方式为http+keepalive+haproxy的方式实现,在三台IP地址为172.16.0.0网段的虚拟机安装http、haproxy、keepalive  

 # yum install haproxy keepalived httpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors..com
* epel: mirror01.idc.hinet.net
* extras: mirrors..com
* updates: centos.ustc.edu.cn
Package haproxy-1.5.-.el7.x86_64 already installed and latest version
Package keepalived-1.3.-.el7.x86_64 already installed and latest version
Package httpd-2.4.-.el7.centos..x86_64 already installed and latest version
Nothing to do

  软件安装完成后,分别进行配置,以一台虚拟机为例,分别配置三个软件:

  a、配置keepalived服务,备份配置文件后,修改相应配置内容,启用服务并设定开机自启

   主节点配置文件内容如下:(注意:在其他两个web节点中需要将vrrp_instance ha1段state更改为BACKUP,priority值设置小于100)

 global_defs {
notification_email {
root@localhost # 告警邮件接收地址
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1 # smtp服务器地址
smtp_connect_timeout # 连接smtp服务器超时时间
router_id web01 # 每一个节点的router_id都是唯一的,不可以重复
vrrp_script haproxy{
script "kiall -0 haproxy"
weight -
}
}
vrrp_instance ha1 {
state MASTER # 角色为MASTER
interface eth0 # 指定haproxy检查网络的接口
virtual_router_id # 虚拟路由的ID,在所有的keepalived节点必须保持一致
priority # 优先级
advert_int # 心跳检查的时间间隔
authentication {
auth_type PASS # 指定keepalived节点之间的验证方式为密码验证
auth_pass linux # keepalived节点的认证密码
}
virtual_ipaddress {
172.16.0.5/ dev eth0 # vip地址
}
track_script{
haproxy # 调用haproxy检查脚本
}
}

   在修改配置文件前,先备份原配置文件;启用服务并设置开机自启:

 # cp /etc/keepalived/keepalived.conf{,.bak20180708}
<!修改配置文件内容>
# systemctl start keepalived && systemctl enable keepalived

  b、配置haproxy服务,备份配置文件后,修改相应配置内容,启用服务并设置开机自启

   节点配置文件内容如下:   

 global                                          # 全局配置
log 127.0.0.1 local3 info # 把发送到日志设备local3的info级别的日志记录在本地
chroot /var/lib/haproxy # 绑定haproxy的工作路径
pidfile /var/run/haproxy.pid # pid文件路径
maxconn # 最大连接数
user haproxy # 运行进程的用户
group haproxy # 运行进程的用户组
daemon # 以后台方式运行
stats socket /var/lib/haproxy/stats # haproxy动态维护的套接字文件,下面会通过一个小实验看这个玩意的作用
defaults # 除非有具体定义,否则default选项会加入到后面 选项,不适用的就不会被定义
mode http # 默认的模式
log global # 引用全局的日志配置
option httplog # 启用日志记录http请求,haproxy默认不记录http请求日志
option dontlognull # 日志中不记录健康检查的连接
option http-server-close # 对于某些server端不支持http长连接的情况,利用这个参数可以使用客户端到haproxy是长连接,而haproxy到server端是短连接
option forwardfor except 127.0.0.0/ # 允许服务器记录发起请求的真实客户端的IP地址
option redispatch
retries # 连接真实服务器的失败重连次数,超过这个值后会将对应正式服务器标记为不可用
timeout http-request 10s # http请求超时时间
timeout queue 1m # 请求在队列中的超时时间
timeout connect 10s # 连接超时
timeout client 1m # 客户端连接超时
timeout server 1m # 服务端连接超时
timeout http-keep-alive 10s # http-keep-alive超时时间
timeout check 10s # 检测超时时间
maxconn # 每个进程最大的连接数
frontend www # 定义前端
bind *: # 绑定客户端访问的是哪个IP的80端口
mode http # 指定模式为http
option httplog # 记录http请求的日志
log global # 应用全局的日志配置
stats uri /haproxy?stats # haproxy自带的监控页面
default_backend web # 指定默认的后端
backend web # 定义后端
mode http # 模式为http
option redispatch
balance roundrobin # 负载均衡算法指定为轮询
option httpchk GET /index.html # 检测后端真实服务器的方法
server web01 172.16.0.2: cookie web01 weight check inter rise fall
server web02 172.16.0.3: cookie web02 weight check inter rise fall
server web03 172.16.0.4: cookie web03 weight check inter rise fall

   在修改配置文件前,先备份原配置文件;启用服务并设置开机自启:

 # cp /etc/haproxy/haproxy.cfg{,.bak20180708}
<!更改配置文件内容>
# systemctl start haproxy && systemctl enable haproxy

  c、配置httpd服务,需要更改监听端口配置;结合后面需要连接数据库,需要使用脚本连接数据库,需要开放cgi-bin配置

   更改配置文件前,备份原始配置文件;更改监听端口,放开cgi-bin配置内容

 # cp /etc/httpd/conf/httpd.conf{,.bak20180708}
<!更改配置文件内容>
# cat /etc/httpd/conf/httpd.conf | egrep -v '#|^$'
...
Listen
...
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
LoadModule cgid_module modules/mod_cgid.so
<Directory "/var/www/cgi-bin">
Options +ExecCGI
</Directory>
AddHandler cgi-script .cgi .py .sh
...
## 确保配置文件中包含以上内容

   启用服务并设置开机自启:

 # systemctl start httpd && systemctl enable httpd

  至此,web集群配置基本完成。

4、mysql集群搭建(galera+keepalive+haproxy)

  mysql集群配置最终确认方案为采用glaera集群+keepalived+haproxy:

software mysql01(192.168.0.2)  mysql02(192.168.0.3) mysql03(192.168.0.4)
CentOS 7.1.1503 mysql01 mysql02 mysql03
MariaDB Galera cluster mysql01 mysql02 mysql03
Keepalived(192.168.64.100) mysql01 mysql02 mysql03
haproxy mysql01 mysql02 mysql03

  a、配置galera集群

   配置yum源

----------------------------------------------------------

待续...

上一篇:Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程


下一篇:mdadm命令详解及实验过程