且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何解决AWS Elastic Beanstalk Django运行状况检查问题

更新时间:2023-10-20 18:30:34

我相信您遇到的问题可能是由于文件settings.py中的ALLOWED_HOSTS设置所致.

I believe that the problem you have maybe due to the ALLOWED_HOSTS settings located in your file settings.py.

EB将HTTP请求发送到您的应用程序,以查看其是否正常运行,但是Django阻止了不是来自设置变量中指定主机的任何通信.但是这里有一个问题,EB将请求发送到ec2实例的私有ip.

EB sends an HTTP request to your application to see if its working but Django blocks any communication that is not from the specified hosts in the setting variable. But there is a problem here, EB sends the request to the private ip of the ec2 instance.

解决此问题的最简单方法是在 settings.py 文件中允许这样的所有主机:

The easiest way to solve this is to allow all HOSTS like this inside your settings.py file:

ALLOWED_HOSTS=['*']

这可能会导致安全问题,但这是最快的方法.现在,为了使其能够动态工作,由于ec2实例可以随时启动,因此私有ip随实例的变化而变化.

This may lead to security issues but is the fastest way to do it. Now, to make it work dynamically, since ec2 instances can be spin-up at any time the private ip change from instance to instance.

要解决此问题,您必须在部署过程开始时获得专用IP.

To solve this you have to get the private IP at the beginning of the deployment process.

settings.py 的顶部放置以下功能:

At the top of your settings.py place the following functions:

import os
import requests
# Other imports ...

def is_ec2_linux():
"""Detect if we are running on an EC2 Linux Instance
   See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
"""
    if os.path.isfile("/sys/hypervisor/uuid"):
        with open("/sys/hypervisor/uuid") as f:
            uuid = f.read()
            return uuid.startswith("ec2")
    return False

def get_token():
"""Set the autorization token to live for 6 hours (maximum)"""
    headers = {
        'X-aws-ec2-metadata-token-ttl-seconds': '21600',
    }
    response = requests.put('http://169.254.169.254/latest/api/token', headers=headers)
    return response.text


def get_linux_ec2_private_ip():
    """Get the private IP Address of the machine if running on an EC2 linux server.
See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html"""

    if not is_ec2_linux():
        return None
    try:
        token = get_token()
        headers = {
            'X-aws-ec2-metadata-token': f"{token}",
        }
        response = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', headers=headers)
        return response.text
    except:
        return None
    finally:
        if response:
            response.close()
# Other settings

最重要的功能是 get_token() get_linux_ec2_private_ip(),第一个设置访问令牌并对其进行检索,第二个使用该访问令牌以使用它并获取当前的ec2实例IP.

The most important functions are get_token() and get_linux_ec2_private_ip(), the first one sets the access token and retrieves it for the second one to use it and get the current ec2 instance IP.

一旦检索到它,将其添加到您的ALLOWED_HOSTS

Once you have retrieved it, add it to your ALLOWED_HOSTS

ALLOWED_HOSTS = ['127.0.0.1', 'mywebsite.com']
private_ip = get_linux_ec2_private_ip()
if private_ip:
   ALLOWED_HOSTS.append(private_ip)

此后,只需提交您的更改,并在设置了EB CLI的情况下使用 eb deploy 重新部署.

After that just commit your changes and redeploy it with eb deploy if you have set the EB CLI.