
У меня есть экземпляр GitLab, работающий в docker. 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
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_url
и gitlab_pages['enable']
.
Отслеживание проблемы
- Запрос к pages.example.com не удался с кодом 502 (неверный шлюз) от CF
- Проверил журнал 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), но запросы на 80(GitLab)успешно завершены. Я потратил пару дней на гугление этой проблемы, но ничего не нашел.
1 Усечено; удалены настройки SMTP, LDAP и omniauth
решение1
Только что нашел причину своей проблемы после многих часов поисков не того (но об этом позже).
TL;DR
Мне пришлось изменить gitlab_pages['listen_proxy']
значение для прослушивания на каждом интерфейсе, поэтому это выглядит так:
gitlab_pages['listen_proxy'] = "0.0.0.0:8090"
Подробный
Я искал эту проблему по ключевым словам, связанным с страницами gitlab, и только сейчас подумал, что, возможно, мне нужно мыслить нестандартно, что если это более общая проблема и даже не связанная с страницами GitLab. После первого поиска в Google я нашелхорошая статьяоб этом.
Я получил сообщение "connection denied", потому что порт 8090 не прослушивался, так как localhost
ссылается на адрес обратной связи, т. е. 127.0.0.1
, но открытые порты перенаправляются для IP контейнера, в моем случае на динамический IP, который при написании вопроса был 172.17.0.7
. Поэтому решение заключается в прослушивании каждого интерфейса, который возможно использовать 0.0.0.0
в качестве IP-адреса.
Две фигуры, наглядно иллюстрирующие проблему и ее решение
(Рисунки из упомянутой статьи, но немного изменены для лучшего соответствия вопросу и сделаны только текстовыми для улучшения читабельности при использовании принудительного темного режима)
Когда используешь 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/что угодно). Если вы завершаете https(TLS) на балансировщике нагрузки, и он проксирует трафик на порты HTTP: 80 - gitlab, 8090 - pages.