前言
PAAS:platform as a service,平台即服务,把软件研发的平台作为一种服务,提供给用户使用。当前PAAS平台服务商,诸如google app engine,sina app egine,cloud foundry等,都是程序员们的福音,可以避免从无到有搭建程序运行的平台,多了一个选择。
本着学习PAAS的态度,构建一个简易版PAAS平台,构建JAVA运行时环境,提供tomcat servlet容器服务。当然,不局限于JAVA,PHP、ROR、nodejs等,理论上行得通。但这里以构建Tomcat Servlet环境为主。
说是简易版,基本靠谱,所有的操作,都需要手动操作,高端功能组件,诸如计费、安全等,暂时还不涉及。仅搭建一个原型,别期望过多,可能为了表示最核心的PAAS的核心部分,其它更为先进的功能,都是在核心的功能上进行的拓展。但这对认识PAAS,可能会有点帮助。
一般来说,虚拟化建立在性能强劲的物理机器上,IAAS(基础即服务)建立在虚拟化技术的基础上,PAAS建立在IAAS基础上,SAAS(软件即服务)可以建立在PAAS的基础上。可以从总体上感知各种服务之间关系,这样做资源利用会更高效些。
PAAS,每一个Tomcat运行平台之间,诸如内存空间、CPU使用、磁盘IO等资源,需要做到相互隔离,并且可以配置。目前Linux服务器一般用KVM、XEN、LVS等虚拟化方案,但与Lxc(Linux Container)相比,有些重。Lxc是一种Linux内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性(更多解释,见http://baike.baidu.com/view/6572152.htm)。一般被用作隔离的虚拟容器使用。
目前vmware的cloud foundry开源的PAAS,单独使用了cgroups + c 语言组件使用了比Lxc更为轻量的方案,有时间会谈一下。Lxc,借助cgroups组件,可以做到精确到CPU、内存、IO性能等,但cgroups无法做到磁盘限额,借助LVM的强大功能,可以做到单个应用磁盘容量的精确控制。
Lxc的另一个替代品,OpenVZ,使用上可能会简单些,起码在磁盘限额方面,比Lxc做的更好一些。
准备
VirtualBox 4.1
所有操作环境,都是基于免费的VritualBox虚拟机基础上。若有兴趣尝试者,也建议安装一个。在进行后面步骤之前,需要熟悉VritualBox的各项操作,都很简单。
官网
Ubuntu 12.04 Server
Ubuntu 12.04服务器版,在虚拟支持方面,比Centos等系统更友好,也更完善。其已经内置对LXC等的支持,十分简单、易用。
LVM
Linux下逻辑磁盘管理工具,可能需要一点点了解。它是一个好东西,Linux系统管理员应该不会陌生,可以对磁盘、分区动态进行容量管理维护,十分强大。
LXC
Linux Container,在一个ubuntu服务器上虚拟若干个互相隔离的子系统,每一个子系统用于托管Java Web应用。
安装
在Virtualbox中安装Ubuntu 12.04,若32位操作系统,只能安装32位Ubuntu服务器,若是64位版本,可以安装64位服务器版本。
网络连接,选择桥接模式即可(我的网络环境为DHCP),利用了现有的网络设施,便于安装一些组件。
安装后,确定openssh服务器已经安装,否则,将很麻烦。记录下IP地址(这里DHCP地址最好)记下IP地址,使用SSH客户端Xshell连接,进行维护操作。
Ubuntu安装时,记得选择LVM管理磁盘;安装好之后,还是可以使用LVM管理磁盘的。
虚拟机安装
挂载新磁盘
这一步不是必须,仅为了建立名称为lxc的卷组。有了卷组,可以方便进行虚拟机的磁盘容量管理,同时也用于单独存放虚拟机的文件系统。
安装好ubuntu 12.04 之后,VritualBox中为当前系统“创建一个新的虚拟硬盘”,假设磁盘名称为NewHardDsik1.vmdk。
很多安装都需要切换到root用户角色下操作,这里优先切换到root管理员下
sudo -i
安装lxc和lvm
apt-get install lxc
备注:若安装Ubuntu时,若没有选择LVM分区管理等,则默认情况下,lvm2软件没有被安装,单独安装lvm2软件包:
apt-get install lvm2
建立lxc卷组
为第二块磁盘创建一个物理卷
pvcreate /dev/sdb
创建一个物理卷组名称为lxc:
vgcreate lxc /dev/sdb
输入vgdisplay查看卷组
root@localhost:~# vgdisplay
--- Volume group ---
VG Name lxc
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 18
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 3
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size 8.00 GiB
PE Size 4.00 MiB
Total PE 2047
Alloc PE / Size 768 / 3.00 GiB
Free PE / Size 1279 / 5.00 GiB
VG UUID SCoO4G-NImr-15WF-CMha-1QAV-7nm3-gnHGz2
配置属性
lxc所有通用配置位于/etc/lxc/lxc.conf,基于默认配置基础上创建一个最小配置lxc_min.conf:
#vi /etc/lxc/lxc_min.conf
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
lxc.cgroup.cpuset.cpus = 0
lxc.cgroup.cpu.shares = 1024
lxc.cgroup.memory.limit_in_bytes = 512M
lxc.cgroup.memory.memsw.limit_in_bytes = 768M
创建虚拟机
创建一个虚拟机:
lxc-create -t ubuntu -n s4 –f /etc/lxc/lxc_min.conf -B lvm --lvname s4 --vgname lxc --fstype ext4 --fssize 1000M
-t : 创建的虚拟机模板名称,默认为ubuntu 12.04最小安装版,非常小
-n : 创建的虚拟名称,需要指定,这里设置为s4,默认情况下也是新建虚拟机的机器名,即 hostnmae
-f : 指定配置文件
-B : 虚拟机磁盘的系统,为了控制单个虚拟机的磁盘容量限制,这里使用lvm进行管理。
--lvname :虚拟机使用卷名,默认使用虚拟机名
--vgname :卷组名称,这个一定要有,默认名称为lxc,可以单独指定。若不指定此选项,则要求名称为lxc的卷组已经存在,否则,请指定已经卷组名。
--fstype :文件系统类型,默认为ext4类型
--fssize :磁盘容量,默认为1G,单个应用所占有磁盘空间,一般安装之后,除了系统文件等,也就剩下500M作用可以使用。
简化后的命令:
lxc-create -t ubuntu -n s4 –f /etc/lxc/lxc_min.conf -B lvm
指定lvm创建的虚拟机磁盘文件位置为 /dev/lxc/s4
第一次安装,会耗费些时间,需要从网络上下载一些软件包进行安装,若没有网络的话,会很惨。第二次安装之后,一些软件包被缓存了之后,会很快的。
另外指定磁盘格式为lvm,创建时,将十分消耗内存。
此虚拟机为最小安装方式,相当绿色,可能会缺失一下软件包,需要登陆进入之后进行安装。
启动虚拟机
lxc-start -n s4 -d
注意一定要加 -d 参数,标记为后台运行,否则,将不太利于管理了。
登录管理
lxc-console -n s4
lxc-console到了SSH的效果,默认的用户名和密码都是ubuntu,输入之后,正常管理。
退出管理
ctrl + a ,然后敲入字母q,即可退出当前系统s4。
SSH连接
登陆进入之后,通过ifconfig命令获得IP地址,使用SSH可连接。
ssh ubuntu@10.0.3.138
hostname解析
建立一个虚拟机之后,登陆进去之后才能够获得IP,下次重启,动态IP可能会变化,对维护操作带来不便。在创建虚拟时,我们已经指定了虚拟机名称,同时也是虚拟hostname的名称,通过虚拟机hostname建立SSH连接最是方便了。
一般采用:
vi /etc/resolv.conf
nameserver 10.0.3.1
nameserver 8.8.8.8
一定要注意顺序,nameserver 10.0.3.1用以解析虚拟机,下面一条随便填写,只要能够使用即可。这里使用免费的8.8.8.8替代。
nslookup s4 & ping s4
测试是否解析正常。
但是一旦系统重启,上述配置会消失,补救:
#vi /etc/resolvconf/resolv.conf.d/tail
nameserver 10.0.3.1
nameserver 8.8.8.8
保存,使之生效:
#/etc/init.d/resolvconf restart
这样下次重启宿主机,可以不用担心DNS失效。
以下方法,可以不用去做:
可不用修改LXC虚拟机s4的 /etc/dhcp/dhclient.conf 配置文件
send host-name "s4";
当然,修改后,需要生效之:
/etc/init.d/networking restart
SSH正常连接
ssh ubuntu@s4
在宿主机下基于SSH使用scp命令执行文件传输等,或执行管理维护命令:
#scp jdk-6u33-linux-i586.bin ubuntu@s4:/home/ubuntu
#scp apache-tomcat-7.0.27.tar.gz ubuntu@s4:/home/ubuntu
在S4中安装JDK之后,设置环境变量:
ubuntu@s4:~$sudo vi /etc/environment
JAVA_HOME=/usr/java/jdk1.6
CLASSPATH=/usr/java/jdk1.6/lib
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:
$JAVA_HOME/bin:$CLASSPATH"
export PATH
保存退出,然后执行:
ubuntu@s4:~$sudo update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.6/bin/javac 1071
ubuntu@s4:~$sudo update-alternatives --install /usr/bin/java java /usr/java/jdk1.6/bin/java 1071
同时设置tomcat解析到s4的/home/ubuntu目录下,mv改名为tomcat,注意设置.sh脚本的启动权限。
安装好JDK,设置tomcat开机自动运行的脚本/etc/init.d/tomcat (后面没有.sh后缀,参考原文,需翻*墙)
#sudo vi /etc/init.d/tomcat
完整内容:
#!/bin/sh
#tomcat auto-start
#export JAVA_HOME=/usr/lib/jvm/java-1.6.0-sun // 已设置JAVA_HOME了,此句可省略。
case $1 in
start)
sh /home/ubuntu/tomcat/bin/startup.sh
;;
stop)
sh /home/ubuntu/tomcat/bin/shutdown.sh
;;
restart)
sh /home/ubuntu/tomcat/bin/shutdown.sh
sh /home/ubuntu/tomcat/bin/startup.sh
;;
*)
echo 'Usage:tomcat7 start|stop|restart'
;;
esac
exit 0
添加到启动项中:
#sudo chmod +x /etc/init.d/tomcat ; sudo update-rc.d tomcat defaults
关闭,便于后面克隆等操作:
#sudo lxc-stop –n s4
虚拟机克隆
上面虚拟机s4安装好之后,执行快速的克隆操作:
lxc-clone -o s4 -n s5 -s -L 1000M
-s 要克隆的景象快照,虚拟机s5和虚拟机s4保持一致了
-L 虚拟机s5的文件系统大小,默认为2G。这里指定和S4一样的文件系统容量。
虚拟机s4使用lvm管理磁盘,克隆后的s5自然也使用LVM,位置位于 /dev/lxc/s5。
这样,克隆出来的S5就对应一个具体的Tomcat Servlet平台。
克隆的速度比创建的速度就是快,5秒之内搞定。
启动s5
lxc-start –n s5 –d && ssh ubuntu@s5
输入java –version可以看到java已经安装成功,tomcat的目录为 /home/ubuntu/tomcat,执行启动脚本:
/home/ubuntu/tomcat/bin/start.
删除/注销
lxc-destroy -n s7 -f
-f 参数可以强制销毁正在运行中的虚拟s7
虚拟机自动启动
把虚拟s5设置为自动启动:
ln -s /var/lib/lxc/s5/config /etc/lxc/auto/s5.conf
下次宿主机重启,s5会自动启动。其它虚拟机设置于此类同。
按照以上办法,克隆s6,s7更多的虚拟机,执行SSH连接,部署WAR包,重启tomcat等,这一切操作可以在宿主机上创建一个sh脚本执行。
注意事项
lxc暂时还不能直接查看内存,CPU等信息,通过free、top或/proc/meminfo、/proc/cpuinfo 是不准确的,看到的都是宿主机的信息。
要想查看,到/sys/fs/cgroup/*/lxc/虚拟机名称下/查看。
查看虚拟机s5当前内存:
#cat /sys/fs/cgroup/memory/lxc/s5/memory.usage_in_bytes
查看虚拟机s5内存上限
#cat /sys/fs/cgroup/memory/lxc/s5/memory.limit_in_bytes
查看交换分区 + 内存的上限
#cat /sys/fs/cgroup/memory/lxc/s5/memory.memsw.limit_in_bytes
有关cpu,或者cpuset,于此类似。
即时修改虚拟机s5的内存上限:
echo 800M > /sys/fs/cgroup/memory/lxc/s5/memory.limit_in_bytes
其它修改也是如此,很简单。
但若是主动mount /cgroup ,则以上位置会发生变化。
PAAS路由
单台宿主机路由
一台宿主机上存在若干个Tomcat Servlet平台,外部请求如何动态转发到相应的虚拟机对应平台上,本文环境是一台宿主机(想虚拟两台,但笔记本太烂),比较好办。
关掉防火墙
ufw disable
然后重启
安装nginx:
apt-get install nginx
创建目录 /home/test/hosts,一般用户可读写。
修改nginx配置文件,在http大括号体最好一行添加内容:
vi /etc/nginx/nginx.conf
inlcude /home/test/hosts/*.conf;
建立虚拟机s5的Tomcat Servlet平台配置片段:
vi /home/test/hosts/s5.conf
server {
listen 80;
server_name s5.yong.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://s5:8080;
}
}
一个虚拟机一个配置文件,其它虚拟机配置于此类似,都丢在此目录下。nginx启动/重新加载时,自动会读取。
测试时,在本地的hosts文件,添加映射
# 192.168.2.28 为宿主机IP
192.168.2.28 s5.yong.com
使用浏览器即可访问。
一般使用非root用户操作nginx,使用iptables等防火墙工具进行端口映射,这里省略。
另外,要做到nginx不重新加载或重启,可能需要定制nginx路由部分了,比如淘宝采用了nginx + lua实现。
这里有一群淘宝牛人开源的nginx组件集 http://openresty.org/ ,可供参考。
多台宿主机路由
这个路由规则相当复杂,可以设置单独一台DHCP服务器,可以分配10.*.*.*私有IP。这样可以保证一个IP对应一个外网域名。
但,如cloud foudry 采用nginx + lua + ruby进行路由转发交换数据,更为复杂。
听说,Heroku则采用nginx + erlang进行路由处理。
有机会再说说这一部分吧。
结束语
好吧,我承认标题有些大,不过,标题党就是这样,先吸引过来再说。但不是初衷,起一个名字,用以概括全文,但最终发现,还是有些虚了,颇感无奈。
类似于资源分配,安全策略,流量计费等,提供SQL,NOSQL,队列服务等高级Topic,太广泛,省略之。
所有操作都是基于终端命令,若是外层可以使用JSP等脚本简单包装一下,那就成了PAAS Tomcat Servlet环境托管管理系统了。
用惯了Tomcat,理论上Jetty或者JAVA EE完整版容器也是可以的。
有关LXC更多、更深入用法,请见参考资料。
参考资料
- https://help.ubuntu.com/12.04/serverguide/lxc.html
- Virtualization in the EC2 cloud using LXC