Traefik on Docker

Dierslair·2022년 5월 28일
1

docker

목록 보기
2/2

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 을 작성하겠습니다. NGINXsites-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 파일에 인증서, 비밀키가 저장됩니다.

해당 포스트는 TraefikTraefik with letsencrypt 깃허브 를 참고하여 작성되었습니다.

profile
Java/Kotlin Backend Developer

0개의 댓글