traefik 代理后面的 docker 中的 gitlab 失败(通常)

Posted

技术标签:

【中文标题】traefik 代理后面的 docker 中的 gitlab 失败(通常)【英文标题】:gitlab in docker behind traefik proxy fails (usually) 【发布时间】:2017-06-30 18:46:11 【问题描述】:

我有几个使用 LetsEncrypt 凭据在 docker 中运行并通过 traefik 路由的网站。 我想使用 LetsEncrypt 和 traefik 在 docker 中运行本地 gitlab-ce。

所以我将它添加到我的 traefik.toml 文件中:

[[acme.domains]]
  main = "gitlab.mydomain.com"

这个到 config/gitlab.rb:

external_url "http://gitlab.mydomain.com"

我开始 gitlab:

docker run -d --restart=always \
     --hostname gitlab.mydomain.com \
     --expose 80 \
     --volume /srv/gitlab/config:/etc/gitlab \
     --volume /srv/gitlab/data:/var/opt/gitlab \
     --volume /var/log/gitlab:/var/log/gitlab \
     --label traefik.frontend.rule=Host:gitlab.mydomain.com \
     --name gitlab gitlab/gitlab-ce:latest

转到https://gitlab.mydomain.com/ 我获得了一个带有 LetsEncrypt 生成证书的安全站点,但该站点无法加载:

内部服务器错误

当我重新加载页面时,我在docker logs gitlab -f 看到这个:

==> /var/log/gitlab/sshd/current <==
2017-02-12_16:51:31.00446 Bad protocol version identification 'GET / HTTP/1.1' from 172.17.0.8 port 41138
2017-02-12_16:51:31.26238 Bad protocol version identification 'GET /favicon.ico HTTP/1.1' from 172.17.0.8 port 41140

在日志中搜索/error/i,我发现有几件事可能是问题(zruby/gems/2.3.0/gems/redis-3.2.2z 中报告了很多错误)但没有“确凿证据”AFAICT。

最疯狂的是,我运行docker restart gitlab 大约每十次左右(随机),该网站就会完美出现。我一直很想把它搁置一旁,但其中隐藏着疯狂......

我怎样才能让它可靠地出现?或者我怎样才能更完整地调试它?

【问题讨论】:

尝试将http 更改为https。是否已调整 gitlab.rb 以指向正确的证书? 谢谢 - 我已经尝试过 httphttps 并已将 gitlab 指向自签名证书,但 gitlab 站点(随机)出现的唯一时间是 http .这与 traefik 和 LetsEncrypt 的工作方式相匹配(即使没有启动,gitlab 也会在带有 LetsEncrypt 证书的浏览器工具栏中显示“安全”)。 我在 kubernetes 环境中遇到了类似的问题(入口 traefik)。使用GITLAB_HTTPS=false 设置,总是成功,但GITLAB_HTTPS=true 永远不会成功。 【参考方案1】:

我使用了sameersbn's docker-compose,并在同一目录中添加了以下 docker-compose.override.yml。

version: "2"

services:
    gitlab:
      labels:
        - "traefik.frontend.rule=Host:git.schulz.codes"
        - "traefik.port=80"
        - "traefik.enable=true"
        - "traefik.frontend.entryPoints=http,https"

使用以下 traefik docker-compose 可以很好地保持安静

version: "2"

services:
  proxy:
    restart: always
    image: traefik
    container_name: traefik
    command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
    ports:
      - "8080:8080"
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik.toml:/etc/traefik/traefik.toml
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/etc/traefik/acme:rw

还有这个 traefik.toml

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
defaultEntryPoints = ["http", "https"]
[acme]
email = "yourmail@domain.com"
storageFile = "/etc/traefik/acme/acme.json"
entryPoint = "https"
OnHostRule = true
[[acme.domains]]
  main = "domain.com"
  sans = ["gitlab.domain.com"]
[web]
address = ":8080"
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "docker.localhost"
watch = true
exposedbydefault = true

【讨论】:

【参考方案2】:

这个答案对你来说可能来得太晚了,但我遇到了同样的问题并且能够解决它。

重要的线索是日志错误是由sshd 守护进程引起的!

Traefik 默认会选择容器公开的第一个端口(通过 Dockerfile,而不是您手动公开的端口!)。 对于 Gitlab 容器,这是 ssh 端口 22。

所以 Traefik 会将 Web 请求定向到 Gitlab 的 SSH 守护进程。

要解决此问题,您需要为 Traefik 明确设置端口,并带有标签:

Traefik 1.x:

labels:
    ...
    - traefik.port=80

Traefik 2.x:

labels:
    - traefik.http.services.<your-service-name>.loadbalancer.server.port=80

【讨论】:

traefik 2.1 的标签是:traefik.http.services.&lt;your-service-name&gt;.loadbalancer.server.port=80 使用 traefik >=2.2.1 它必须是 traefik.http.services.&lt;your-service-name&gt;.loadbalancer.server.port=80

以上是关于traefik 代理后面的 docker 中的 gitlab 失败(通常)的主要内容,如果未能解决你的问题,请参考以下文章

traefik 2.1 for docker

Traefik:反向代理工具

Docker traefikV2.1

Traefik,多个前端规则到一个 docker 容器

新反向代理与负载均衡工具 traefik 安装配置部署详解

traefik使用