首页 > 解决方案 > 如何使用 Traefik 路由 docker(swarm)容器需要一个端口到 /myapp 之类的主机 url 的上下文?

问题描述

我的配置是 Docker Swarm。

MyWebApp 在 Container 中运行并且可以访问端口 8100。

由于某些原因,我需要 URL 访问不使用端口,而是使用 URL 上下文,如 myhost.com/mywebapp。

路由应该由 Traefik 完成。

我尝试使用 Path、PathPrefix、PathPrefixStrip,用于配置 Traefik,无论如何结果相同,我只能访问 MyWebApp,因为 URL 中的端口无法使用上下文 /mywebapp。

#startscript.sh

docker swarm init
docker network create -d overlay proxy
docker stack deploy -c docker-compose.traefik.yml traefik
docker stack deploy -c docker-compose.webapps.yml webapps

traefik.toml

accessLogsFile = "/dev/stdout"

logLevel = "DEBUG"

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
#    [entryPoints.http.redirect]
#    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      CertFile = "/run/secrets/cert.pem"
      KeyFile = "/run/secrets/key.pem"

[web]
address = ":8085"

[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "myhost.com"
watch = true
swarmmode = true
exposedbydefault = false

[file]

docker-compose-traefik.yml

version: '3.3'

networks:
  proxy:
    external:
      name: proxy

configs:
  traefik_toml_v2:
    file: ./traefik.toml

secrets:
  traefik_cert:
    file: ./tls/cert.pem
  traefik_key:
    file: ./tls/key.pem

services:
  traefik:
    image: traefik
    deploy:
      replicas: 2
      placement:
        constraints:
        - node.role == manager
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    networks:
    - proxy
    ports:
    - target: 80
      protocol: tcp
      published: 80
      mode: ingress
    - target: 443
      protocol: tcp
      published: 443
      mode: ingress
    - target: 8085
      protocol: tcp
      published: 8085
      mode: ingress
    configs:
    - source: traefik_toml_v2
      target: /etc/traefik/traefik.toml
      mode: 444
    secrets:
    - source: traefik_cert
      target: cert.pem
      uid: "0"
      mode: 400
    - source: traefik_key
      target: key.pem
      uid: "0"
      mode: 400

docker-compose-webapps.yml

version: '3.3'

networks:
  proxy:
    external: true
  net:
    driver: overlay
    attachable: true

services:
  whoami:
    image: emilevauge/whoami
    networks:
    - proxy
    deploy:
      replicas: 2
      resources:
        limits:
          memory: 1G
      labels:
#This is working - i can access with: http://myhost/whoami
      - traefik.frontend.rule=PathPrefixStrip:/whoami
      - traefik.docker.network=proxy
      - traefik.port=80
      - traefik.enable=true

  mywebapp:
    image: myregistry/myrepos:my_image
    networks:
    - proxy
    - net
    ports:
    - 8100:8100
    volumes:
    - ~/dev/myconf:/home/developer/dev/myconf 
    command: mywebapp.bin --http-address=0.0.0.0 --http-port=8100
    deploy:
      replicas: 2
      resources:
        limits:
          memory: 1G
      labels:
      - traefik.enable=true
#This is NOT working - i canNOT access with: http://myhost/webapp
#Access is only possible with: http://myhost:8100
#WHAT I HAVE TO DO THAT i can forward/redirect http://myhost:8100 to http://myhost/webapp????
#      - traefik.frontend.rule=Host:myhost.com;Path:/mywebapp
#      - traefik.port=8100
#I tried both, with servicename and without servicename, in both cases access to http://myhost/webapp is not possible, only to http://myhost:8100
      - traefik.webapps_mywebapp.frontend.rule=Host:myhost.com;Path:/mywebapp
      - traefik.webapps_mywebapp.port=8100
      - traefik.docker.network=proxy

标签: docker-swarmtraefik

解决方案


我要试一试。

首先,您向外部连接打开了 docker 容器端口:

ports:
  - 8100:8100

这就是您可以通过端口访问 URL 的原因。因此,当您通过http://url:8100访问它时,您实际上是在绕过 traefik 并直接连接到容器。

如果您将其设置为 EXPOSE,则它应该只对 docker 网络开放。

expose:
  - "8100"

(在此处参考此链接:docker-compose ports 与 expose 之间有什么区别

现在谈谈您的 Traefik 连接问题,我明白您无法访问的原因之一是因为您的前端规则错误:

labels:    
  - traefik.frontend.rule=Host:myhost.com;Path:/mywebapp

拥有主机规则将要求您将额外信息添加到请求的标头中。您不能只调用 URL。

对于 Path,我不确定那是做什么的,但对我来说它只是发送 404。

您需要将 PathPrefixStrip 设置为唯一的前端规则:

labels:    
  - traefik.frontend.rule=PathPrefixStrip:/mywebapp

我遇到了同样的问题。这是一个对我有用的 docker-compose 块的示例:

cherrypy-helloworld:
  build:
    dockerfile: cherrypy_helloworld.Dockerfile
  expose:
    - "8080"
  volumes:
    - $PWD/cherrypy_helloworld:/pyapp
  labels:
    - traefik.frontend.rule=PathPrefixStrip:/apitest
    - traefik.enable=true

希望这可以帮助。


推荐阅读