無法從容器外部訪問在 Docker 中執行的 GitLab 頁面
我有一個在 docker 中執行的 GitLab 實例。GitLab 工作正常,但我無法訪問GitLab Pages。
設置
概述
+------------+ 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.rb 1
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_url
andgitlab_pages['enable']
。追查問題
對 pages.example.com 的請求失敗,來自 CF 的 502(錯誤網關)
查看Nginx日誌,發現上面提到的日誌條目
從主機向容器發出多個請求
# curl 172.17.0.1:8090 -> curl: (7) Failed to connect to 172.17.0.1 port 8090: Connection refused
# curl 172.17.0.7:8090 -> curl: (7) Failed to connect to 172.17.0.7 port 8090: Connection refused
從容器發出請求
# curl localhost:8090 -> 404 error page
據此,我假設某些東西阻止了 8090 (GitLab Pages)的傳入流量,但對 80 *(GitLab)*的請求已成功完成。我花了幾天時間在Google上搜尋這個問題,但我找不到任何東西。
1截斷;已刪除 SMTP、LDAP 和omniauth 設置
經過數小時搜尋錯誤的事情后,才找到了我的問題的原因(但稍後會詳細介紹)。
TL;博士
我不得不改變
gitlab_pages['listen_proxy']
值來監聽每個介面,所以它看起來像這樣:gitlab_pages['listen_proxy'] = "0.0.0.0:8090"
詳細的
我正在使用與 gitlab 頁面相關的關鍵字搜尋這個問題,剛才我覺得我可能需要跳出框框思考,如果這是一個更普遍的問題,甚至與 GitLab 頁面無關怎麼辦。在第一次Google搜尋後,我發現了一篇關於這個的好文章。
我收到“連接被拒絕”消息,因為埠 8090 上沒有任何內容正在偵聽,因為
localhost
它指的是環回地址,即127.0.0.1
,但暴露的埠被轉發給容器的 IP,在我的情況下,它是一個動態 IP,寫問題時是172.17.0.7
。所以解決方案是監聽每個可能0.0.0.0
用作 IP 地址的介面。將問題和解決方案形象化的兩張圖
(來自上述文章的數字,但稍作修改以更好地匹配問題,並且在使用 force-darkmode 時僅將其變為文本以提高可讀性)
使用時
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 | +-------------------------------------+