Traefik 기초 (with docker)

재필님에게 배울적만해도 version 1 이었던 것 같은데.. 2.0 버전으로 테스트를 한다.

Traefik 은 Service Discovery 와 Routing 을 수행하는 Reverse Proxy 이다.

  • Edge Router : service 의 맨 앞에서 어떤 request 가 어떤 service 로 처리될 지 결정한다(routing)
  • Auto Service Discovery : 전통적으로 reverse proxy 는 모든 route 설정을 설정정보로 갖고 있지만, Traefik 은 그런 정보를 service 들에게서 받는다.(provider 에게 api 호출을 한다) service 를 배포할 때, Traefik 이 사용할 수 있는 추가 정보를 더함으로 써 Traefik 이 해당 정보로 route 를 가능하게 한다.

Routing & Load Balancing

음 컨셉에 대해 좀 더 쓰려고했지만 너무 귀찮아졌다. 그리고 공식홈에 너무 잘 설명이 되어있어서..

  • Providers discover the services that live on your infrastructure (their IP, health, …)
    • 서비스 오케스트레이터
  • Entrypoints listen for incoming traffic (ports, …)
    • 외부의 요청에대해 Traefik 이 listen 하는 지점.
  • Routers analyse the requests (host, path, headers, SSL, …)
    • 어떤 rule 에 따라 어떤 service 에 request 를 route 할지.
  • Services forward the request to your services (load balancing, …)
    • request 를 처리할 수 있는 application.
  • Middlewares may update the request or make decisions based on the request (authentication, rate limiting, headers, …)
  • request 를 service 에 route 하기 전에 전/후처리하는 기능들

Supported Providers

설정

Traefik 의 설정은 두 가지가 있다.

  1. static configuration - startup time - 기동 시 설정
    • 로그설정, entrypoint 설정, metric 설정 등…
  2. dynamic configuration - while running - 런타임 설정
    • service, route rule, 등 provider 에게서 받는 정보들로 구성.

static configuration

static configuration 은 세가지 방법이 있고 우선순위는 다음과 같다.

  1. In a configuration file - 설정 파일
  2. In the command-line arguments - 실행 인자
  3. As environment variables - 환경 변수

우선 순위가 높은 설정이 하나라도 발견되면 낮은 우선 순위의 설정은 모두 무시된다.

mutually exclusive (e.g. you can use only one at the same time)

dynamic configuration

dynamic configurationprovider 로부터 설정을 받아온다.

