一、首先,几个概念
1、AMI
An Amazon Machine Image (AMI) is an encrypted machine image that contains all information necessary to boot instances of your software.
use public AMIs as a base to create your own custom private AMIs.
可以理解为系统的一个模板。你可以基于这个模板启动多个系统实例,或者修改这个模板,做为自己的模板。
AMI有官方的和第三方的,现在官方的linux支持ubuntu和fedora。系统有64位和32位的。
下面有一部分是专门说明AMI的选择的。
也可以从下面的地址中查找自己需要的AMI,这里提供的一般是第三方的AMI。
2、Instances
After an AMI is launched, the resulting running system is called an instance。
AMI启动以后就叫做Instance了。
默认每个账号最多可以启动20个instance。可以从下面的地址申请增加:
3、Instance Store
The instance store refers to the disk storage associated with an instance. In the event an instance fails or is terminated, all content on
the instance store is deleted.
Instance基本硬件配置是是:Xen VM,2G CPU,1.7G RAM,文件系统Ext3: 10G /(镜像持久), 140G /mnt(每次重启被清空)
Instance不负责持续存储,Instance失败和停止后,所有存储在Instace内的内容都会消失。
如果需要持续的存储,就需要使用EBS,详细说明在下面。
4、EBS
Amazon Elastic Block Store (Amazon EBS)
Amazon Elastic Block Store (Amazon EBS) is a new type of storage designed specifically for Amazon EC2 instances. Amazon EBS allows you to
create volumes that can be mounted as devices by Amazon EC2 instances. Amazon EBS volumes behave like raw unformatted external block devices
为ec2的instance生命周期提供持续的存储,并在后台自动复制,可以提供基于时间点的快照,并存储到S3中。这个快照可以用于一个新的instance。同一时间,一个vol在同一时间只能挂载在一个Instance上。
注意:在建立volume时,要选择和Instance相同的 Availability Zone内,否则不能挂载。
每个账号默认限制可以建立20个volume,可以提交申请增加:
建议使用LVM,这样下次方便磁盘扩展
How many volumes can I attach to an instance?Each account will be limited to 20 EBS volumes. If you require more than 20 EBS volumes, you can make a request using Amazon's EBS request form. Although you can attach up to 20 volumes on a single instance, we recommend attaching no more than 10 volumes, where each volume can range in size (1GB - 1TB). With EBS, you no longer have to use large or x-large instances if you require more than the 160GB that are available on a small instance.
5、关于EC2_PRIVATE_KEY和EC2_CERT
在Home > Your Account > Access Identifiers > X.509 Certificate 中点击创建一个新的key时会出现下面的界面,允许你下载你的cert和pk。如果这个key不是你创建的,我现在不知道什么地方可以下载private key,还是重新创建一个吧~~~
6、关于Elastic IP
每个账户限制有5个EIP,可以申请多于5个的IP:
上面的文章中有详细的说明,具体的申请页面
7、有关rightscale的AMI
rightscale 是我认为比较好的第三方AMI提供者。提供cetos的AMI。
AMI的版本:
关于AMI的选择:
对yurightscale的AMI的命名规则,如下图的V1_10,v4_0_1,是centos5的1版本和4版本,我当时不清楚,选择的是一版本,后来用了一段时间发现rightscale的验证失败。同时发现v4版本使用的KID是9b00e5f2,而这个AKI是amazon提供的2.6.18的内核。
所以,在选择rightscale的AMI时,在确定了平台和系统版本后,选择AMI版本较高的AMI。
我是在这个AMI上构建自己的AMI的: ami-08f41161
rightscale_images/CentOS5V1_10.img.manifest.xml。有兴趣的话可以试试。
后记:ami-08f41161使用的是2.6.16的内核,ami-0913f760使用的是2.6.18的内核。关于如何查看某个public 的AMI是使用的哪个内核,
可以在console里选择显示AKI,其中AKI-9b00e5f2是2.6.18的32位版内核。AKI-9b00e5f1是64位。
关于rightscale的AMI ami-08f41161 :该AMI会启动一个rightscale的服务,每次instance启动时会做一些操作,详细见/var/log/install。
因为发现有时该服务会失败,造成/etc/rc.d/rc.local里的启动项不能正常运行,所以我把rightscale服务去掉了。
为什么启动失败?
日志中记录的是验证失败之类的错误,因为我使用的是rightscale的v1版本,后来使用了V4版本就不会有这样的问题,所以我猜测可能是旧版本的不再提供一些相关的服务了,所以验证失败,毕竟是免费的,如果是付费的可能就不会出现这样的问题了,管他呢,取消该服务吧。
另外,如果取消该服务,记得删掉/etc/motd文件。
你也可以把正在使用的一个linux系统做成镜像,然后上传到S3上做为自己的AMI。方法在后面介绍。
二、使用一个第三方的AMI需要做的一些操作。
1、Disable Password-Based Logins for Root
to disable password-based logins for root,Open the /etc/ssh/sshd_config file with a text editor and locate the following line:
#PermitRootLogin yes
Change the line to:
PermitRootLogin without-password
To randomize the root password, add the following to your boot process:
if [ -f "/root/firstrun" ] ; then
dd if=/dev/urandom count=50|md5sum|passwd --stdin root
rm -f /root/firstrun
else
echo "* Firstrun *" && touch /root/firstrun
fi
2、检查是否有异常的服务
3、检查是否有异常的系统用户
4、检查是否有异常的crontab
三、定制自己的AMI
1、以amazon上的AMI为基础创建:
(1)选择一个AMI,启动一个Instance
(2)安装jdk1.5
(3)安装ruby
yum install ruby
(4)安装ami-tools
下载:http://developer.amazonwebservices.com/connect/entry.jspa?externalID=368
安装:rpm -i ec2-ami-tools-x.x-xxxx.i386.rpm
(5)上传private key和cert
(6)打包现在的系统
ec2-bundle-vol -k /opt/ec2/pk-6FW5MJGDE7EHO9WFDZVOTDNHBMM5MRPA.pem -c /opt/ec2/cert-6FW5MJGDE7EHO9WFDZVOTDNHBMM5MRPA.pem -u 911139294232 --debug
说明:-u是你的账号去掉“-”
执行到一半时会umount /mnt/img-mnt,确保没有程序在使用该目录。常见的,查看是否有终端登在该目录中。
打包好的文件存储在/tmp中
(7)上传打包好的系统到S3上
cd /tmp
命令:ec2-upload-bundle -b
-m image.manifest.xml -a -s 如:ec2-upload-bundle -b wamo-uranus -m image.manifest.xml -a 1DQ7TN5665Z7TVDNN687 -s jUop8Yv8Ze6J0xi9qNrI+UbIbPKYrZQFt0pn6Va
说明:
bucket:在S3上的一个存储目录。这个bucket name需要保证全局唯一性。
(8)注册这个AMI
To launch the AMI, you must register it. For more information, see ec2-register
如:ec2-register wamo-uranus/image.manifest.xml
2、从vmware创建一个AMI
http://blog.chinaunix.net/u/32831/showart_1839873.html
另外,kernel需要是xen的内核:The current hardware does NOT support hardware virtualization, so you need to build for Xen。In general, building for Xen, even on virtualizing hardware, can improve performance.
更多,可以查看我的另一篇文章:
注:从本地上传做好的image到s3上时只需要上传 image.part.00 到 image.part.98和image.manifest.xml文件即可,大概1G左右,最大的那个3G左右的image文件不需要上传。
注:我按照上面的方法做了一个AMI,启动时出现了错误
FATAL: Could not load /lib/modules/2.6.16-xenU/modules.dep: No such file or directory 。
原因,查看下面的文章:
四、开始使用Instance
1、使用secucrt连接到instance
使用putty的话可以查看官方文档,我习惯使用secucrt,但是官方没有提供将amazon的key转换成secucrt的文档。下面的内容摘自论坛:
原理:使用openssh ssh-keygen将.pem转换为openssh格式的key。
(1)、上传gsg-keypair.pem到一台linux服务器上
(2)、cat gsg-keypair.pem>amazonec2key
(3)、chmod 600 amazonec2key
(4)、ssh-keygen -p -f amazonec2key
(5)、ssh-keygen -e -f amazonec2key >> amazonec2key.pub
(6)、使用amazonec2key.pub做为secuCRT的key文件。
2、使用ec2-api
(1)设置环境变量
export JAVA_HOME=/usr/java/jdk1.5.0_15
export EC2_HOME=/opt/ec2/ec2-api-tools-1.3-30349
export EC2_PRIVATE_KEY=/opt/ec2/pk-6FW5MJGDE7EHO6WFDZVOTDNHBMM5MRPA.pem
export EC2_CERT=/opt/ec2/cert-6FW5MJGDE7EHO6WFDZVOTDNHBMM5MRPA.pem
PATH=$PATH:$EC2_HOME/bin:$JAVA_HOME/bin
(2)使用,ec2-api提供对aws的操作,如启动实例,挂载EBS存储,等等,等等~~~好多
PROMPT> ec2-describe-regions
REGION us-east-1 us-east-1.ec2.amazonaws.com
REGION eu-west-1 eu-west-1.ec2.amazonaws.com
(3)关于下面的报错
一般是由于jdk的版本造成的,建议使用jdk1.5.
另外,还有可能是CLASSPATH里包含了某些jar包造成的,建议先取消环境变量CLASSPATH试一下:unset CLASSPATH
org.codehaus.xfire.fault.XFireFault: Signature creation failed; nested exception is:
java.lang.NullPointerException
at org.codehaus.xfire.fault.XFireFault.createFault(XFireFault.java:89)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:83)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
at org.codehaus.xfire.client.Client.invoke(Client.java:336)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy12.describeAddresses(Unknown Source)
at com.amazon.aes.webservices.client.Jec2.describeAddresses(Jec2.java:1645)
at com.amazon.aes.webservices.client.Jec2.describeAddresses(Jec2.java:1616)
at com.amazon.aes.webservices.client.cmd.DescribeAddresses.invokeOnline(DescribeAddresses.java:42)
at com.amazon.aes.webservices.client.cmd.BaseCmd.invoke(BaseCmd.java:637)
at com.amazon.aes.webservices.client.cmd.DescribeAddresses.main(DescribeAddresses.java:51)
Caused by: org.apache.ws.security.WSSecurityException: Signature creation failed; nested exception is:
java.lang.NullPointerException
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:666)
at com.amazon.aes.webservices.client.Jec2.signRequest(Jec2.java:258)
at com.amazon.aes.webservices.client.Jec2.access$000(Jec2.java:70)
at com.amazon.aes.webservices.client.Jec2$1.invoke(Jec2.java:152)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
... 10 more
Caused by: java.lang.NullPointerException
at org.apache.crimson.tree.ElementNode2.getAttributeNodeNS(ElementNode2.java:432)
at org.apache.crimson.tree.ElementNode2.hasAttributeNS(ElementNode2.java:388)
at org.apache.ws.security.util.WSSecurityUtil.findElementById(WSSecurityUtil.java:269)
at org.apache.ws.security.util.WSSecurityUtil.getElementByWsuId(WSSecurityUtil.java:438)
at org.apache.ws.security.message.EnvelopeIdResolver.engineResolve(EnvelopeIdResolver.java:117)
at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Unknown Source)
at org.apache.xml.security.signature.Reference.dereferenceURIandPerformTransforms(Unknown Source)
at org.apache.xml.security.signature.Reference.calculateDigest(Unknown Source)
at org.apache.xml.security.signature.Reference.generateDigestValue(Unknown Source)
at org.apache.xml.security.signature.Manifest.generateDigestValues(Unknown Source)
at org.apache.xml.security.signature.XMLSignature.sign(Unknown Source)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:659)
... 15 more
关于启动了的Instance的相关信息,可以通过下面的工具查看
wget
chmod u+x ec2-metadata
./ec2-metadata
或者查看EC2 Developer Guide > Using Amazon EC2 >Launching and Using Instances >
3、关于挂载EBS存储
(1)创建一个存储,大小的单位是G,可以使用--snapshot充一个快照进行创建。
ec2-create-volume --size 1 --availability-zone us-east-1c
(2)挂载一个vol到一个Instance
ec2-attach-volume VOLUME -i INSTANCE -d DEVICE
如:ec2-attach-volume vol-0553b76c -i i-9743d7fe -d /dev/sdh
注意,不要挂载到/dev/sd3上去,/dev/sd3是swap分区。
登陆到linux上
mount /dev/sdh /mnt/data-store
(3)卸载存储
首先,从linux卸掉挂载 umount /mnt/data-store
卸载存储:
ec2detvol [GENERAL OPTIONS] VOLUME [-i INSTANCE [-d DEVICE]] [-f|--force]
ec2-detach-volume vol-0553b76c -i i-fd33a694 -d /dev/sdh
4、关于操作S3上的bucket
常用于删除修改后删除以前的AMI
需要使用工具:s3cmd工具,第三方的。
下载地址:
安装:(1)先安装windows的python
(2)右击“我的电脑”->“属性”->“高级”->“环境变量”,选择“PATH”,点“编辑”,把;C:\Python26加入“变量值”中(注意分号分割)。确定
(3)运行python setup.py install
(4)运行python c:\python26\scripts\s3cmd --configure
设定 access_key和secret_key
(5)关于删除bucket,s3cmd 0.9.9 以前的版本不支持删除非空bucket,建议使用s3cmd 0.9.9 版本。
Many people wanted an easy way to delete a subtrees from S3 or to remove non-empty buckets. Both is now possible – del understands
—recursive and rb honours —force (which in fact will do a recursive delete first internally):
~$ python c:\python26\scripts\s3cmd rb --force s3://bkt-test
WARNING: Bucket is not empty. Removing all the objects from it
first. This may take some time...
File s3://bkt-test/testfile.txt deleted
Bucket 's3://bkt-test/' removed
(6)其余操作:
Make bucket
s3cmd mb s3://BUCKET
Remove bucket
s3cmd rb s3://BUCKET
List objects or buckets
s3cmd ls [s3://BUCKET[/PREFIX]]
List all object in all buckets
s3cmd la
Put file into bucket
s3cmd put FILE [FILE...] s3://BUCKET[/PREFIX]
Get file from bucket
s3cmd get s3://BUCKET/OBJECT LOCAL_FILE
Delete file from bucket
s3cmd del s3://BUCKET/OBJECT
Synchronize a directory tree to S3
s3cmd sync LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DI
Disk usage by buckets
s3cmd du [s3://BUCKET[/PREFIX]]
Get various information about Buckets or Objects
s3cmd info s3://BUCKET[/OBJECT]
Copy object
s3cmd cp s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]
Move object
s3cmd mv s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]
Modify Access control list for Bucket or Object
s3cmd setacl s3://BUCKET[/OBJECT]
List CloudFront distribution points
s3cmd cflist
Display CloudFront distribution point parameters
s3cmd cfinfo [cf://DIST_ID]
Create CloudFront distribution point
s3cmd cfcreate s3://BUCKET
Delete CloudFront distribution point
s3cmd cfdelete cf://DIST_ID
Change CloudFront distribution point parameters
s3cmd cfmodify cf://DIST_ID
五、其他
1、关于使用rightscale的ami时,远程连接到其他instance时的提示:
Address 174.129.230.151 maps to ec2-174-129-230-151.compute-1.amazonaws.com, but this does not map back to the address - POSSIBLE BREAK-IN
ATTEMPT!
思路:
ssh -v root@174.129.230.151
解决:
vi /etc/ssh/ssh_config
GSSAPIAuthentication no
2、一个小脚本,启动时自动绑定ELASTIC IP
wget
#!/bin/sh #set environment unset CLASSPATH export JAVA_HOME=/usr/java/jdk1.5.0_15 export EC2_HOME=/opt/ec2/ec2-api-tools-1.3-30349 export EC2_PRIVATE_KEY=/opt/ec2/pk-6FW5MJGDE7EHO6WFDZVOTDNHBMM9MRPA.pem export EC2_CERT=/opt/ec2/cert-6FW5MJGDE7EHO6WFDZVOTDNHBMM9MRPA.pem PATH=$PATH:$EC2_HOME/bin:$JAVA_HOME/bin
#get metadata my_instance_id=`/opt/ec2-metadata |awk '/instance-id/ {print $2}'`
#about ELASTIC IP ip=174.12.23.152 ip152_status=$(ec2-describe-addresses $ip|awk '{print $3}')
#main if [ "$ip152_status" = "" ];then ec2-associate-address $ip -i $my_instance_id echo "`date +%y/%m/%d-%T`: associate-address $ip to \"this INSTANC\" " else ip152_associate=`ec2-describe-instances |grep "$ip"|awk '{print $2}'` if [ "$ip152_associate" = "$my_instance_id" ];then echo "`date +%y/%m/%d-%T`: IP $ip has associated to \"this INSTANCE\"". else echo "`date +%y/%m/%d-%T`: IP $ip has associated to INSTANCE: $ip152_associate,not this INSTANCE " fi fi |
3、show下我的使用记录
4.我使用下面的脚本在启动时获取另一台服务器的内部ip,并修改一些配置文件
注意,这个脚本有点问题,什么问题?往下看。。。
#!/bin/sh
#for ip
uranusip=`ssh root@174.129.230.151 ifconfig |grep inet|grep -v "127.0.0.1"|awk '{print $2}'|awk -F: '{print $2}'`
echo $uranusip
localip=`/opt/ec2-metadata -o|awk '{print $2}'`
#set log
sed -i /loghost_ip_here/s/loghost_ip_here/$uranusip/g /etc/syslog-ng/syslog-ng.conf
service syslog-ng restart
#modify config-sample.xml file on uranus
exist=`ssh root@174.12.23.151 sed -n \'/$localip/p\' /home/config-sample.xml`
if [ "$exist" = "" ];then
ssh root@174.129.230.151 sed -i \'/Smtphost-here/a\\' /home/config-sample.xml
echo "`date +%y/%m/%d-%T`:write my interip to uranus /home/config-sample.xml"
fi
#allow uranus ip concent local port 25
echo $uranusip:allow,RELAYCLIENT=\"\">>/etc/tcp.smtp
#start memcached
/usr/local/memcached/bin/memcached -d -m 10 -p 11211 -u root
#start qmail
#service qmail start
但是这个脚本手动运行是正常的,重启后却不能取到对方内网ip。
添加debug
`ssh -v root@174.129.230.151 ifconfig |grep inet|grep -v "127.0.0.1"|awk '{print $2}'|awk -F: '{print $2}'`
查看该Instance的output
注:output会滞后,重启两次才显示上次的~~
加个key上去就OK了,
ssh -i /root/.ssh/wmokey.pem root@222.222.222.222 ifconfig |grep inet|grep -v "127.0.0.1"|awk '{print $2}'|awk -F: '{print $2}'
注意,要修改权限为600~~
#!/bin/sh #for ip server_public_ip=222.222.222.222 server_inner_ip=`ssh -i /root/.ssh/wanmokey.pem root@$server_public_ip ip addr sh eth0|awk '/inet/ {print $2}'|awk -F / '{print $1}'` echo "uransip is $uranus_inner_ip!!"
localip=`/opt/ec2-metadata -o|awk '{print $2}'`
#set log #sed -i /loghost_ip_here/s/loghost_ip_here/$uranus_inner_ip/g /etc/syslog-ng/syslog-ng.conf #service syslog-ng restart
#modify config-sample.xml file on uranus exist=`ssh -i /root/.ssh/wanmokey.pem root@$server_public_ip sed -n \'/$localip/p\' /EBS/config-sample.xml`
if [ "$exist" = "" ];then ssh -i /root/.ssh/wanmokey.pem root@$server_public_ip sed -i \'/Smtphost-here/a\\' /EBS/config-sample.xml echo "`date +%y/%m/%d-%T`:write my interip to uranus /EBS/config-sample.xml" fi
#allow uranus ip concent local port 25 echo $uranus_inner_ip:allow,RELAYCLIENT=\"\">>/etc/tcp.smtp
#start memcached /usr/local/memcached/bin/memcached -d -m 10 -p 11211 -u root |
6 关于启动时选择key,这个key会被加入到/root/.ssh/authorized_keys 文件中,这样就可以登陆了,想多个账户登陆?还不容易?