Попытка подключиться к сервису grpc, работающему на изолированном рое Docker, которое открывается через Traefik - PullRequest
0 голосов
/ 24 мая 2019

Я пытался настроить Traefik в качестве обратного прокси-сервера для моего роя Dev Docker, который работает на собственной VPN, изолированной от внешнего мира. Рой состоит из 3 управляющих узлов и 3 рабочих узлов и не имеет TLS для связи между ними. Мне удалось правильно установить количество внешних интерфейсов (с правилами для хоста) и внутренних компонентов, которые указывают на службы, работающие в рое. Ниже приведен мой файл docker-compose, который я использую для развертывания стека докеров для traefik на рое.

version: '3.6'

networks:
  traefik:
    driver: overlay

configs:
  traefik:
    file: ./config.dev.toml

services:
  traefik:
    image: traefik:1.7
    command:
      - --docker
      - --docker.swarmMode
      - --docker.domain=traefik.dev.pap
      - --docker.exposedByDefault=false
      - --entryPoints=Name:http Address::80 Redirect.EntryPoint:https
      - --entryPoints=Name:https Address::443 TLS:/certs/certfile.cert,/certs/keyfile.key
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    configs:
      - source: traefik
        target: /traefik.toml
    networks:
      - traefik
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host
      - target: 8080
        published: 8080
        mode: host
      - target: 8081
        published: 8081
        mode: host
      - target: 8082
        published: 8082
        mode: host
    deploy:
      mode: global
      placement:
        constraints:
          - node.role == manager
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure

Toml файл для traefik

defaultEntryPoints = ["http", "https"]

logLevel = "WARN"

insecureSkipVerify = true

