Traefik Docker Swarm 라우팅 문서
본문
Traefik & Docker Swarm
Traefik의 가장 좋은 기능 중 하나는 라우팅 구성을 애플리케이션 레벨에 위임하는 것이에요. Docker Swarm에서는 Traefik이 서비스에 붙은 라벨을 활용해 라우팅 규칙을 생성할 수 있어요.
라벨과 민감 데이터
라벨에 민감 데이터(인증서, 자격 증명 등)를 저장하지 않는 것을 권장해요. 대신 민감 데이터는 더 안전한 저장소(secret, 파일 등)에 보관하는 것을 권장해요.
설정 예시
Docker Swarm 구성 & 서비스 하나 배포/노출하기 docker 프로바이더 (Swarm 모드) 활성화하기
Structured (YAML)
providers:
swarm:
# swarm classic (1.12-)
# endpoint: "tcp://127.0.0.1:2375"
# docker swarm mode (1.12+)
endpoint: "tcp://127.0.0.1:2377"
Structured (TOML)
[providers.swarm]
# swarm classic (1.12-)
# endpoint = "tcp://127.0.0.1:2375"
# docker swarm mode (1.12+)
endpoint = "tcp://127.0.0.1:2377"
CLI
# swarm classic (1.12-)
# --providers.swarm.endpoint=tcp://127.0.0.1:2375
# docker swarm mode (1.12+)
--providers.swarm.endpoint=tcp://127.0.0.1:2377
Swarm 모드에서는 (컨테이너가 아니라) 서비스에 라벨을 붙여요 (Docker compose 파일에서). 서비스가 하나뿐이고 라우터가 서비스를 지정하지 않으면, 그 서비스가 라우터에 자동으로 할당돼요.
services:
my-container:
deploy:
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
- traefik.http.services.my-container-service.loadbalancer.server.port=8080
Docker Swarm 모드의 라벨
Swarm 모드에서 Traefik은 개별 컨테이너가 아니라 서비스에 있는 라벨을 사용해요.
따라서 Swarm 모드로 compose 파일을 사용한다면 라벨은 서비스의 deploy 부분에 정의해야 해요.
이 동작은 docker-compose 버전 3+ 에서만 활성화돼요 (Compose 파일 참조).
컨테이너에 사용자 지정 포트 지정하기
http://example.com 에 대한 요청을 http://:12345 로 전달해요:
services:
my-container:
# ...
deploy:
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
- traefik.http.routers.my-container.service=my-service"
# Tell Traefik to use the port 12345 to connect to `my-container`
- traefik.http.services.my-service.loadbalancer.server.port=12345
Traefik이 잘못된 포트에 연결: HTTP/502 Gateway Error
기본적으로 Traefik은 Swarm 프로바이더의 포트 감지에 설명된 대로 컨테이너의 가장 낮은 노출 포트를 사용해요. Swarm 프로바이더의 포트 감지.
traefik.http.services.xxx.loadbalancer.server.port 라벨을 설정하면
이 동작이 재정의돼요.
컨테이너당 여러 개의 라우터와 서비스 지정하기 컨테이너의 둘 이상의 포트로 요청을 전달하려면 라우터의 service 매개변수를 사용해 서비스 로드밸런서 포트 정의를 참조해야 해요.
이 예시에서는 http://example-a.com 요청을 http://:8000 으로, http://example-b.com 요청을 http://:9000 으로 전달해요:
services:
my-container:
# ...
deploy:
labels:
- traefik.http.routers.www-router.rule=Host(`example-a.com`)
- traefik.http.routers.www-router.service=www-service
- traefik.http.services.www-service.loadbalancer.server.port=8000
- traefik.http.routers.admin-router.rule=Host(`example-b.com`)
- traefik.http.routers.admin-router.service=admin-service
- traefik.http.services.admin-service.loadbalancer.server.port=9000
설정 옵션
Labels
라벨은 대소문자를 구분하지 않아요.
TLS 기본 생성 인증서
Traefik 기본 생성 인증서를 구성하는 방법은 TLS 인증서 페이지를 참고하세요.
일반
Traefik은 각 컨테이너에 대해 해당하는 서비스와 라우터를 생성해요.
서비스는 컨테이너의 인스턴스마다 자동으로 서버를 가지며,
라우터에는 defaultRule 이 정의한 규칙이 자동으로 적용돼요 (라벨에 그 규칙이 정의되지 않은 경우).
Service 정의
일반적으로 Traefik 프로바이더를 구성할 때, 라우팅이 동작하려면 하나(또는 여러 개)의 라우터에 할당된 서비스도 정의되어 있어야 해요.
하지만 라벨 기반 구성을 사용할 때는 예외가 있어요:
-
라벨이 라우터를 정의하고(예: router Rule을 통해) 라벨이 서비스를 정의하는데(예: 로드밸런서 서버 포트 값을 통해 암시적으로), 라우터가 어떤 서비스도 지정하지 않으면, 그 서비스가 라우터에 자동으로 할당돼요.
-
라벨이 라우터를 정의하고(예: router Rule을 통해) but no service is defined, 서비스가 자동으로 생성되어 라우터에 할당돼요.
예상할 수 있듯이 이 두 경우 모두에서 라우터에 서비스가 추가로 지정되어 있으면, 실제로 정의되어 있는지 다른 서비스가 정의되어 있는지와 무관하게 그 서비스가 할당돼요.
라벨로 서비스 자동 할당 compose 파일의 라벨로
labels:
- "traefik.http.routers.myproxy.rule=Host(`example.net`)"
# service myservice gets automatically assigned to router myproxy
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
라벨로 서비스 자동 생성 및 할당 compose 파일의 라벨로
labels:
# no service specified or defined and yet one gets automatically created
# and assigned to router myproxy.
- "traefik.http.routers.myproxy.rule=Host(`example.net`)"
Router
컨테이너에 자동으로 연결된 Router의 구성을 업데이트하려면,
traefik.http.routers.. 으로 시작하고 변경할 옵션이 뒤따르는 라벨을 추가하세요.
예를 들어 규칙을 변경하려면 traefik.http.routers.my-container.rule=Host(example.com) 라벨을 추가하면 돼요.
라우터 이름 ** 에는 @ 문자가 허용되지 않아요.
설정 옵션
| Label | Description | Value |
| traefik.http.routers..rule | 자세한 내용은 rule을 참고하세요. | Host(example.com) |
| traefik.http.routers..ruleSyntax | 자세한 내용은 ruleSyntax를 참고하세요. RuleSyntax 옵션은 더 이상 사용되지 않으며 다음 메이저 버전에서 제거될 예정이에요. 이 필드를 사용하지 말고 라우터 규칙을 v3 문법으로 다시 작성해 주세요. | v3 |
| traefik.http.routers..entrypoints | 자세한 내용은 엔트리 포인트를 참고하세요. | ep1,ep2 |
| traefik.http.routers..middlewares | 자세한 내용은 미들웨어 개요를 참고하세요. | auth,prefix,cb |
| traefik.http.routers..service | 자세한 내용은 서비스를 참고하세요. | myservice |
| traefik.http.routers..tls | 자세한 내용은 tls를 참고하세요. | true |
| traefik.http.routers..tls.certresolver | 자세한 내용은 certResolver를 참고하세요. | myresolver |
| traefik.http.routers..tls.domains[n].main | 자세한 내용은 도메인을 참고하세요. | example.org |
| traefik.http.routers..tls.domains[n].sans | 자세한 내용은 도메인을 참고하세요. | test.example.org,dev.example.org |
| traefik.http.routers..tls.options | 자세한 내용은 TLS 옵션을 참고하고, 여러 라우터가 같은 호스트 이름을 제공할 때는 TLS 옵션 충돌을 참고하세요. | foobar |
| traefik.http.routers..observability.accesslogs | accessLogs 옵션은 라우터가 액세스 로그를 생성할지 여부를 제어해요. | true |
| traefik.http.routers..observability.metrics | metrics 옵션은 라우터가 메트릭을 생성할지 여부를 제어해요. | true |
| traefik.http.routers..observability.tracing | tracing 옵션은 라우터가 트레이스를 생성할지 여부를 제어해요. | true |
| traefik.http.routers..priority | 자세한 내용은 우선순위를 참고하세요. | 42 |
Service
컨테이너에 자동으로 연결된 Service의 구성을 업데이트하려면,
traefik.http.services.. 으로 시작하고 변경할 옵션이 뒤따르는 라벨을 추가하세요.
예를 들어 passHostHeader 동작을 변경하려면,
traefik.http.services..loadbalancer.passhostheader=false 라벨을 추가하면 돼요.
서비스 이름 ** 에는 @ 문자가 허용되지 않아요.
설정 옵션
| Label | Description | Value |
| traefik.http.services..loadbalancer.server.port | 포트를 등록해요. 컨테이너가 여러 포트를 노출할 때 유용해요. Docker Swarm에는 필수예요 ("Port Detection with Docker Swarm" 섹션 참고). | 8080 |
| traefik.http.services..loadbalancer.server.scheme | 기본 스킴을 재정의해요. | http |
| traefik.http.services..loadbalancer.server.url | 서비스 URL을 정의해요. 이 옵션은 port 나 scheme 정의와 함께 사용할 수 없어요. | http://foobar:8080 |
| traefik.http.services..loadbalancer.server.weight | 기본 가중치를 재정의해요. | 42 |
| traefik.http.services..loadbalancer.serverstransport | 파일 프로바이더나 Kubernetes CRD 프로바이더로 정의된 ServersTransport 리소스를 참조할 수 있게 해줘요. 자세한 내용은 serverstransport를 참고하세요. | foobar@file |
| traefik.http.services..loadbalancer.passhostheader | | true |
| traefik.http.services..loadbalancer.healthcheck.headers. | 자세한 내용은 헬스 체크를 참고하세요. | foobar |
| traefik.http.services..loadbalancer.healthcheck.hostname | 자세한 내용은 헬스 체크를 참고하세요. | example.org |
| traefik.http.services..loadbalancer.healthcheck.interval | 자세한 내용은 헬스 체크를 참고하세요. | 10s |
| traefik.http.services..loadbalancer.healthcheck.unhealthyinterval | 자세한 내용은 헬스 체크를 참고하세요. | 10s |
| traefik.http.services..loadbalancer.healthcheck.path | 자세한 내용은 헬스 체크를 참고하세요. | /foo |
| traefik.http.services..loadbalancer.healthcheck.method | 자세한 내용은 헬스 체크를 참고하세요. | foobar |
| traefik.http.services..loadbalancer.healthcheck.status | 자세한 내용은 헬스 체크를 참고하세요. | 42 |
| traefik.http.services..loadbalancer.healthcheck.port | 자세한 내용은 헬스 체크를 참고하세요. | 42 |
| traefik.http.services..loadbalancer.healthcheck.scheme | 자세한 내용은 헬스 체크를 참고하세요. | http |
| traefik.http.services..loadbalancer.healthcheck.timeout | 자세한 내용은 헬스 체크를 참고하세요. | 10s |
| traefik.http.services..loadbalancer.healthcheck.followredirects | 자세한 내용은 헬스 체크를 참고하세요. | true |
| traefik.http.services..loadbalancer.sticky.cookie | | true |
| traefik.http.services..loadbalancer.sticky.cookie.httponly | | true |
| traefik.http.services..loadbalancer.sticky.cookie.name | | foobar |
| traefik.http.services..loadbalancer.sticky.cookie.path | | /foobar |
| traefik.http.services..loadbalancer.sticky.cookie.secure | | true |
| traefik.http.services..loadbalancer.sticky.cookie.samesite | | none |
| traefik.http.services..loadbalancer.responseforwarding.flushinterval | 자세한 내용은 응답 전달을 참고하세요. | 10 |
Middleware
traefik.http.middlewares.. 으로 시작하는 라벨을 사용해 미들웨어를 선언할 수 있어요.
그 뒤에 미들웨어 타입/옵션이 이어져요.
예를 들어 my-redirect 라는 이름의 redirectscheme 미들웨어를 선언하려면,
traefik.http.middlewares.my-redirect.redirectscheme.scheme=https 라고 쓰면 돼요.
사용 가능한 미들웨어에 대한 자세한 내용은 전용 미들웨어 섹션을 참고하세요.
미들웨어 이름에는 @ 문자가 허용되지 않아요.
미들웨어 선언 및 참조하기
services:
my-container:
# ...
deploy:
labels:
# Declaring a middleware
- traefik.http.middlewares.my-redirect.redirectscheme.scheme=https
# Referencing a middleware
- traefik.http.routers.my-container.middlewares=my-redirect
선언 충돌
이름은 같은데 매개변수가 다른 미들웨어를 여러 개 선언하면 미들웨어 선언이 실패해요.
TCP
라벨을 사용해 TCP Router 및/또는 Service를 선언할 수 있어요.
TCP Router와 Service 선언하기
services:
my-container:
# ...
deploy:
labels:
- "traefik.tcp.routers.my-router.rule=HostSNI(`example.com`)"
- "traefik.tcp.routers.my-router.tls=true"
- "traefik.tcp.services.my-service.loadbalancer.server.port=4123"
TCP와 HTTP
TCP Router/Service를 선언하면 Traefik이 HTTP Router/Service를 자동으로 생성하는 것을 막아요 (TCP Router/Service가 정의되지 않으면 기본적으로 생성하듯이요). 같은 컨테이너에 TCP Router/Service와 HTTP Router/Service를 모두 선언할 수 있어요 (단, 수동으로 해야 해요).
TCP Router
설정 옵션
| Label | Description | Value |
| traefik.tcp.routers..entrypoints | 자세한 내용은 엔트리 포인트를 참고하세요. | ep1,ep2 |
| traefik.tcp.routers..rule | 자세한 내용은 rule을 참고하세요. | HostSNI(example.com) |
| traefik.tcp.routers..ruleSyntax | 라우터별로 규칙을 파싱하는 데 사용할 규칙 문법을 구성해요. RuleSyntax 옵션은 더 이상 사용되지 않으며 다음 메이저 버전에서 제거될 예정이에요. 이 필드를 사용하지 말고 라우터 규칙을 v3 문법으로 다시 작성해 주세요. | v3 |
| traefik.tcp.routers..service | 자세한 내용은 서비스를 참고하세요. | myservice |
| traefik.tcp.routers..tls | 자세한 내용은 TLS를 참고하세요. | true |
| traefik.tcp.routers..tls.certresolver | 자세한 내용은 certResolver를 참고하세요. | myresolver |
| traefik.tcp.routers..tls.domains[n].main | 자세한 내용은 TLS를 참고하세요. | example.org |
| traefik.tcp.routers..tls.domains[n].sans | 자세한 내용은 TLS를 참고하세요. | test.example.org,dev.example.org |
| traefik.tcp.routers..tls.options | 자세한 내용은 TLS를 참고하세요. | mysoptions |
| traefik.tcp.routers..tls.passthrough | 자세한 내용은 Passthrough를 참고하세요. | true |
| traefik.tcp.routers..priority | 자세한 내용은 우선순위를 참고하세요. | 42 |
TCP Service
설정 옵션
| Label | Description | Value |
| traefik.tcp.services..loadbalancer.server.port | 애플리케이션의 포트를 등록해요. | 423 |
| traefik.tcp.services..loadbalancer.server.tls | 백엔드와 다이얼할 때 TLS를 사용할지 여부를 결정해요. | true |
| traefik.tcp.services..loadbalancer.serverstransport | 파일 프로바이더나 Kubernetes CRD 프로바이더로 정의된 ServersTransport 리소스를 참조할 수 있게 해줘요. 자세한 내용은 serverstransport를 참고하세요. | foobar@file |
TCP Middleware
You can declare pieces of middleware using tags starting with traefik.tcp.middlewares.{name-of-your-choice}., 그 뒤에 미들웨어 타입/옵션이 이어져요.
예를 들어 test-inflightconn 이라는 이름의 InFlightConn 미들웨어를 선언하려면 traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10 이라고 쓰면 돼요.
사용 가능한 미들웨어에 대한 자세한 내용은 전용 미들웨어 섹션을 참고하세요.
미들웨어 선언 및 참조하기
# ...
# Declaring a middleware
traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10
# Referencing a middleware
traefik.tcp.routers.my-service.middlewares=test-inflightconn
선언 충돌
이름은 같은데 매개변수가 다른 미들웨어를 여러 개 선언하면 미들웨어 선언이 실패해요.
UDP
라벨을 사용해 UDP Router 및/또는 Service를 선언할 수 있어요.
UDP Router와 Service 선언하기
services:
my-container:
# ...
deploy:
labels:
- "traefik.udp.routers.my-router.entrypoints=udp"
- "traefik.udp.services.my-service.loadbalancer.server.port=4123"
UDP와 HTTP
UDP Router/Service를 선언하면 Traefik이 HTTP Router/Service를 자동으로 생성하는 것을 막아요 (UDP Router/Service가 정의되지 않으면 기본적으로 생성하듯이요). 같은 컨테이너에 UDP Router/Service와 HTTP Router/Service를 모두 선언할 수 있어요 (단, 수동으로 해야 해요).
UDP Router
설정 옵션
| Label | Description | Value |
| traefik.udp.routers..entrypoints | 자세한 내용은 엔트리 포인트를 참고하세요. | ep1,ep2 |
| traefik.udp.routers..service | 자세한 내용은 서비스를 참고하세요. | myservice |
UDP Service
설정 옵션
| Label | Description | Value |
| traefik.udp.services..loadbalancer.server.port | 애플리케이션의 포트를 등록해요. | 423 |
특정 프로바이더 옵션
| Label | Description | Value |
| traefik.enable | traefik.enable 을 true 또는 false로 설정해 Traefik이 컨테이너를 고려할지(또는 하지 않을지) 지정할 수 있어요. 이 옵션은 exposedByDefault 값을 재정의해요. | true |
| traefik.swarm.network | 컨테이너에 대한 연결에 사용할 기본 docker 네트워크를 재정의해요. 컨테이너가 여러 네트워크에 연결되어 있다면 올바른 네트워크 이름을 설정해야 해요 (docker inspect 로 확인할 수 있어요). 그렇지 않으면 (docker가 반환하는 방식에 따라) 임의로 하나를 선택할 거예요. compose 파일에서 스택을 배포할 때 정의된 네트워크에는 stack 프리픽스가 붙어요. | mynetwork |
| traefik.swarm.lbswarm | Swarm의 내장 로드 밸런서를 활성화해요 (Swarm 모드에서만 관련 있음). 이 옵션을 활성화하면 Traefik은 컨테이너 IP 대신 docker swarm이 제공하는 가상 IP를 사용해요. 즉, Traefik은 어떤 종류의 로드 밸런싱도 수행하지 않고 이 작업을 swarm에 위임하게 돼요. | true |