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 깃허브 를 참고하여 작성되었습니다.