[entryPoints]
  [entryPoints.http]
    address = ":80"
    [entryPoints.http.auth.basic]
    users = ["traefik:$2y$05$ZF08gDSv0f88vEUVzmwuxu.9seYIAZVzTMXnrETBDhQT30dxu4vOu"]
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = """-----BEGIN CERTIFICATE-----
                    MIICsjCCAZoCCQDP9WReX5fgQjANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBAq
                    dHJhZWZpay5kZXYucGFwMB4XDTE5MDUyNDIwMTYzMloXDTIwMDUyMzIwMTYzMlow
                    GzEZMBcGA1UEAwwQKnRyYWVmaWsuZGV2LnBhcDCCASIwDQYJKoZIhvcNAQEBBQAD
                    ggEPADCCAQoCggEBAJ86nJMpyENKQrsDlfrMI8TwdAuHXXLpglMSPVmmTzm0Y7F7
                    CVRAwl8NJdbBJnBmK3+vaG1P3WfXfu/pBfn8GDrvlJd+1XqKdExMYMCDy2Ay1ghk
                    1mOcRkJ2XS2h7FjvGjAmE7/icYZprRziek/4hLCtpTjPwPIx/5tN/ZR+lpMXe+dG
                    24CqvcTftZCS+RZSMuACG0tKlmhOx/xjoUOQMiEA8ysmQE+RrEs7ZSvu1SLYMILa
                    jGrHmH/52kIia+zOJqi8k4pVTkRFB1CNeSURgFOQf1zWzSI49GTh0UGsmlgeMoOX
                    FgrEjsbmMKxCz8ItPiTMjJ1zLd5YyBt+ATeDl0kCAwEAATANBgkqhkiG9w0BAQsF
                    AAOCAQEAYXrBbyJ75TMInYmPjkPD/Vdh3dI62qwHrKJsXN519FC8gbYSJFSdr5Pd
                    y/stM2Xn8KGgnkLSuo62MzGD15X/IYqn4Kt9Eizqd5kpsdNc7l/pTTidcCY3nQ82
                    CUGQrnwyVjZ/8wwbjtTL1TOismK3yA169WXD2yXGz15fR08lLCMqXEKotl82FxfX
                    6mw9EkLC3MAfIxuuWcaCl8/AHAUlrzrQOoVj9OkBcxwYeYH++KKYOGCaiuKMen9x
                    cjyCo05qmBQq4PWOoafDJMrdAcnzjc0tTW3DBTnJY7tR0qA/6iGVsdlHce6rMZtR
                    sb5m6XFgABCcg54yfrHIGgv1Te78aA==
                    -----END CERTIFICATE-----
                    """
      keyFile = """-----BEGIN PRIVATE KEY-----
                    MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfOpyTKchDSkK7
                    A5X6zCPE8HQLh11y6YJTEj1Zpk85tGOxewlUQMJfDSXWwSZwZit/r2htT91n137v
                    6QX5/Bg675SXftV6inRMTGDAg8tgMtYIZNZjnEZCdl0toexY7xowJhO/4nGGaa0c
                    4npP+ISwraU4z8DyMf+bTf2UfpaTF3vnRtuAqr3E37WQkvkWUjLgAhtLSpZoTsf8
                    Y6FDkDIhAPMrJkBPkaxLO2Ur7tUi2DCC2oxqx5h/+dpCImvsziaovJOKVU5ERQdQ
                    jXklEYBTkH9c1s0iOPRk4dFBrJpYHjKDlxYKxI7G5jCsQs/CLT4kzIydcy3eWMgb
                    fgE3g5dJAgMBAAECggEBAJb3QyxkGPNznQEizTgUBHXcZKnplbg1nNKWIIS3IbZc
                    SYkkVhwDqkXkeVO7nW5D8EoHTMMXTZv+vONJ09jII1D9hax9HHoqe0k7wR/F1TVH
                    /ZXHxVx79kFdZ8q0Exne2L193Iu5blk6KF+SetUHkwbQHC5ZC16V+PqOXzZDLxAV
                    XOXjv5nOK2bqffgZdjYmW3fiwARJ1y/2s6G2Pn3Uk9z3Hk259ZI6k1zE4mwmf62t
                    FQJfjDQ7Ej7N0lXwmSA/Kb7qTXQ/div+juGlEjKTZIZRJMcLOxaZMo93sU8T/Y6b
                    wWnsRvEZlZ9yy8Y/OWN3UxWjc6nx8DPI6sYnTBUNEmECgYEA0Co6Px6n4CFtmeT6
                    6vj/YNGY1vzrycqixtymaIJk7TmPXeLqL919Sro/jbI0B189tnm3DFLk458feRaA
                    Nw+Jl1vQo9IjutJ1ujNt7IrCtlP6smRpQ5fXQ9Ywk3IPtZiG9W+fxM1uHSYKoAh/
                    sAym38Ao5hPRoRJ0TJxvlkCJtz8CgYEAw9GdFa+CXcx9U8pZE1tV2J9gXjd0mr10
                    OKjpKA9ez8IOB9S96bNOiEwHzzsza+OFoou1DrIK0zoK2+XYZYJ+sWOU1pO4PYlj
                    vbRC5kFb2EvD5h47oIoAWqk3QOGewM+z6eWI9r4LTOgdiZ1r6c73jydGGtTBtcZq
                    oqgVOziHV3cCgYEAgtw495se77A0BU3ES1iyujuo+GXRGG7xe1AUsJhgOB06Okw+
                    6k4zyHljIIGJYaUG16KWZwHpcAqFL4rsmTCET4lhlMqyuWw6pA5WqR/mHdaXP/QN
                    lHds1PFeYiKPK5qyJLLCXmbCNULH5SjSlGqvsPNNAq4s1zQRtmOVZoA10uMCgYBw
                    laPrQ+2AYIHuGvj72BeTZI7TnK6+CQ85RGRJVAz/BmNqvTYzl5QfaRdUXoVCEp5S
                    xmBjApqWt1hm9c9lDZIqC0cX1/al6sgd2fZczFcyFN2dAOTneHCbr47FDvNniAO5
                    Bu+obbuxjALvjELvOr+63qm/43M8P8gvnNQYKHgoIQKBgQCQJrT3z27O/hRVUIGg
                    bwAmzwGExOC39uLHNWmOcVmw36oV592sVw1K9pRvPFVJp956T63lhcGv4t0ki2DE
                    gBN/V1jhkAw33qRDd5bbYmIutf6RO7HeewwFHpbaLw0FULe5UlsziE9AbTHmddqU
                    GTcyajXnqimXvSu6AC9XFA9s4g==
                    -----END PRIVATE KEY-----
                   """
  [entryPoints.api]
    address = ":8081"
  [entryPoints.ping]
    address = ":8082"

[api]
  entryPoint = "api"
  dashboard = true

[ping]
  entryPoint = "ping"

[retry]
  logLevel = "DEBUG"

[traefikLog]
  logLevel = "DEBUG"
  format   = "json"

[accessLog]
  logLevel = "DEBUG"
  format = "json"

[docker]
  endpoint = "unix:///var/run/docker.sock"
  domain = "traefik.dev.pbp"
  swarmmode = true
  watch = true
  exposedByDefault = false

Указанные выше сертификаты были сгенерированы на моем ноутбуке с помощью команды: openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./backend.key -out ./backend.cert и общее имя: *traefik.dev.pap.

2 службы, которые я хочу предоставить, имеют следующие метки:

      labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_traefik"
      # Public segment
      - "traefik.public.protocol=h2c"
      - "traefik.public.port=50051"
      - "traefik.public.frontend.rule=Host:serviceA-grpc.traefik.dev.pbp"
      - "traefik.public.frontend.auth.forward.tls.insecureSkipVerify=true"
      - "traefik.public.backend.loadbalancer.method=drr"
      - "traefik.public.frontend.passHostHeader=true"
      labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_traefik"
      # Public segment
      - "traefik.public.protocol=http"
      - "traefik.public.port=8080"
      - "traefik.public.frontend.rule=Host:serviceB-gateway.traefik.dev.pbp"
      - "traefik.public.frontend.passHostHeader=true"
      - "traefik.public.backend.loadbalancer.method=drr"

