簡體   English   中英

訪問在 AWS Linux 上運行的 NGINX 配置中的 Elastic Beanstalk 環境屬性 2

[英]Access Elastic Beanstalk environment properties in NGINX configs running on AWS Linux 2

我之前在 AWS Linux AMI 上工作過,但在 AWS Linux 2 上沒有運氣。

在 EB 應用程序部署期間,我需要從 Nginx 配置文件訪問我的環境屬性。 這是一個單實例節點服務器。

我用 AWS Linux AMI 這樣做,它沒有問題:

.ebextensions/00_options.config

option_settings:
   aws:elasticbeanstalk:application:environment:
      DOMAIN: socket.example.com
      MASTER_DOMAIN: https://example.com
      etc..

.ebextensions/10_proxy.config

... some configs ...

files:

  /etc/nginx/conf.d/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |

      upstream nodejs {
          server 127.0.0.1:8081;
          keepalive 256;
      }

      map $http_origin $cors_header {
          hostnames;
          default "";
          `{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "MASTER_DOMAIN"}}` "$http_origin";
      }

      server {

          listen 80;
          listen 8080;

          server_name `{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "DOMAIN"}}`;

          location ~ /.well-known {
              allow all;
              root /usr/share/nginx/html;
          }
          location / {
              return 301 https://$host$request_uri;
          }
      }
      
      etc..


.... some more configs ....
      

我沒有包括上面的大部分配置,因為它們不相關。

所以當我之前這樣做時,一切都按預期進行。 配置文件插入了我的屬性並在/etc/nginx/conf.d/proxy.conf文件夾中創建了文件。


現在對於 AWS Linux 2,規格已經更改,我們必須在位於應用程序包根文件夾的.platform/nginx/conf.d文件夾中添加 Nginx 配置文件。

