【问题标题】:Cannot access airflow web server via AWS load balancer HTTPS because airflow redirects me to HTTP无法通过 AWS 负载均衡器 HTTPS 访问气流 Web 服务器,因为气流将我重定向到 HTTP
【发布时间】:2018-07-02 22:39:42
【问题描述】:

我在 EC2 上配置了一个气流网络服务器,它侦听端口 8080。

我在 EC2 前面有一个 AWS ALB(应用程序负载均衡器),监听 https 80(面向互联网),实例目标端口面向 http 8080。

我无法从浏览器浏览 https://,因为气流 Web 服务器将我重定向到 http:///admin,ALB 不监听。

如果我从浏览器浏览 https:// /admin/airflow/login?next=%2Fadmin%2F,我会看到登录页面,因为此链接不会重定向我。

我的问题是如何更改气流,以便在浏览 https:// 时,气流网络服务器会将我重定向到 https:...,而不是 http://..... 以便 AWS ALB 可以处理请求。

根据下面的答案,我尝试将airflow.cfg 的base_url 从http://localhost:8080 更改为https://localhost:8080,但我看不出与我的更改有什么不同......

无论如何,如何从 ALB 访问 https://

【问题讨论】:

    标签: amazon-web-services airflow amazon-elb


    【解决方案1】:

    我们在我的团队中解决了这个问题,方法是向我们的 ALB 添加一个 HTTP 侦听器,该侦听器将所有 HTTP 流量重定向到 HTTPS(因此我们有一个 HTTP 侦听器和一个 HTTPS 侦听器)。我们的 Airflow 网络服务器任务仍然在端口 80 上侦听 HTTP 流量,但是这个 HTTP 流量只在我们的 VPC 中,所以我们不在乎。从浏览器到负载均衡器的连接始终是 HTTPS 或 HTTP,然后重新路由到 HTTPS,这很重要。

    这是新监听器的 Terraform 代码:​​

    resource "aws_lb_listener" "alb_http" {
      load_balancer_arn = aws_lb.lb.arn
      port              = 80
      protocol          = "HTTP"
      default_action {
        type = "redirect"
        redirect {
          port        = "443"
          protocol    = "HTTPS"
          status_code = "HTTP_301"
        }
      }
    }
    

    或者,如果您是 AWS 控制台,您可以在这里为侦听器设置默认操作:

    Console

    【讨论】:

      【解决方案2】:

      我在使用official apache airflow helm chart(1.0.0 版)时也遇到了这个问题。

      问题

      最初我配置了LoadBalancer类型的网络服务器服务。

      webserver:
        service:
          type: LoadBalancer
          annotations:
            service.beta.kubernetes.io/aws-load-balancer-internal: "true"
            service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:1234512341234:certificate/231rc-r12c3h-1rch3-1rch3-rc1h3r-1r3ch
            service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      

      这导致了经典弹性负载均衡器的创建。

      这主要是可行的,但是当我单击气流徽标(链接到 https://my-domain.com)时,我会被重定向到 http://my-domain.com/home,但由于负载平衡器配置为仅使用 HTTPS,因此失败。

      解决方案

      我通过在我的 EKS 集群上安装 AWS Load Balancer Controller 然后配置入口解决了这个问题。

      图表配置的入口相关部分如下所示:

      ingress:
        enabled: true
        web:
          host: my-airflow-address.com
          annotations:
            kubernetes.io/ingress.class: alb
            alb.ingress.kubernetes.io/subnets: subnet-01234,subnet-01235,subnet-01236
            alb.ingress.kubernetes.io/scheme: internal  # if in private subnets
            alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
      webserver:
        service:
          type: NodePort
      
      

      注意事项

      也许可以将网络服务器配置为使用 ALB 而不是经典 ELB,并将其配置为处理 HTTP 路由,但我还没有测试过。

      【讨论】:

        【解决方案3】:

        深入研究the gunicorn documentation:似乎可以通过GUNICORN_CMD_ARGS 环境变量传递任何命令行参数(当调用 gunicorn 命令时)。

        所以我正在尝试设置GUNICORN_CMD_ARGS=--forwarded-allow-ips=*,因为所有流量都会从 AWS ALB 到达我的实例...我猜可以用实例看到的 ALB 的实际 IP 替换通配符,但这将是下一步......

        由于我在 ECS 上运行,我将其传递为:

                    - Name: GUNICORN_CMD_ARGS
                      Value: --forwarded-allow-ips=*
        

        在我的taskcontainer definitionEnvironment 中。

        PS:从文档中,这种可能性是从 gunicorn 19.7 开始添加的;相比之下,Airflow 1.10.9 似乎在 gunicorn 19.10 上与任何(或多或少)最新版本的 Airflow 一起使用!

        【讨论】:

          【解决方案4】:

          由于他们使用 Gunicorn - 您可以将 forwarded_allow_ips 值配置为环境变量,而不必使用 Nginx 之类的中间代理。

          就我而言,我只是设置了FORWARDED_ALLOW_IPS = *,它工作得非常好。

          在 ECS 中,如果您将一个 docker 映像用于所有 Airflow 任务(网络服务器、调度程序、工作人员等),则可以在网络服务器任务配置中进行设置。

          【讨论】:

            【解决方案5】:

            用户 user389955 自己的解决方案可能是最好的方法,但对于任何寻求快速修复(或想要更好地了解正在发生的事情)的人来说,这似乎是罪魁祸首。

            在以下文件中(python 发行版可能不同):

            /usr/local/lib/python3.5/dist-packages/gunicorn/config.py

            以下部分防止从本地以外的任何地方转发标头

            class ForwardedAllowIPS(Setting):
                name = "forwarded_allow_ips"
                section = "Server Mechanics"
                cli = ["--forwarded-allow-ips"]
                meta = "STRING"
                validator = validate_string_to_list
                default = os.environ.get("FORWARDED_ALLOW_IPS", "127.0.0.1")
                desc = """\
                    Front-end's IPs from which allowed to handle set secure headers.
                    (comma separate).
            
                    Set to ``*`` to disable checking of Front-end IPs (useful for setups
                    where you don't know in advance the IP address of Front-end, but
                    you still trust the environment).
            
                    By default, the value of the ``FORWARDED_ALLOW_IPS`` environment
                    variable. If it is not defined, the default is ``"127.0.0.1"``.
                    """
            

            如果 IP 未知,则从 127.0.0.1 更改为特定 IP 或 * 即可。

            此时,我还没有找到从气流配置本身设置此参数的方法。如果我找到办法,会更新我的答案。

            【讨论】:

              【解决方案6】:

              最后我自己找到了解决办法。

              我在 ALB 和气流网络服务器之间引入了一个 nginx 反向代理:即。 https 请求 ->ALB:443 ->nginx 代理:80 ->web 服务器:8080。我让 nginx 代理通过添加 http 标头“X-Forwarded-Proto https”来告诉气流 Web 服务器原始请求是 https 而不是 http。

              nginx 服务器与 web 服务器位于同一位置。我将它的配置设置为 /etc/nginx/sites-enabled/vhost1.conf (见下文)。此外,我删除了 /etc/nginx/sites-enabled/default 配置文件。

              server {
                  listen 80;
                  server_name <domain>;
                  index index.html index.htm;
                  location / {
                    proxy_pass_header Authorization;
                    proxy_pass http://localhost:8080;
                    proxy_set_header Host $host;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto https;
                    proxy_http_version 1.1;
                    proxy_redirect off;
                    proxy_set_header Connection "";
                    proxy_buffering off;
                    client_max_body_size 0;
                    proxy_read_timeout 36000s;
                  }
              }
              

              【讨论】:

              • 为什么让nginx代理告诉airflow web服务器原始请求是https而不是http?有必要吗?
              【解决方案7】:

              我认为您的一切工作正常。您看到的重定向是预期的,因为网络服务器是从 //adminset to redirect。如果您使用 curl,则可以传递标志 -L / --location 以跟踪重定向,它应该会将您带到 DAG 列表。

              另一个很好的测试端点是https://&lt;airflow domain name&gt;/health(没有尾部斜杠,否则你会得到 404!)。它应该返回“服务器正常!”。

              确保您在气流配置的网络服务器部分下的base_url 中有https://

              【讨论】:

              • 谢谢丹尼尔,如果我尝试直接从浏览器浏览 https:///admin,我会得到页面!所以问题是由于气流网络服务器将 https:// 重定向到 http:///admin,我的 AWS ALB 没有监听。我当前的airflow.cfg 有base_url = http://localhost:8080。你的意思是我应该把它改成 base_url = https : //localhost:8080?我不明白。我的网络服务器正在监听 http 端口 8080,它前面的 ALB 正在监听 https 80。
              • 我认为 base_url 不会影响重定向,仅用于电子邮件。
              猜你喜欢
              • 2017-02-19
              • 2018-12-15
              • 2015-03-18
              • 2023-04-01
              • 2017-10-21
              • 1970-01-01
              • 2023-03-08
              • 2020-08-21
              • 2015-11-13
              相关资源
              最近更新 更多