Первый - это служба grpc, которую я запускаю, а второй - HTTP-шлюз для службы grpc. 2-й работает как положено. Там нет ничего странного, кроме того факта, что сертификат небезопасен. Тем не менее, мне очень трудно сделать сервис grpc доступным для Traefik. Если я выполню grpcurl -plaintext tag-service-grpc.traefik.dev.pbp:443 list, я получу результат Failed to list services: rpc error: code = Unknown desc = Internal Server Error и журналы Traefic

{"BackendAddr":"","BackendName":"Traefik","BackendURL":{"Scheme":"","Opaque":"","User":null,"Host":"","Path":"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo","RawPath":"","ForceQuery":false,"RawQuery":"","Fragment":""},"ClientAddr":"x.x.x.x:64391","ClientHost":"x.x.x.x","ClientPort":"64391","ClientUsername":"-","DownstreamContentSize":0,"DownstreamStatus":500,"DownstreamStatusLine":"500 Internal Server Error","Duration":426232,"FrontendName":"Auth for frontend-public-tag-service-public","OriginContentSize":0,"OriginDuration":222656,"OriginStatus":500,"OriginStatusLine":"500 Internal Server Error","Overhead":203576,"RequestAddr":"serviceA-grpc.traefik.dev.pap:443","RequestContentSize":0,"RequestCount":14,"RequestHost":"serviceA-grpc.traefik.dev.pap","RequestLine":"POST /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo HTTP/2.0","RequestMethod":"POST","RequestPath":"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo","RequestPort":"443","RequestProtocol":"HTTP/2.0","RetryAttempts":0,"StartLocal":"2019-05-24T20:24:24.216358162Z","StartUTC":"2019-05-24T20:24:24.216358162Z","level":"info","msg":"","request_Content-Type":"application/grpc","request_Te":"trailers","request_User-Agent":"grpc-go/1.19.0","time":"2019-05-24T20:24:24Z"}
{"BackendAddr":"","BackendName":"Traefik","BackendURL":{"Scheme":"","Opaque":"","User":null,"Host":"","Path":"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo","RawPath":"","ForceQuery":false,"RawQuery":"","Fragment":""},"ClientAddr":"x.x.x.x:64391","ClientHost":"x.x.x.x","ClientPort":"64391","ClientUsername":"-","DownstreamContentSize":0,"DownstreamStatus":500,"DownstreamStatusLine":"500 Internal Server Error","Duration":398352,"FrontendName":"Auth for frontend-public-tag-service-public","OriginContentSize":0,"OriginDuration":142857,"OriginStatus":500,"OriginStatusLine":"500 Internal Server Error","Overhead":255495,"RequestAddr":"serviceA-grpc.traefik.dev.pap:443","RequestContentSize":0,"RequestCount":15,"RequestHost":"serviceA-grpc.traefik.dev.pap","RequestLine":"POST /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo HTTP/2.0","RequestMethod":"POST","RequestPath":"/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo","RequestPort":"443","RequestProtocol":"HTTP/2.0","RetryAttempts":0,"StartLocal":"2019-05-24T20:24:24.297632103Z","StartUTC":"2019-05-24T20:24:24.297632103Z","level":"info","msg":"","request_Content-Type":"application/grpc","request_Te":"trailers","request_User-Agent":"grpc-go/1.19.0","time":"2019-05-24T20:24:24Z"}

Если я выполню grpcurl -plaintext docker-swarm-worker-01.dev.pap:50061 list, я получу список услуг, которым могу позвонить. Может кто-то помочь мне, пожалуйста?

1 Ответ

1 голос
/ 27 мая 2019

Мне удалось заставить его работать! Кажется, что проблема заключалась в перенаправлении http на https и базовой аутентификации http, которую я использовал.

Файл конфигурации Traefik.toml теперь проще:

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
    address = ":80"
    compress = true
  [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/certs/certfile.cert"
      keyFile = "/certs/keyfile.key"

  [entryPoints.api]
    address = ":8081"
  [entryPoints.ping]
    address = ":8082"

[api]
  entryPoint = "api"
  dashboard = true

[ping]
  entryPoint = "ping"

[retry]

[traefikLog]
  format   = "json"

[accessLog]
  format = "json"

[docker]
  endpoint = "unix:///var/run/docker.sock"
  domain = "traefik.dev.pbp"
  swarmmode = true
  watch = true
  exposedByDefault = false
  insecureSkipVerify = true

Теперь я могу подключиться к моей службе grpc, работающей на Docker Swarm, через Traefik!

...