docker 를 provider 로 사용할 경우, contianer label 을 통해서 설정을 한다. 그리고 container label 을 붙일 때는 ` backtick 이나 \" escaped double-quotes을 사용해야한다. Traefik 이 Golang 으로 만들어져 있는데, Golang 에는 ' Single quotes 가 string literal 이 아니란다.

Swarm mode

  • Swarm mode 에서는 label 을 delpoy 쪽에 넣어야한다.

    Therefore, if you use a compose file with Swarm Mode, labels should be defined in the deploy part of your service.

  • 포트 또한 label 에 적어줘야한다.

    Therefore you must specify the port to use for communication by using the label

  • Traefik 노드 또한 매니져에 배치해야한다.

    As the Swarm API is only exposed on the manager nodes, you should schedule Traefik on the Swarm manager nodes by default

docker-compose-traefik.yaml

#도커 컴포즈의 버전
version: '3'

volumes:
  #포테이너의 도커 볼륨 설정
  portainer_data: {}

services:

  reverse-proxy:
    image: traefik:v2.0
    #command: --accesslog=true --api.insecure=true --providers.docker --entrypoints.web.address=:80 --entrypoints.myportainer.address=:9000
    #command 와 environment 는 mutually exclusive 하다.
    environment:
      - TRAEFIK_ACCESSLOG=true #로그 사용
      - TRAEFIK_METRICS_PROMETHEUS=true #metric prometheus 사용
      - TRAEFIK_API_INSECURE=true #traefik 8080 api web ui 사용
      - TRAEFIK_PROVIDERS_DOCKER=true #provider docker 사용
      #entrypoint 설정들
      #TRAEFIK_ENTRYPOINTS_<ENTRYPOINT_NAME>_ADDRESS
      - TRAEFIK_ENTRYPOINTS_WEB_ADDRESS=:80
      - TRAEFIK_ENTRYPOINTS_MYPROMETHEUS_ADDRESS=:9090
      - TRAEFIK_ENTRYPOINTS_MYGRAFANA_ADDRESS=:3000
      - TRAEFIK_ENTRYPOINTS_NODEEXPORTER_ADDRESS=:9100
      - TRAEFIK_ENTRYPOINTS_MYPORTAINER_ADDRESS=:9000
    #entrypoint 들은 expose 해줘야한다.
    ports:
      - "80:80"
      - "8080:8080"
      - "9090:9090"
      - "3000:3000"
      - "9100:9100"
      - "9000:9000"
    volumes:
      #docker provider 사용
      - /var/run/docker.sock:/var/run/docker.sock
      #static configuration file 을 사용한다면 아래처럼 사용하면 된다.
      #- <MY-STATIC-CONFIGURATION-FILE-LOCATION>:/etc/traefik/traefik.yaml #traefik static config
      #- ./traefik-stack.yaml:/etc/traefik/traefik.yaml #예시

  prometheus:
    image: prom/prometheus
    volumes:
      #로컬 설정파일
      - /home/ec2-user/prometheus.yml:/etc/prometheus/prometheus.yml
    labels:
      #http router <myprometheus> 설정
      #  - request 가 myprometheus entrypoint 로 들어오면서 (소문자로 변형되나봄)
      #  - header 에 Host:CUSTOM.USER.DOMAIN.COM 일 때,
      #http service <myprometheus> 설정
      #  - http service 이기 때문에 http://<service-private-ip>:9090 으로 매핑
      - "traefik.http.routers.myprometheus.rule=Host(`CUSTOM.USER.DOMAIN.COM`)"
      - "traefik.http.routers.myprometheus.entrypoints=myprometheus"
      - "traefik.http.services.myprometheus.loadbalancer.server.port=9090"

  grafana:
    image: grafana/grafana
    labels:
      - "traefik.http.routers.mygrafana.rule=Host(`CUSTOM.USER.DOMAIN.COM`)"
      - "traefik.http.routers.mygrafana.entrypoints=mygrafana"
      - "traefik.http.services.mygrafana.loadbalancer.server.port=3000"

  node-exporter:
    image: prom/node-exporter
    labels:
      - "traefik.http.routers.nodeexporter.rule=Host(`CUSTOM.USER.DOMAIN.COM`)"
      - "traefik.http.routers.nodeexporter.entrypoints=nodeexporter"
      - "traefik.http.services.nodeexporter.loadbalancer.server.port=9100"

  portainer:
    image: portainer/portainer
    #ports:
      #- "8000:8000"
      #- "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data portainer/portainer
    restart: always
    labels:
      - "traefik.http.routers.myportainer.rule=Host(`CUSTOM.USER.DOMAIN.COM`)"
      - "traefik.http.routers.myportainer.entrypoints=myportainer"
      - "traefik.http.services.myportainer.loadbalancer.server.port=9000"
      #- "traefik.http.routers.myportainer.middlewares=myportainer-stripprefix"
      #- "traefik.http.middlewares.myportainer-stripprefix.stripprefix.prefixes=/first"
      #- "traefik.http.middlewares.myportainer-replacepathregex.replacepathregex.regex=/p/*.c"
      #- "traefik.http.middlewares.myportainer-replacepathregex.replacepathregex.replacement=/p/$$1"
      #- "traefik.http.middlewares.myportainer-stripprefix.stripprefix.forceslash=true"
      #- "traefik.http.middlewares.myportainer-replacepath.replacepath.path=/myp"

  whoami:
    image: containous/whoami
#    ports:
#     - "82:80"
    labels:
      - "traefik.http.routers.mywhoami.rule=Path(`/second`)"
      - "traefik.http.services.mywhoami.loadbalancer.server.port=80"
      - "traefik.http.routers.mywhoami.middlewares=mywhoami-stripprefix"
      - "traefik.http.middlewares.mywhoami-stripprefix.stripprefix.prefixes=/second"

traefik static configration file example

## traefik.yml

# Docker configuration backend
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    swarmMode: true

# API and dashboard configuration
api:
  insecure: true
  dashboard: true

log:
  filePath: "/path/to/traefik.log"
  level: DEBUG #DEBUG, PANIC, FATAL, ERROR, WARN, INFO.

accessLog:
  filePath: "/path/to/access.log"
  bufferingSize: 100

entryPoints:
  web:
    address: ":80"
  my-address:
    address: ":8090"

출처