在 Docker 中運行的 GitLab 頁面無法從容器外部存取

在 Docker 中運行的 GitLab 頁面無法從容器外部存取

我有一個在 docker 中運行的 GitLab 實例。 GitLab 工作正常,但我無法訪問亞搏體育appGitLab頁面

設定

概述

           +------------+
Request+-->+ Cloudflare |
           +-----+------+
                 |
                 v       +---------+
               Nginx+--->+Docker   |
                         |  +------+
                         |  |GitLab|
                         +---------+

問題是 Nginx 無法將請求傳遞到 GitLab Pages 伺服器(請注意,GitLab 它可以自行工作)。
Nginx 錯誤日誌條目

[error] 14932#14932: *30505 connect() failed (111: Connection refused) while connecting to upstream, [...]

碼頭工人

image: gitlab/gitlab-ce
version: 13.7.1 (latest)
ip: 172.17.0.7 (dynamic)
published ports:
    172.17.0.1:8080 -> 80
    172.17.0.1:8090 -> 8090

nginx

頁面的伺服器條目

server {
        listen 80 default_server;
        listen 443 default_server;
        server_name _;
        
        location / {
                proxy_pass      http://172.17.0.1:8090;
        }
}

GitLab

grep -v '^#|^$' gitlab.rb1

nginx['listen_port'] = 80
nginx['listen_https'] = false
pages_external_url "http://pages.example.com/"
gitlab_pages['enable'] = true
gitlab_pages['external_http'] = []
gitlab_pages['listen_proxy'] = "localhost:8090"
gitlab_pages['inplace_chroot'] = true
gitlab_pages['metrics_address'] = ":9235"
pages_nginx['enable'] = true
pages_nginx['listen_https'] = false
pages_nginx['redirect_http_to_https'] = false

也嘗試使用絕對最小配置,僅定義pages_external_urlgitlab_pages['enable']

追蹤問題

  1. CF 對pages.example.com 的請求失敗,出現 502(錯誤網關)
  2. 檢查Nginx日誌,發現上述日誌條目
  3. 從主機向容器發出多個請求
    1. # curl 172.17.0.1:8090 -> curl: (7) Failed to connect to 172.17.0.1 port 8090: Connection refused
    2. # curl 172.17.0.7:8090 -> curl: (7) Failed to connect to 172.17.0.7 port 8090: Connection refused
  4. 從容器發出請求
    # curl localhost:8090 -> 404 error page

由此我假設有什麼東西阻止了 8090 的傳入流量(GitLab 頁面),但要求80(GitLab)均已成功完成。我花了幾天時間在谷歌上搜尋這個問題,但我找不到任何東西。


1截斷; SMTP、LDAP 和omniauth 設定已刪除

答案1

經過幾個小時的搜尋錯誤的事情後,剛剛找到了問題的原因(稍後會詳細介紹)。

長話短說

我必須更改gitlab_pages['listen_proxy']值以在每個介面上偵聽,因此它看起來像這樣:

gitlab_pages['listen_proxy'] = "0.0.0.0:8090"

詳細的

我正在使用與 gitlab 頁面相關的關鍵字搜尋這個問題,現在我想也許我需要跳出框框思考,如果這是一個更普遍的問題,甚至與 GitLab 頁面無關怎麼辦。第一次谷歌搜尋後我發現了好文章對這個。

我收到“連接被拒絕”訊息,因為連接埠 8090 上沒有任何內容偵聽,因為localhost它指的是環回位址,即127.0.0.1,但暴露的連接埠被轉發到容器的IP,在我的情況下轉發到動態IP,在編寫問題時是172.17.0.7。因此,解決方案是監聽每個可以用作0.0.0.0IP 位址的介面。

兩張圖直觀地展示了問題和解決方案

(上述文章中的數字,但稍加修改以更好地匹配問題,並將其設為文本只是為了提高使用強制黑暗模式時的可讀性)
使用時localhost:8090

   Request      +--------------------------------------+
      +         | Default network namespace            |
      |         |                                      |
      |         |               +-------+              |
      v         |        +----->+ Nginx +------+       |
+-----+------+  |        |      +-------+      |       |
| Cloudflare |  |        |                     |       |
+-----+------+  |        |                     v       |
      |         +--------+-----------+-+-------+-------+
      |         | Physical interface | | Docker bridge |
      +-------->+ 10.0.0.1           | | 172.17.0.1    |
                +--------------------+ +-------+-------+
                                               |
                                               |
                                               v
                                       +-------+-------+
                                       | Docker bridge |
                                       | 172.17.0.7    |
                 +-------+-----------+-+---------------+
                 |       | Loopback  |                 |
                 |       | 127.0.0.1 |                 |
                 |       +-----+-----+                 |
                 |             |                       |
                 |             |      +--------------+ |
                 |             +----->+ Pages server | |
                 |                    +--------------+ |
                 |GitLab's Network namespace           |
                 +-------------------------------------+

監聽每個接口,使用0.0.0.0:8090

   Request      +--------------------------------------+
      +         | Default network namespace            |
      |         |                                      |
      |         |               +-------+              |
      v         |        +----->+ Nginx +------+       |
+-----+------+  |        |      +-------+      |       |
| Cloudflare |  |        |                     |       |
+-----+------+  |        |                     v       |
      |         +--------+-----------+-+-------+-------+
      |         | Physical interface | | Docker bridge |
      +-------->+ 10.0.0.1           | | 172.17.0.1    |
                +--------------------+ +-------+-------+
                                               |
                                               |
                                               v
                                       +-------+-------+
                                       | Docker bridge |
                                       | 172.17.0.7    |
                 +-------+-----------+-+-------+-------+
                 |       | Loopback  |         |       |
                 |       | 127.0.0.1 |         |       |
                 |       +-----+-----+         |       |
                 |             |               v       |
                 |             |      +--------+-----+ |
                 |             +----->+ Pages server | |
                 |                    +--------------+ |
                 |GitLab's Network namespace           |
                 +-------------------------------------+

答案2

我的 gitlab 16.xx 最新配置

GITLAB_OMNIBUS_CONFIG: |
        ### Web interace settings
        external_url "https://gitlab.domain.org"
        nginx['listen_port'] = 80
        nginx['listen_https'] = false

        ### Pages
        gitlab_pages['enable'] = true
        pages_external_url "https://pages.domain.org"
        pages_nginx['ssl'] = false
        pages_nginx['listen_https'] = false
        gitlab_pages['listen_proxy'] = '0.0.0.0:8090'
        gitlab_pages['internal_gitlab_server'] = 'http://localhost:8080'

這是 1 個 docker 容器的配置,該容器位於反向代理(nginx/traefik/whatever)後面。如果您在負載平衡器上終止 https(TLS),它會將流量代理到 HTTP 連接埠:80 - gitlab、8090 - 頁面。

相關內容