컨테이너 외부에서 액세스할 수 없는 Docker에서 실행되는 GitLab 페이지

컨테이너 외부에서 액세스할 수 없는 Docker에서 실행되는 GitLab 페이지

Docker에서 실행 중인 GitLab 인스턴스가 있습니다. GitLab은 잘 작동하지만 액세스할 수 없습니다.GitLab 페이지.

설정

개요

           +------------+
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

엔진스

페이지용 서버 항목

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에서 502(잘못된 게이트웨이)로 인해 Pages.example.com에 대한 요청이 실패했습니다.
  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번으로 요청(깃랩)성공적으로 완료되었습니다. 이 문제에 대해 며칠 동안 인터넷 검색을 했지만 아무것도 찾을 수 없었습니다.


1 잘림; SMTP, LDAP 및 omniauth 설정이 제거됨

답변1

몇 시간 동안 잘못된 것을 검색한 끝에 내 문제의 원인을 찾았습니다(그러나 이에 대해서는 나중에 자세히 설명합니다).

TL;DR

모든 인터페이스에서 수신 대기하도록 값을 변경해야 했기 gitlab_pages['listen_proxy']때문에 다음과 같습니다.

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

상세한

저는 gitlab 페이지와 관련된 키워드로 이 문제를 검색하고 있었는데 지금은 고정관념에서 벗어나 더 일반적인 문제이고 GitLab 페이지와도 관련이 없는 문제라면 어떻게 해야 할지 고민했습니다. 첫 번째 Google 검색 후 나는좋은 기사이것에 관해서.

localhost루프백 주소를 참조하기 때문에 포트 8090에서 아무것도 수신 대기하지 않았기 때문에 "연결이 거부되었습니다" 메시지를 받았습니다. 즉 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'

이는 역방향 프록시(nginx/traefik/whatever) 뒤에 있는 1개의 도커 컨테이너에 대한 구성입니다. 로드 밸런서에서 https(TLS)를 종료하고 트래픽을 HTTP 포트(80 - gitlab, 8090 - 페이지)로 프록시하는 경우.

관련 정보