【IT168 技术】Eucalyptus的一个显著的特点是比较完整的实现了Amazon EC2/S3的API,虽然在Scalability/HA和可管理性等方面存在较大差距,作为企业级使用还是可行的。下面就Eucalyptus实现的几个主要功能进行说明,包括:
Instance/Image
Security Group,
Elastic IP,
EBS
S3
软件环境
Mule ESB作为Cloud Controller组件交互的纽带
数据库采用Hsqldb,采用Hibernate封装接口
节点之间采用Axis2 SOAP进行通信,并使用WS-Security提供安全保证
开发语言: clc大部分使用Java语言,ESB部分调用C操作LVM,cc和nc使用C语言。
系统组件
▲
Cloud Controller(CLC) - 负责管理基础设施虚拟化资源,包括服务器,网络,和存储,并提供一个工业标准的API(Amazon EC2)
Walrus - 实现可扩展的“put-get bucket”风格的存储。接口兼容Amazon S3(提供bucket和object的get/put接口),提供虚拟机Image和用户数据的持久存储和访问控制
Cluster Controller(CC) - 控制节点上虚拟机的执行并管理虚拟网络资源,包括虚拟机之间和虚拟机和外部用户之间的虚拟网络。
Storage Controller(SC) - 提供块级(Block-level)的网络存储,并能动态attach到VM上。支持EBS接口。
Node Controller(NC) - NC通过hypervisor控制VM的活动,包括执行,监视,终止VM实例。
功能实现:
实例管理:
cloud controller维护着系统的各种资源,包括Instance, Image, Network, Volume, Object等,cloud controller每隔一定时间会向clluster controller询问资源的使用情况,实例的运行状况和地址的使用情况等信息。
当用户调用RunInstances服务时,系统先进行Image,KeyPair,VmType,Security Group的验证,通过后先后指令CC给VM初始化网络,配置安全组,运行实例与给实例关联Public/Elastic IP.
Image管理: Warlus管理imager.
虚拟化网络:
1. 实现功能:
IP Control: 为实例动态分配私有IP地址
Security Groups: 安全组为一组实例提供一组访问规则,限制用户对指定端口的访问。
Elastic IPs:Elastic IP与用户的帐号相关联,而不是与实例相关联,使得实例失败后新启动的实例可以继续关联同一个IP地址
VM Isolation: 组内的实例之间可以互相访问,不同组实例之间除非授权不能互相访问
2. 使用技术:
IP Control: 为一个将要启动的VM分配一个Mac:IP地址对,然后使用DHCP,让VM在启动时通过DHCP Server获取到分配的IP地址。
Security Groups:使用Iptables 的 filter 功能
Elastic IPs: 运用iptables的NAT功能
VM Isolation: 运用vlan技术实现
EBS实现:
Block管理通过LVM实现,通过AOE和iSCSI两种方式提供网络访问
S3实现
具体流程:
EBS实现:
$ ec2-create-volume -s 1 -z mycluster -v
#dd if=/dev/zero of=/opt/eucalyptus/var/lib/eucalyptus/volumes/vol-32BA04A4 count=1024 bs=1M
# losetup -f
# losetup /dev/loop6 /opt/eucalyptus/var/lib/eucalyptus/volumes/vol-32BA04A4
# pvcreate /dev/loop6
# vgcreate vg-6gg0_w.. /dev/loop6
# lvcreate -n lv-4IY3lw.. -l 100%FREE vg-6gg0_w..
# vblade 0 7 eth0 /dev/vg-6gg0_w../lv-4IY3lw..
$ ec2-delete-volume vol-32BA04A4
# kill -9 721
# lvremove -f /dev/vg-6gg0_w../lv-4IY3lw..
# vgremove vg-6gg0_w..
# pvremove /dev/loop6
# losetup -d /dev/loop6
$ ec2-attach-volume vol-32ED04AF -i i-5C7809B1 -d /dev/sdb
doAttachVolume() invoked (id=i-5C7809B1 vol=vol-32ED04AF remote=/dev/etherd/e0.9 local=/dev/sdb)
attached /dev/etherd/e0.9 to sdb in domain i-5C7809B1
登录到VM,可以看到增加了一个dev:
root@ubuntu:~# ls -al /dev/sd*
brw-rw---- 1 root disk 8, 0 2011-06-14 23:53 /dev/sda
brw-rw---- 1 root disk 8, 1 2011-06-14 23:53 /dev/sda1
brw-rw---- 1 root disk 8, 3 2011-06-14 23:53 /dev/sda3
brw-rw---- 1 root disk 8, 16 2011-06-14 23:59 /dev/sdb
$ ec2-detach-volume vol-32ED04AF
doDetachVolume() invoked (id=i-5C7809B1 vol=vol-32ED04AF remote=/dev/etherd/e0.9 local=sdb force=0)
Running command: /opt/eucalyptus/usr/share/eucalyptus/euca_rootwrap virsh detach-device i-5C7809B1 /tmp/detachxml.xx2tM9
first workaround command failed (1), trying second workaround...
Running command: sudo xm block-detach i-5C7809B1 sdb
detached /dev/etherd/e0.9 as sdb in domain i-5C7809B1
登录到VM,可以看到刚才增加的dev消失了:
root@ubuntu:~# ls -al /dev/sd*
brw-rw---- 1 root disk 8, 0 2011-06-14 23:53 /dev/sda
brw-rw---- 1 root disk 8, 1 2011-06-14 23:53 /dev/sda1
brw-rw---- 1 root disk 8, 3 2011-06-14 23:53 /dev/sda3
$ ec2-create-snapshot vol-32ED04AF
dd if=/dev/zero of=/opt/eucalyptus/var/lib/eucalyptus/volumes/vol-32ED04AF-cOopjC9F count=1024 bs=1M
losetup -f
losetup /dev/loop1 /opt/eucalyptus/var/lib/eucalyptus/volumes/vol-32ED04AF-cOopjC9F
pvcreate /dev/loop1
vgcreate vg-wbRfkw.. /dev/loop1
lvcreate -n lv-9ALq_A.. -l 100%FREE vg-wbRfkw..
dd if=/dev/vg-Ca_8lQ../lv-nXF7eg.. of=/dev/vg-wbRfkw../lv-9ALq_A.. bs=1M
dd if=/dev/zero of=/opt/eucalyptus/var/lib/eucalyptus/volumes/snap-331704B5 count=1024 bs=1M
losetup -f
losetup /dev/loop2 /opt/eucalyptus/var/lib/eucalyptus/volumes/snap-331704B5
pvcreate /dev/loop2
vgextend vg-wbRfkw.. /dev/loop2
lvcreate -n lv-snap-ms8MNg.. -s -l 100%FREE /dev/vg-wbRfkw../lv-9ALq_A..
$ ec2-delete-snapshot snap-331704B5
lvremove -f /dev/vg-wbRfkw../lv-snap-ms8MNg..
vgreduce vg-wbRfkw.. /dev/loop2
pvremove /dev/loop2
losetup -d /dev/loop2
lvremove -f /dev/vg-wbRfkw../lv-9ALq_A..
vgremove vg-wbRfkw..
pvremove /dev/loop1
losetup -d /dev/loop1
网络相关功能实现:
网络相关的配置参数为:
VNET_INTERFACE="eth1"
VNET_MODE="MANAGED"
VNET_SUBNET="192.168.1.0"
VNET_NETMASK="255.255.255.0"
VNET_DNS="192.168.1.1"
VNET_ADDRSPERNET="16"
VNET_PUBLICIPS="1.2.3.1 1.2.3.2 1.2.3.3 1.2.3.4"
网络初始化:
flushing 'filter' table
iptables -t filter -F
flushing 'nat' table
iptables -t nat -F
过滤掉不相关的包:
iptables -t filter -P FORWARD DROP
iptables -t filter -A FORWARD -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -t filter -A FORWARD -d ! 192.168.1.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -d ! 192.168.1.0/24 -j MASQUERADE
169.254.169.254用于提供meta data服务
ip addr add 169.254.169.254 dev eth1
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -d 169.254.169.254 -p tcp --dport 80 -j DNAT --to 169.254.169.254:8773
将整个物理网络划分为若干个subnet:?
vlan 2 network:192.168.1.0 netmask:255.255.255.240 broadcast:192.168.1.15 dns:192.168.1.1 router:192.168.1.1
vlan 3 network:192.168.1.16 netmask:255.255.255.240 broadcast:192.168.1.31 dns:192.168.1.1 router:192.168.1.17
vlan 4 network:192.168.1.32 netmask:255.255.255.240 broadcast:192.168.1.47 dns:192.168.1.1 router:192.168.1.33
vlan 5 network:192.168.1.48 netmask:255.255.255.240 broadcast:192.168.1.63 dns:192.168.1.1 router:192.168.1.49
vlan 6 network:192.168.1.64 netmask:255.255.255.240 broadcast:192.168.1.79 dns:192.168.1.1 router:192.168.1.65
vlan 7 network:192.168.1.80 netmask:255.255.255.240 broadcast:192.168.1.95 dns:192.168.1.1 router:192.168.1.81
vlan 8 network:192.168.1.96 netmask:255.255.255.240 broadcast:192.168.1.111 dns:192.168.1.1 router:192.168.1.97
vlan 9 network:192.168.1.112 netmask:255.255.255.240 broadcast:192.168.1.127 dns:192.168.1.1 router:192.168.1.113
vlan 10 network:192.168.1.128 netmask:255.255.255.240 broadcast:192.168.1.143 dns:192.168.1.1 router:192.168.1.129
vlan 11 network:192.168.1.144 netmask:255.255.255.240 broadcast:192.168.1.159 dns:192.168.1.1 router:192.168.1.145
vlan 12 network:192.168.1.160 netmask:255.255.255.240 broadcast:192.168.1.175 dns:192.168.1.1 router:192.168.1.161
vlan 13 network:192.168.1.176 netmask:255.255.255.240 broadcast:192.168.1.191 dns:192.168.1.1 router:192.168.1.177
vlan 14 network:192.168.1.192 netmask:255.255.255.240 broadcast:192.168.1.207 dns:192.168.1.1 router:192.168.1.193
将来?对每个security group会分配一个vlan,这样保证网络的隔离?
Security Group实现:
Eucalyptus会为每个安全组(security group)创建一个vlan,下面以一个实例进行说明,相应的函数为StartNetwork(netName=app vlan=10):
首先,生成 filter chain: ?
iptables -t filter -N admin-app
?iptables -t filter -D FORWARD -j admin-app
iptables -t filter -A FORWARD -j admin-app
接着,在网络10上生成一个vlan,并生成一个bridge和其上的gateway,这样在eth1.10上的数据包就可以通过这个gateway进行路由:?
// first, create tagged interface
vconfig add eth1 10
?// create new bridge
brctl addbr eucabr10
brctl addif eucabr10 eth1.10
?// bring br up
ip link set dev eucabr10 up
ip addr flush eucabr10
?// bring if up
ip link set dev eth1.10 up
// Add gateway in the bridge?
ip addr add 192.168.1.129/28 broadcast 192.168.1.143 dev eucabr10'
ip link set dev eucabr10 up
在NC上也生成一个vlan和bridge:
vconfig add eth0 10
brctl addbr eucabr10
brctl addif eucabr10 eth0.10
ip link set dev eucabr10 up
ip link set dev eth0.10 up
Private IP地址的分配
在RunInstance时,CC会为每个实例分配一个MAC/IP地址对,并通过dpcp服务让instance在启动时自动获取到自己的IP地址,具体操作如下:
CC从预先配置的表中获取一个空闲的MAC/IP地址对:d0:0d:4C:46:07:DF/192.168.1.130
然后CC调用SOAP指令NC运行实例,并将image-id, MAC地址等作为参数传入
NC将bridge和Mac作为interface参数调用libvirt创建实例:
CC将192.168.1.128网络参数和映射的MAC/IP地址对写入dhcp配置文件euca-dhcp.conf:
shared-network euca {
subnet 192.168.1.128 netmask 255.255.255.240 {
option subnet-mask 255.255.255.240;
option broadcast-address 192.168.1.143;
option domain-name-servers 192.168.1.1;
option routers 192.168.1.129;
}
host node-192.168.1.130 {
hardware ethernet d0:0d:4C:46:07:DF;
fixed-address 192.168.1.130;
}
}
随后重启dhcpd:
/usr/sbin/dhcpd -cf euca-dhcp.conf -lf euca-dhcp.leases -pf euca-dhcp.pid -tf euca-dhcp.trace eucabr10 eth1
Public IP和Elastic IP的实现:
Public IP和Elastic Ip使得外部用户可以通过这个IP访问到VM,它的实现类似于NAT,
例如要把1.2.3.2这个地址作成PublicIP/Elastic IP,需要在Front end的CC的eth1上增加这个地址
ip addr add 1.2.3.2/32 dev eth1
然后应用iptables规则,将外网用户访问1.2.3.2的包,目的地址改为192.168.1.130,将从192.168.1.130发出的包,其源地址改为1.2.3.2
iptables -t nat -A PREROUTING -d 1.2.3.2 -j DNAT --to 192.168.1.130
iptables -t nat -A POSTROUTING -s 192.168.1.130 -j SNAT --to 1.2.3.2