29

通过最近关于使用 Git 为 Ruby 部署设置 AWS Elastic Beanstalk 的教程,我刚刚从我的 CI 服务器设置了一个 Elastic Beanstalk 环境。但是,应用程序无法启动。我浏览了日志,发现bundle install失败并显示错误消息。

获取 git@github.com:example/private-repository.git 主机密钥验证失败。致命:远程端意外挂断[31mGit错误:git clone 'git@github.com:example/private-repository.git' "/var/app/ondeck/vendor/cache/ruby/1.9.1/cache/bundler/git/private-repository-e4bbe6c2b13bb62664e39e345c1b01d80017934c" --bare --no-hardlinks目录/var/app/ondeck中的命令失败。[0m

Gemfile我的 Rails 应用程序包含对托管在我在 Github 上的几个私有存储库中的 gemified 插件的引用。就像是

gem 'somegemname', :git => 'git@github.com:example/private-repository.git'

我在 Capistrano 部署中遇到过类似的问题,这些问题通过设置ssh_options[:forward_agent] = true.

AWS Elastic Beanstalk Ruby 容器支持通过.config放置在.ebextensions. 在这种情况下,设置 SSH 转发代理会有所帮助吗?在启动 Elastic Beanstalk 环境时,是否有其他替代方法可以访问私有 Github 存储库?

更新 1:我刚刚检查了bundle install启动 a 的用户。发现脚本以用户身份/opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh启动。我尝试在下创建一个 SSH 密钥,并将它的 pub-key 添加到该存储库的 Github Deploy 密钥中。到目前为止没有运气。现在将尝试将 SSH 发布密钥添加到我在 Github 上的用户帐户,以便它适用于通过我的 Github 帐户访问的所有私有存储库。bundle installroot/root/.ssh

4

5 回答 5

44

经过一天的努力,我终于通过使用一个.config文件来启用我组织的私有 GitHub 存储库和 Elastic Beanstalk。我正在使用 Python 和pip,但它也应该适用于 EB 上的其他包安装程序。

rhetonik 的ssh-agent+ssh-add方法对我根本不起作用,所以我选择设置一个 ssh 配置文件。

这是我的.ebextensions/3-pip-install-from-github.config文件:

files:
    "/root/.ssh/config":
        owner: root
        group: root
        mode: "000600"
        content: |
            Host github.com
                User git
                Hostname github.com
                IdentityFile /root/.ssh/github

commands:
    01-command:
        command: sudo ssh-keyscan -H github.com >> /root/.ssh/known_hosts
    02-command:
        command: sudo chmod 644 /root/.ssh/known_hosts
    03-command:
        command: sudo aws s3 cp s3://bucket-with-your-github-ssh-key/github /root/.ssh
    04-command:
        command: sudo chmod 600 /root/.ssh/github

粗略说明:

  • 设置您的 EB 实例可访问的 S3 存储桶pip在该存储桶中,存储 SSH 密钥,以允许通过、npmbundle等访问您想要访问的 GitHub 存储库。用于sudo aws s3 cp在部署时将该密钥复制到您的 EB 实例上。sudo是必要的,因为 EB 脚本使用root而不是ec2-user.

  • 此 ebextensions 配置文件还在您的 EB 实例上创建 2 个文件。/root/.ssh/config告诉(由andssh调用)使用从 S3 复制的密钥。存储into的输出将预先验证您的 EB 实例上实际上正在与 GitHub 通信以避免 MITM 攻击。这比禁用.pipgitssh-keyscan -H github.com/root/.ssh/known_hostssshStrictHostKeyChecking/root/.ssh/config

这是我的requirements.txt文件pip

Beaker==1.7.0
Flask==0.10.1
Jinja2==2.7.3
MarkupSafe==0.23
# [...]
git+ssh://git@github.com/myorganization/myprivaterepo.git@0.0.142

运行eb-deploy时,您可以tail -f /var/log/eb-activity.log确保一切顺利。

于 2015-08-11T15:31:16.347 回答
10

这就是我最终做到的方式。这一切都是为了为负责bundle install阶段的用户设置一个 SSH 密钥。

  1. 在 AWS Elastic Beanstalk 中为应用程序启动环境
  2. 可选- 登录到 Amazon EC2 控制台并将实例类型更改为所需值
  3. 更新 SSH 密钥对名称以启用远程 SSH 登录。(我确信在启动环境时必须有一种方法来指定实例类型和 SSH 密钥对名称)
  4. 在 EC2 控制台或通过 CLI 查找新启动的实例,记下此实例的完全限定域名 (FQDN)。EB 实例与您使用 Amazon EC2 创建的任何其他实例一样。通过 SSH 登录到此实例。
  5. 执行以下命令为root用户 创建 SSH 密钥

    $ sudo su - 根

    $ ssh-keygen -t rsa -C "some-email@yourdomain.com"

  6. 编辑.bash_profile以显式启动ssh-agent并添加新生成的 SSH 密钥。添加以下几行(这似乎没有必要,我这样做只是为了确定)

    eval `ssh-agent

    评估ssh-add ~/.ssh/id_rsa

  7. 注意 SSH 公钥,例如:~/.ssh/id_rsa.pub并将其添加到可以访问私有存储库的 Github 帐户的 SSH 密钥集中

  8. 此时,您的实例可以访问您的私有 Github 存储库。git clone您可以通过以用户身份登录在这些存储库上发出 a 来测试这一点root

  9. 使用标准方法从此实例创建 AMI

  10. 回到您的 AWS Elastic Beanstalk 仪表板并在您的应用程序环境中寻找Edit Configuration选项。在Server选项卡中,查找可让您指定Custom AMI. 使用新创建的 AMI ID 更新此字段,例如:ami-4324fd4

  11. 点击保存配置Apply Changes。AWS Elastic Beanstalk 将开始在您的环境中部署新实例并终止旧实例。这是为了确保您的所有自动扩展实例都具有私有 Github 访问所需的列入白名单的 SSH 密钥。

完成上述步骤后,您可以继续部署 Rails 应用程序git aws.push

希望这可以帮助其他陷入困境的人。不过,我很高兴看到比这个更优雅的解决方案。

于 2012-11-22T07:23:06.047 回答
4

如果您赶时间,并且您的应用程序存储库也是私有的,您可以创建一个额外的 Github 用户帐户并将其分配给包含 gem 的存储库的只读权限。

然后为 bundler 提供带有新帐户凭据的 https url:

gem 'somegemname', git: "https://username:password@github.com/example/privaterepository"
于 2013-06-11T14:42:11.110 回答
0

使用 GitHub 进行身份验证有两种方法。无论哪种情况,我都建议将您的个人 GitHub 帐户与私有 GitHub 存储库相关联。

第一种方法传递您在本地用于从远程 GitHub 存储库推送、拉取等的相同 ssh 凭据——您为您的个人帐户上传了您的公钥,这就是 GitHub 使用的。要在另一台服务器上运行时使其工作,您需要ssh-agent运行并使用ssh-add将您的密钥添加到代理 - 然后您的个人 GitHub 凭据可用于执行 git 命令。

第二种方法是允许您部署的远程服务器访问 GitHub——这可能是弹性 beanstalk 或您的实际服务器。在服务器上创建一个无密码的 ssh 密钥(ssh-keygen -t rsa接受默认值,或者 EB 可能有自己的方式)然后复制生成的公钥内容并在您的 GitHub 存储库中创建一个包含该密钥的新“部署密钥”——您将需要是管理员,我假设你是。已安装的部署密钥将允许 EB 用户登录远程服务器并从服务器执行git pull相关命令(只读)。

我认为随着您要部署到的服务器数量的增长,第一种方法更优雅且更易于管理,但您使用哪种方法可能取决于 EB 的选项。

于 2012-11-20T15:35:51.563 回答
0

从您的 requirements.txt 文件中删除私有 github 存储库,并创建一个脚本以使用用户名和密码的环境变量来安装它们。

文件:project-root/install-extra-requirements.sh

#!/bin/sh

source /opt/python/run/venv/bin/activate
python ".extra-requirements.py"

文件:project-root/.extra-requirements.py

import os

def main():
    github_username = os.environ['GITHUB_USERNAME']
    github_password = os.environ['GITHUB_PASSWORD']
    repository = "git+https://%s:%s@github.com/yourgithubrepo" % (github_username, github_password)
    os.system("pip install %s" % repository)

if __name__ == '__main__':
    main()

文件:项目根/.ebextensions/002_container.config

container_commands:
  01_install_extra_requirements:
    command: './install-extra-requirements.sh'

现在您可以在弹性 beanstalk 环境中将 GITHUB_USERNAME 和 GITHUB_PASSWORD 设置为环境变量。

于 2018-07-26T15:55:19.880 回答