前言
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