为EC2实例提供高效且可重复的软件部署
项目描述
先决条件
要安装和 使用CGCloud,您需要
Python ≧ 2.7.x
Mac OS X: Xcode 和 Xcode 命令行工具(在安装cgcloud-core编译PyCrypto依赖项时需要)
安装
在粘贴任何命令之前,请阅读整个部分,并确保已安装所有先决条件。建议将CGCloud安装到virtualenv中。创建一个virtualenv并使用 pip 安装 cgcloud-core 包
virtualenv ~/cgcloud source ~/cgcloud/bin/activate pip install cgcloud-core
如果您遇到 DistributionNotFound: No distributions matching the version for cgcloud-core 错误,请尝试运行 pip install --pre cgcloud-core。
如果您收到关于 yaml.h 缺失的错误,您可能需要安装libyaml(通过OS X上的HomeBrew)或libyaml-dev(通过Linux上的apt-get或yum)。
如果您收到
AttributeError: 'tuple' object has no attribute 'is_prerelease'
您可能需要升级setuptools
sudo pip install --upgrade setuptools
如果您收到
ImportError: cannot import name cgcloud_version
您可能需要升级virtualenv
sudo pip install --upgrade virtualenv
如果在Mountain Lion上遇到
clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future] clang: note: this will be a hard error (cannot be downgraded to a warning) in the future error: command 'clang' failed with exit status 1
尝试以下解决方案
export CFLAGS=-Qunused-arguments export CPPFLAGS=-Qunused-arguments
安装程序将 cgcloud 可执行文件放置在virtualenv的 bin 目录中。在您可以调用 cgcloud 之前,您必须像上面那样激活virtualenv。或者,创建一个针对用户的 bin 目录并将 cgcloud 可执行文件链接到其中
deactivate mkdir -p ~/bin ln -snf ~/cgcloud/bin/cgcloud ~/bin
在将 export PATH="$HOME/bin:$PATH" 添加到您的 ~/.profile、~/.bash_profile 或 ~/.bashrc 之后,您在运行cgcloud之前不需要显式激活virtualenv。
现在您应该可以调用 cgcloud 了
cgcloud --help
Bash 自动补全
安装强大的 argcomplete 模块
pip install argcomplete
然后,将以下命令添加到您的 ~/.profile
eval "$(/absolute/path/to/virtualenv/bin/register-python-argcomplete cgcloud)"
配置
访问密钥
请向您的 AWS 管理员请求在 AWS 中为您设置一个 IAM 账户。登录到 Amazon 的 IAM 控制台,为您自己生成一个 访问密钥。虽然您的 IAM 用户名和密码用于通过 AWS 控制台进行交互式认证,但访问密钥用于通过 cgcloud 进行程序性访问。
一旦您有了访问密钥,请在本地的计算机上创建 ~/.boto 文件,并包含以下内容
[Credentials] aws_access_key_id = PASTE_YOUR_ACCESS_KEY_ID_HERE aws_secret_access_key = PASTE_YOUR_SECRET_ACCESS_KEY_HERE
~/.boto 文件已被弃用。请考虑使用 ~/.aws/credentials,因为它被各种 AWS SDK 支持,并允许轻松地在不同的 AWS 账户(配置文件)之间切换。
[foo] aws_access_key_id=PASTE_YOUR_FOO_ACCESS_KEY_ID_HERE aws_secret_access_key=PASTE_YOUR_FOO_SECRET_KEY_ID_HERE region=us-west-2 [bar] aws_access_key_id=PASTE_YOUR_BAR_ACCESS_KEY_ID_HERE aws_secret_access_key=PASTE_YOUR_BAR_SECRET_KEY_ID_HERE region=us-west-2
要选择活动配置文件,请设置 AWS_PROFILE 环境变量
export AWS_PROFILE=foo
EC2 区域和可用区
编辑您的 ~/.profile 或 ~/.bash_profile 并添加以下行
export CGCLOUD_ZONE=us-west-2a
此配置同时设置了区域 us-west-2 和该区域内的可用区 a。您可以使用 us-east-1a 或任何其他区域中的任何其他区域,而不是 us-west-2a。
公钥 SSH
如果您没有 SSH 密钥,可以使用 ssh-keygen 命令创建一个。不要使用 EC2 控制台生成密钥。这将是不安全的,并产生一个与 CGCloud 不兼容的密钥。
通过运行以下命令在 EC2 中注册您的 SSH 密钥
cgcloud register-key ~/.ssh/id_rsa.pub
上述命令将给定的公钥导入到 EC2 中作为密钥对(我知道,术语可能令人困惑),同时也将其上传到 S3,下一段将进行解释。EC2 中的密钥对名称将设置为您的 IAM 用户账户名称。在 S3 中,公钥将存储在其指纹下。
如果 cgcloud 抱怨 Private key file is encrypted,则您的私钥可能被密码短语加密了(应该这样)。您需要通过 ssh-add 将密钥添加到 SSH 代理,这应该会提示您输入密码短语。在 Mac OS X 上,这可以通过运行 ssh-add -K 或 ssh-add -K /path/to/private/key 一次来使操作更加方便。这将自动在每次登录时将密钥添加到代理。密码短语将存储在 OS X 的密钥链中,因此无需再次输入。
注意:使用EC2控制台导入密钥对与使用 cgcloud register-key 不等价。为了能够管理团队中的密钥对,CGCloud需要知道每个团队成员密钥对的公钥内容。但EC2仅通过其REST API公开指纹,而不是实际的公钥。为此,CGCloud将这些公钥保存在一个特殊的S3存储桶中。使用 cgcloud register-key 确保公钥被导入到EC2 并且 上传到该特殊S3存储桶。还请注意,虽然该S3存储桶是全局可见的,并且存储其中的公钥适用于各个区域,但EC2中的相应密钥对仅在区域内可见。因此,当您切换到不同的区域时,您将需要再次使用 cgcloud register-key 将密钥对导入到该EC2区域。
多用户SSH登录
默认情况下,CGCloud仅将其公钥注入它创建的盒子中。这意味着只有您才能SSH到这些盒子。如果您想其他人也能SSH到您创建的盒子,您可以指定要注入盒子的密钥对列表。您可以通过使用 -k 命令行选项来执行 cgcloud create 或通过设置 CGCLOUD_KEYPAIRS 环境变量来实现。后者将默认将这些密钥对注入您创建的每个盒子中。 -k 的默认值是特殊的字符串 __me__,它被替换为当前IAM用户的名字,即您。这仅适用于您的IAM用户账户和您的EC2 SSH密钥对具有相同的名字,这是一种非常推荐的做法。《span class="docutils literal">cgcloud register-key 命令默认遵循该约定。
然而,对于 -k 和 CGCLOUD_KEYPAIRS 最有用的快捷方式是使用前缀 @@ 列出IAM组的名称。假设存在一个名为 developers 的IAM组,将以下行添加到您的 .profile 或 .bash_profile
export CGCLOUD_KEYPAIRS="__me__ @@developers"
将您的密钥对以及 developers IAM组中每个用户的密钥对注入从那时起您创建的每个盒子中。显然,这仅在EC2密钥对和IAM用户名相同的情况下才有效,但如上所述,如果您使用了 cgcloud register-key,则应该如此。
在上面的例子中,如果用户从 developers IAM组中删除,或者他们的密钥对从EC2中删除,那么他们的密钥对将自动从使用该值创建的每个盒子中删除。
请注意,更改 CGCLOUD_KEYPAIRS 不会影响使用 cgcloud recreate ROLE 创建的盒子。您需要使用 cgcloud create -IT ROLE 创建新的镜像,以便更改生效。
第一步
现在,您已经准备好创建第一个 盒子 即EC2实例或虚拟机
cgcloud create generic-ubuntu-trusty-box
这将从标准的Ubuntu AMI创建一个Ubuntu Trusty实例,并通过SSH运行额外的命令进一步自定义它。这需要几分钟时间。《span class="docutils literal">generic-ubuntu-trusty-box 参数表示一个 角色,即实例的蓝图。您可以使用 cgcloud list-roles 查看可用的角色。
现在登录到新创建的盒子
cgcloud ssh generic-ubuntu-trusty-box
聪明的读者会注意到,没有必要记住分配给盒子的公网主机名。只要每个角色只有一个盒子,您就可以使用角色的名称来引用该盒子。否则,您需要使用 -o 选项指定序号来消除歧义。使用 cgcloud list 查看所有运行实例及其序号。
此外,没有必要指定登录时要使用的管理用户账户名,例如 ec2-user,root 或 ubuntu。不同 Linux 发行版的库存镜像使用不同的账户名,但 CGCloud 便利地隐藏了这些差异。
要复制文件到或从盒子中,您可以使用 cgcloud rsync
cgcloud rsync generic-ubuntu-trusty-box -av ~/mystuff :
cgcloud rsync 命令的行为类似于 rsync 命令的前缀,但有一个重要区别:使用 rsync 时,您需要指定远程主机名后跟一个冒号,而使用 cgcloud rsync 时,您只需将主机名留空,并指定一个冒号后跟远程路径。如果您省略远程路径,将使用管理用户的家目录。
现在您可以使用 cgcloud stop 停止盒子,使用 cgcloud start 重新启动它,或使用 cgcloud terminate 终止它。请注意,停止的实例的成本远低于运行的实例,但这不是免费的。只有 terminate 命令才会将实例产生的运营成本降至零。
如果您想保留对盒子所做的修改,以便将来可以创建另一个与它完全相同的盒子,请停止盒子,然后使用 cgcloud image 命令创建其镜像。然后您可以使用 cgcloud recreate 命令启动盒子。
哲学评论
虽然创建镜像是一种保存盒子手动修改的有效机制,但这不是最好的方法。问题在于您将卡在创建盒子时使用的基镜像版本。您也将卡在您使用的特定 cgcloud 版本执行的定制中。如果基镜像或 CGCloud 中的角色定义更新,您将无法从这些更新中受益。因此,自定义盒子的首选方法是 脚本 定制。这通常通过创建 CGCloud 插件来完成,即一个带有 VM 定义(称为 roles)的 Python 包。角色是 Box 类的子类,而盒子(即 VM 或 EC2 实例)是该类的实例。Box 及其派生类形成的突出设计模式是 模板方法 和 混入。混入模式引入了对 Python 的方法解析顺序的敏感性,因此您需要意识到这一点。
即使您在 cgcloud create 后没有进行任何修改,创建镜像也是有意义的。它捕获了 cgcloud create 执行的所有特定于角色的定制,从而保护它们免受角色定义、底层基镜像和 Linux 发行版中包更新的更改。这是 CGCloud 哲学的一个关键点:它为您提供了根据要求创建一个包含所有最新软件的 创建 的最新镜像的方法,并且它允许您可靠地重现该步骤的确切结果。实际上,recreate 比创建 create 快得多,这是锦上添花的。
构建 & 测试
首先,克隆此仓库并cd进入。要运行测试,请使用
python setup.py nosetests --with-doctest,
python setup.py test,
nosetest或
python -m unittest discover -s src.
我们更推荐第一种方法,因为它会安装所有依赖并使用Nose运行测试,Nose是一个比unittest更好的测试运行器,它可以并行运行测试并生成类似XUnit的报告。例如,在持续集成中,我们使用
virtualenv env env/bin/python setup.py nosetests --processes=16 --process-timeout=900
要创建一个可编辑的安装,也称为开发模式,请使用python setup.py develop。要移除可编辑安装,请使用python setup.py develop -u。
故障排除
如果cgcloud create反复卡住并打印Private key file is encrypted,则您的私钥可能被密码加密(应该如此)。您需要通过ssh-add将密钥添加到SSH代理,这将提示您输入密码。在Mac OS X上,可以通过运行ssh-add -K或ssh-add -K /path/to/private/key一次来使其更方便。这将在每次登录时自动将密钥添加到代理。密码将存储在OS X的密钥链中,因此无需再次输入。
如果您遇到以下错误
ERROR: Exception: Incompatible ssh peer (no acceptable kex algorithm) ERROR: Traceback (most recent call last): ERROR: File "/usr/local/lib/python2.7/site-packages/paramiko/transport.py", line 1585, in run ERROR: self._handler_table[ptype](self, m) ERROR: File "/usr/local/lib/python2.7/site-packages/paramiko/transport.py", line 1664, in _negotiate_keys ERROR: self._parse_kex_init(m) ERROR: File "/usr/local/lib/python2.7/site-packages/paramiko/transport.py", line 1779, in _parse_kex_init ERROR: raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)') ERROR: SSHException: Incompatible ssh peer (no acceptable kex algorithm)
尝试升级paramiko
pip install --upgrade paramiko
自定义
CGCloud可以通过插件进行自定义。插件是一个包含两个函数的Python模块或包
def roles(): """ Return a list of roles, each role being a concrete subclass of cgcloud.core.box.Box """ return [ FooBox ] def command_classes(): """ Return a list of command classes, each class being a concrete subclass of cgcloud.lib.util.Command. """ return [ FooCommand ]
如果插件是一个Python包,这两个函数需要在它的__init__.py中定义。这两个函数返回的box和command类可以在该包的子模块中定义。
为了被CGCloud加载,插件需要可以从sys.path加载,并且其模块路径(foo.bar.blah)需要在CGCLOUD_PLUGINS环境变量中提及,该变量应包含冒号分隔的插件模块路径列表。
您还可以使用--script选项和Python脚本的路径运行CGCloud。该脚本将被处理为插件,但不应定义command_classes()函数,因为该函数不会为脚本插件调用。换句话说,脚本插件应仅定义角色,而不是命令。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源代码分发
构建分发
cgcloud-core-1.6.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | f021841a032e079e8df191e8f15c5fc442f5adbb0f770c2d75021677b39d0fcd |
|
MD5 | 98cb3cd76658fd1da2a845cec19769df |
|
BLAKE2b-256 | 15e8866aac5ab4b563fa6f9a7bad467aa1db2491bebc6e9c7496f6fd67c9f53b |
cgcloud_core-1.6.0-py2.7.egg的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7219345881bfbdf33fcb869fc4add4d9fba5fa12a6a705c7ee2a0ed4eb614a3f |
|
MD5 | 8226d430678db081604f46c87c158ed2 |
|
BLAKE2b-256 | a09dc4e785d57410c0aee853d312eea285df13e4e7d090d9ed39f7fbe200aa1a |