Traefik 이라는, golang 을 사용해 만들어진 경량의 고성능 웹 서버가 무서운 속도로 급성장하고 있습니다.
NGINX 와는 달리 마이크로서비스를 쉽게 운영할 수 있도록 고려하여 개발되었기 때문에 Docker Swarm , Kubernetes 와 같은 Container Orchestration 도구와 함께 사용하기에 편리합니다.
직접 사용하면서 느낀 점은 NGINX on Docker 와는 달리 Let's encrypt와 같은 Issuer를 사용한 TLS 구현이 이미 내장되어 있어 적용이 매우 쉬웠고(발급 과정 없이 설정만 정의하면 발급과 재발급을 알아서 처리합니다.) 공식 도큐먼트가 잘 되어 있어 별도의 블로그를 참조할 필요가 없다는 점이었습니다.
호스트의 8080 , 8081 포트에 애플리케이션을 올려 Reverse-Proxy 예제를 진행해 보겠습니다.
Traefik 설정 파일 구성traefik.yml 을 적당한 곳에 작성합니다. 저는 ~/docker/traefik/traefik.yml 위치에 작성하겠습니다.$ cd ~/docker
$ mkdir traefik
$ cd traefik
$ vi traefik.yml
# traefik.yml
log:
level: error
global:
checkNewVersion: true
sendAnonymousUsage: true
accessLog:
filePath: "/var/log/traefik/traefik.log"
bufferingSize: 100
filters:
statusCodes:
- "200-530"
entryPoints:
http:
address: ":80"
https:
address: ":443"
# 기본적으로 대시보드를 지원합니다
traefik:
address: ":5000"
api:
dashboard: true
insecure: true
providers:
docker:
exposedByDefault: false
swarmMode: false
endpoint: "unix:///var/run/docker.sock"
file:
watch: true
filename: "/etc/traefik/dynamic_conf.yml"
dynamic_conf.yml 을 작성하겠습니다. NGINX 의 sites-available 과 비슷해 보입니다.$ vi dynamic_conf.yml
# dynamic_conf.yml
http:
services:
greeting:
loadBalancer:
servers:
- url: "http://host.docker.internal:8080"
- url: "http://host.docker.internal:8081"
routers:
# 대시보드용 라우팅
traefik-api:
entryPoints: ["traefik"]
rule: "PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
service: api@internal
# NGINX 의 location 에 해당
greeting-http:
entryPoints:
- http
rule: "Host(`{domain}`)"
service: greeting
rule 구현이 있어 복잡한 라우팅도 쉽게 매핑할 수 있어 보입니다. TLS 구현에 필요한 acme.json 파일도 생성해 줍니다. 해당 파일은 Traefik 이 사용하므로 빈 파일만 만들어 두면 됩니다.$ touch acme.json
$ sudo chmod 600 acme.json
docker-compose 파일 작성docker-compose.yml 파일을 생성합니다.$ cd ~/docker
$ vi docker-compose.yml
# docker-compose.yml
version: "3.3"
services:
reverse-proxy:
image: traefik:v2.7.0
container_name: reverse-proxy
restart: always
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/etc/localtime:/etc/localtime:ro"
- "./traefik/traefik.yml:/etc/traefik/traefik.yml:ro"
- "./traefik/dynamic_conf.yml:/etc/traefik/dynamic_conf.yml"
- "./traefik/acme.json:/etc/traefik/acme.json"
ports:
- "80:80"
- "443:443"
- "5000:5000" # dashboard
docker-compose 를 올리게 되면 도메인을 통해 호스트에 서비스 중인 8080, 8081 애플리케이션의 index 를 볼 수 있습니다.Let's Encrypt 를 통한 TLS 구현traefik.yml 에 certificate resolver 를 먼저 정의해야 합니다.$ cd ~/docker/traefik
$ vi traefik.yml
# traefik.yml
# 가장 마지막에 추가합니다.
certificatesResolvers:
letsencrypt:
acme:
email: [YOUR_EMAIL]
storage: "/etc/traefik/acme.json"
httpChallenge:
entryPoint: "http"
dynamic_conf.yml 에 TLS 를 사용한다는 선언이 필요합니다.$ vi dynamic_conf.yml
# dynamic_conf.yml
http:
services:
greeting:
loadBalancer:
servers:
- url: "http://host.docker.internal:8080"
- url: "http://host.docker.internal:8081"
routers:
traefik-api:
entryPoints: ["traefik"]
rule: "PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
service: api@internal
greeting-http:
entryPoints:
- http
rule: "Host(`{domain}`)"
service: greeting
middlewares:
# http 접근인 경우 https 로 보냅니다
- redirect_to_https
greeting-https:
entryPoints:
- https
rule: "Host(`{domain}`)"
service: greeting
middlewares:
- web_rate_limit
# TLS 를 사용합니다
tls:
certResolver: letsencrypt
# 여러 도메인에 적용하고 싶은 경우
# domains:
# - main: example.org
# sans:
# - "*.example.org"
middlewares:
web_rate_limit:
rateLimit:
average: 16
burst: 32
redirect_to_https:
redirectScheme:
scheme: https
permanent: true
docker-compose 명령어로 컨테이너를 재시작하고 조금 기다리면 인증서가 발급되며 acme.json 파일에 인증서, 비밀키가 저장됩니다.해당 포스트는 Traefik 및 Traefik with letsencrypt 깃허브 를 참고하여 작성되었습니다.