這里參考(見反向代理配置

所以我在上面提到的位置創建了一個proxy.conf文件,其中包含之前插入的內容/etc/nginx/conf.d/proxy.conf


.platform/nginx/conf.d/proxy.conf

upstream nodejs {
    server 127.0.0.1:8081;
    keepalive 256;
}
    
map $http_origin $cors_header {
    hostnames;
    default "";
   `{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "MASTER_DOMAIN"}}` "$http_origin";
}

etc...

然后問題開始了..

第一次試驗unexpected "{" in /var/proxy/staging/nginx/conf.d/proxy.conf:11

之后我嘗試了很多東西。 嘗試使用${MASTER_DOMAIN}並使用新的 EB AWS Linux 2 個hooks (參見上面的鏈接Platform hooks )。 一切都無濟於事,您似乎無法訪問 Nginx 配置中的屬性。 我已經閱讀了一篇來自 Nginx 的文章或文檔,今天提到了類似的內容,但我再也找不到了(做了很多谷歌搜索)。


我還嘗試創建一個配置文件,就像我在工作版本中所做的那樣,目的是將臨時文件保存在包含屬性的某處,然后將此文件包含在所需的.platform/nginx/conf.d/proxy.conf文件中,因為我開始認為沒有辦法將它們直接包含在新規范中。

.ebextensions/10_proxy.config

... some configs ....

files:

  /var/proxy/staging/custom_folder/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
    
    etc...

.platform/nginx/conf.d/proxy.conf

include custom_folder/proxy.conf;

考慮到這個想法,我做了很多廢話,我創建了用於創建 ( mkdir ) 目錄的hooks ,我試圖在其中臨時保存導致新權限錯誤的文件。 我無法為 prebuild 和prebuild文件提供適當的權限, postdeploy是另一個問題。

還有更多的嘗試和失敗......


但后來我讀過(也來自上面的鏈接):

如果您將代理配置為向多個應用程序進程發送流量,則可以配置多個環境屬性,並在代理配置和應用程序代碼中使用它們的值。

希望回來了。這是否意味着我實際上可以直接將環境變量添加到位於.platform目錄中的.platform配置中? ...我不知道..你呢?


我可以繼續描述我整晚嘗試的所有事情,所以我會在這里停下來。 我希望你能明白這個問題。 如果不問我,我會盡力讓所有這些都可以理解。

在與這個問題作斗爭 14 小時后,我的頭腦也不再很清楚了。 我需要休息。

如果你做到了最后,謝謝你的時間,我們將不勝感激。

概括

一種方法是在.platform/hooks/postdeploy postdeploy 中創建一個 shell 腳本。

這是一個簡化的示例,假設您有一個名為MASTER_DOMAIN的 Elastic Beanstalk 環境屬性:

#!/bin/bash
    
# write nginx config file
cat > /etc/nginx/conf.d/elasticbeanstalk/test.conf << LIMIT_STRING
location /test/ {
  default_type text/html;
  return 200 "nginx variable: \$host, and EB env property: $MASTER_DOMAIN";
}
LIMIT_STRING
    
# restart nginx service so the config takes effect
systemctl restart nginx.service

此示例中的location塊可以替換為原始帖子中.ebextensions/10_proxy.config中的 nginx content 不過不需要Fn::GetOptionSetting東西。

我認為您還需要.platform/confighooks/postdeploy中的重復腳本。

詳情如下。

(對不起文字牆)

nginx中的環境變量

實際上,正如此處此處所討論的,不可能(開箱即用)在httpserver或 nginx 配置文件中的location塊中使用操作系統環境變量。 有一些解決方法,例如使用 lua、perl 或模板,但我們先不談這些。 這部分與 AWS 無關。

在 Amazon Linux AMI (AL1) 的 OP 原始配置中,使用.ebextensions/10_proxy.config中的files部分,他們實際上使用 shell 腳本在部署期間編寫 nginx 配置文件。 shell 腳本擴展了環境變量,但生成的proxy.conf的 proxy.conf 實際上並沒有訪問任何環境變量。

這就是它在 AL1 上起作用的原因。

平台掛鈎

現在,對於 Amazon Linux 2 (AL2),我們可以使用.platform/hooks.platform/confighooks文件夾中的 shell 腳本執行類似的操作。

這些.platform掛鈎腳本以root用戶身份執行,並且可以訪問 Elastic Beanstalk (EB) 環境屬性。 EB 環境屬性可以像普通操作系統環境變量一樣訪問,因此無需使用Fn::GetOptionSetting東西。

基本上,我們需要創建一個 shell 腳本,該腳本使用原始.ebextensions/10_proxy.configcontent寫入一個文件。 但是,我們需要考慮兩個問題:

  1. 我們應該使用prebuildpredeploy還是postdeploy鈎子?

  2. 我們的 nginx proxy.conf文件的正確目標目錄是什么?

文件位置

要回答這些問題,我們必須參考擴展 Elastic Beanstalk Linux 平台的 AWS 文檔,特別是實例部署工作流部分。

... 平台掛鈎的當前工作目錄 (cwd) 是應用程序的根目錄。 對於 prebuild 和 predeploy 文件,它是應用程序暫存目錄,對於 postdeploy 文件,它是當前應用程序目錄。 如果其中一個文件失敗(以非零退出代碼退出),部署將中止並失敗。

這很有趣,但留下了一些問題,例如“應用程序暫存目錄”位於何處? 我們可以通過檢查我們的部署日志文件之一來填補空白。 根據我們的eb-engine.log ,以下是應用程序部署期間平台掛鈎和 nginx 配置文件發生的情況(跳過很多細節):

  1. 源包從 S3 下載並提取到/var/app/staging/
  2. .platform/hooks/prebuild/中的平台鈎子被執行
  3. 代理服務器配置從/var/app/staging/.platform/nginx/復制到/var/proxy/staging/nginx
  4. .platform/hooks/predeploy/中的平台鈎子被執行
  5. 代理服務器啟動,配置從/var/proxy/staging/nginx/復制到/etc/nginx
  6. .platform/hooks/postdeploy/中的平台鈎子被執行

請注意,部署后,應用程序位於/var/app/current中。

基於以上,有幾種選擇:

  1. 在寫入/etc/nginx/conf.d/proxy.conf.platform/hooks/postdeploy postdeploy 中創建一個 shell 腳本。

    nginx服務已經運行,現階段需要重啟才能使配置生效。

    下面是一個最小的測試示例。 在此示例中,我們寫入elasticbeanstalk子目錄,因為我們只想在默認server塊內添加一個location 然后我們可以在瀏覽器中訪問/test/頁面,以檢查配置是否有效。

    我們使用一些bash io 重定向<<> )來編寫 nginx 配置文件。

    請注意,我們需要轉義任何 nginx 變量,例如$host變為\$host ,否則 shell 會將它們解釋為環境變量。

    另請注意,shell 腳本需要具有執行權限,如文檔中有關平台掛鈎的更多信息中所述。

#!/bin/bash
    
cat > /etc/nginx/conf.d/elasticbeanstalk/test.conf << LIMIT_STRING
location /test/ {
  default_type text/html
  return 200 "nginx variable: \$host, and EB env property: $MASTER_DOMAIN";
}
LIMIT_STRING
    
systemctl restart nginx.service
  1. 或者,我們可以在.platform/hooks/predeploy中創建一個 shell 腳本,該腳本寫入/var/proxy/staging/nginx/conf.d/proxy.conf

    在這種情況下不需要重新啟動 nginx 服務,因為這個鈎子是在應用服務器配置之前執行的。

謹防:

不確定這是錯誤還是設計特性,但我們新創建的proxy.conf配置部署(與應用程序部署相反)后消失,除非我們將重復的腳本放在.platform/confighooks/postdeploy目錄中。 不是很干...

編輯:AWS 支持人員確認在這種情況下我們需要hooksconfighooks掛鈎中的重復腳本。 文檔中的應用示例還在hooksconfighooks中顯示了一些重復項(至少是重復的文件名)。

編輯:除了復制腳本,我們還可以編寫一個調用鈎子的配置鈎子,例如.platform/confighooks/predeploy/01_my_confighook.sh可能如下所示:

#!/bin/bash
source "/var/app/current/.platform/hooks/predeploy/01_my_hook.sh"

免責聲明:這是在新創建的單實例EB 環境中測試的,“Python 3.7 在 64 位亞馬遜 Linux 2/3.1.5 上運行”,使用所有默認配置和默認 AWS Python 示例應用程序(僅使用我們的自定義掛鈎進行擴展)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM