将 Elastic Beanstalk 环境从 AWS Linux 1 升级到 AWS Linux 2

Zag*_*ags 3 python amazon-web-services amazon-elastic-beanstalk

我有一个在 AWS Linux 1 上运行 Python 3.6 的 Elastic Beanstalk 环境,我想将其切换到 Amazon Linux 2 上的 Python 3.8。

我知道我可以使用 aws CLIupdate-environment命令升级环境:

aws elasticbeanstalk update-environment --environment-name <ENV_NAME> --solution-stack-name "64bit Amazon Linux 2 v3.3.7 running Python 3.8"
Run Code Online (Sandbox Code Playgroud)

但是,AWS Linux 2 使用不同的配置参数。我无法部署 AWS Linux 2 配置,因为它在 AWS Linux 1 上无效,并且我无法升级到 AWS Linux 2,因为我的配置无效。

如何进行升级?有没有办法就地进行升级?

Zag*_*ags 12

配置差异

AWS Linux 2 对 Elastic beanstalk 的工作方式及其配置方式进行了很多更改。无论您是进行就地升级还是启动新环境,这里列出了在升级之前需要执行的不同操作。这里的大多数项目与.ebextensions.

  1. Python 3.6 和 3.8 之间的子包依赖关系存在差异。您应该在 Python 3.8 上测试您的需求文件并确保它兼容,特别是如果您使用生成的requirements.txt.

  2. AWS Linux 2 不再允许您file使用.ebextensions. 这些修改现在需要存在于.platform/httpd/conf.

  3. 运行 container_commands 时,虚拟环境不再处于活动状态。使用您的代码的任何容器命令都需要source $PYTHONPATH/activate先运行。

  4. 生成的文件现在会在配置更改时被擦除,因此像 django 这样的命令collectstatic 需要移动到 hooks

  5. 尽管 yum,Postgres 客户端不再正常可用。要安装它,您需要执行以下操作:

    packages:
        yum:
            amazon-linux-extras: []
    
    commands:
        01_postgres_activate:
            command: sudo amazon-linux-extras enable postgresql10
        02_postgres_install:
            command: sudo yum install -y postgresql-devel
    
    Run Code Online (Sandbox Code Playgroud)
  6. Apache 不再是默认的 Web 服务器(而是 Nginx)。要继续使用它,您需要将其指定为环境中的选项,例如:

    option_settings:
      aws:elasticbeanstalk:environment:proxy:
        ProxyServer: apache
    
    Run Code Online (Sandbox Code Playgroud)
  7. Modwsgi 已被 Gunicorn 取代。您拥有的任何 modwsgi 自定义都将不再起作用,并且 WSGI 路径具有不同的格式:

    option_settings:
      aws:elasticbeanstalk:container:python:
        WSGIPath: config.wsgi:application
    
    Run Code Online (Sandbox Code Playgroud)
  8. 静态文件配置有不同的格式:

    option_settings:
      aws:elasticbeanstalk:environment:proxy:staticfiles:
        /static: staticfiles
    
    Run Code Online (Sandbox Code Playgroud)
  9. 您将选择加入高级健康报告。强烈建议添加 Elastic Beanstalk 运行状况检查:

    option_settings:
      aws:elasticbeanstalk:application:
        Application Healthcheck URL: /health-check/
    
    Run Code Online (Sandbox Code Playgroud)
  10. 该应用程序现在通过 Gunicorn 在服务器上的端口 8000 上运行,Apache/Nginx 只是将请求代理到 Gunicorn。如果您正在进行 apache 定制(例如加密负载平衡器和应用程序服务器之间的流量) ,这一点就很重要。

  11. Apache 现在通过 systemctl 而不是supervisord 运行。如果您尝试重新启动 Apache,则命令现在是sudo systemctl restart httpd

  12. 如果您想在 sshed 到服务器时加载环境变量,则需要以不同的方式解析它们:

  13. 环境变量位于不同的位置并且具有不同的格式。要在通过 SSH 连接时访问它们,您需要添加jq: []到 yum 安装中。然后,运行以下命令或将它们添加到服务器的 bashrc(使用file中的指令.ebextensions)来加载环境变量并激活 python 虚拟环境:

    source <(/opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""')
    source $PYTHONPATH/activate
    cd /var/app/current
    
    Run Code Online (Sandbox Code Playgroud)

通过启动新环境进行升级

要采用此升级路径,您不需要使用 Elastic Beanstalk 数据层(即您自己启动 RDS 实例,而不是通过 Elastic Beanstalk)。

  1. 使用您的 AWS Linux 2 配置创建代码分支

  2. 在 AWS Linux 2 上启动新的 Elastic Beanstalk 环境。

  3. 从之前的环境中复制环境变量。

  4. 允许从新环境访问您的数据库(将新环境的服务器安全组添加为数据库安全组的入口规则的目标)

  5. 在新环境中设置 SSL。

  6. 将 AWS Linux 2 代码分支部署到新环境。

  7. 测试这个新环境,忽略浏览器证书警告(或设置临时 DNS 条目来测试它)。

  8. 切换 DNS 条目以指向您的新环境,或在两个环境上使用 AWS 的 CNAME 交换功能

  9. 当新环境运行足够长的时间而没有出现问题后,终止旧环境。

就地升级

有一种方法可以就地升级,尽管几分钟后您的网站会显示“502 Bad Gateway”。为此,您需要与 AWS Linux 1 和 AWS Linux 2 环境兼容的 EB 配置。

对于 Python,您可以使用一个小型 Flask 应用程序和一个由四部分组成的部署来完成此操作。

第 1 部分:部署与两个平台兼容的占位符应用程序

  1. 添加flask到您的requirements.txt(如果尚不存在)。

  2. 删除所有文件.ebextensions

  3. 制作.ebextensions/01.config

    option_settings:
      aws:elasticbeanstalk:container:python:
        WSGIPath: wsgi_shim.py
    
    Run Code Online (Sandbox Code Playgroud)
  4. 制作wsgi_shim.py

    from flask import Flask
    
    application = Flask(__name__)
    
    @application.route("/")
    @application.route("/<path:path>/")
    def hello_world(path=None):
        return "This site is currently down for maintenance"
    
    Run Code Online (Sandbox Code Playgroud)
  5. [如果使用负载均衡器对应用程序服务器加密,请将负载均衡器更改为通过 HTTP 将所有流量发送到服务器。]

  6. eb deploy

第 2 部分:将平台升级到 AWS Linux 2

  1. [如果您在 elastic beanstalk 中配置了任何静态路由,请删除它们。]

  2. 升级您的 eb 环境

    # Get list of solution stacks
    aws elasticbeanstalk list-available-solution-stacks --output=json --query 'SolutionStacks' --region us-east-1
    
    # Use one of the above options here
    aws elasticbeanstalk update-environment --environment-name <ENV_NAME> --solution-stack-name "64bit Amazon Linux 2 v3.3.7 running Python 3.8"
    
    Run Code Online (Sandbox Code Playgroud)

第 3 部分:将主应用程序部署到 AWS Linux 2

  1. 替换.ebextensions/01.config为新的 AWS Linux 2 配置。

  2. 添加.platform/httpd/conf.d/ssl_rewrite.conf

    RewriteEngine On <If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'"> RewriteRule (.*) https://%{HTTP_HOST} %{REQUEST_URI} [右,左]

  3. eb deploy

第 4 部分:清理

  1. [如果使用负载均衡器对应用程序服务器加密,请将负载均衡器更改回通过 HTTPS 向服务器发送流量。]

  2. 从中删除wsgi_shim.py并移除 Flask requirements.txt(除非它是 Flask 项目)。

  3. eb deploy