跳转到主要内容

为EC2实例提供高效且可重复的软件部署

项目描述

先决条件

要安装和 使用CGCloud,您需要

安装

在粘贴任何命令之前,请阅读整个部分,并确保已安装所有先决条件。建议将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 -Kssh-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 命令默认遵循该约定。

然而,对于 -kCGCLOUD_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-userrootubuntu。不同 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 -Kssh-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

另请参阅https://github.com/fabric/fabric/issues/1212

自定义

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()函数,因为该函数不会为脚本插件调用。换句话说,脚本插件应仅定义角色,而不是命令。

项目详情


发布历史 发布通知 | RSS源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

cgcloud-core-1.6.0.tar.gz (67.8 kB 查看哈希值)

上传时间 源代码

构建分发

cgcloud_core-1.6.0-py2.7.egg (168.1 kB 查看哈希值)

上传时间 源代码

支持