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
의 설정은 두 가지가 있다.
- static configuration - startup time - 기동 시 설정
- 로그설정, entrypoint 설정, metric 설정 등…
- dynamic configuration - while running - 런타임 설정
- service, route rule, 등 provider 에게서 받는 정보들로 구성.
static configuration
static configuration
은 세가지 방법이 있고 우선순위는 다음과 같다.
- In a configuration file - 설정 파일
- In the command-line arguments - 실행 인자
- As environment variables - 환경 변수
우선 순위가 높은 설정이 하나라도 발견되면 낮은 우선 순위의 설정은 모두 무시된다.
mutually exclusive (e.g. you can use only one at the same time)
dynamic configuration
dynamic configuration
은 provider
로부터 설정을 받아온다.
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"
출처