dev.to

Traefik 3.7's service middlewares target one branch of a weighted service

Traefik 3.7 서비스 미들웨어로 가중 서비스의 특정 분기만 처리하기

Traefik 3.7은 미들웨어를 서비스에 붙여 가중 서비스의 특정 백엔드에만 적용합니다. 다만 블로그 예제와 달리 middlewares는 loadBalancer 안이 아니라 서비스 바로 아래에 둬야 합니다. 글은 9:1 분기 테스트로 적용 범위와 실행 순서를 확인하고, 설정 오류와 API의 사용처 표시 문제도 짚습니다.

에디터 노트

이 사례에서 가장 확실한 결과는 설정 위치에 따라 라우트 전체가 실패할 수 있다는 점입니다. 블로그 예제의 필드 위치와 실제 구조체가 달랐고, 글쓴이는 수정한 설정을 3.7.14에서 시험해 분기별 헤더 적용과 미들웨어 순서를 확인했습니다. 다만 200건과 500건의 테스트는 해당 구성에서 관찰한 결과이며, 모든 부하나 설정에서 같은 분배 패턴을 보장한다는 자료는 없습니다. 사용처 API도 전역 목록만 보면 서비스 미들웨어가 연결되지 않은 것처럼 보이므로 서비스별 조회 결과와 구분해서 읽어야 합니다.

AI 요약

Traefik 3.7의 서비스 미들웨어는 라우터가 백엔드를 선택한 뒤 실행됩니다. 따라서 안정 버전과 카나리 버전을 가중 서비스로 나눈 경우, 카나리 서비스에만 헤더를 붙이는 식으로 분기별 처리가 가능합니다. 글쓴이는 Traefik 공식 발표 글의 YAML 예제를 그대로 적용했지만 라우트 설정에 실패했고, 원인이 기능 비활성화가 아니라 예제의 들여쓰기 위치였다고 설명합니다.

설정 위치와 동작 확인

공식 블로그 예제는 middlewares를 loadBalancer 안에 둡니다. 그러나 Traefik 3.7.14의 Go 구조체에서 middlewares 필드는 Service에 있고 ServersLoadBalancer에는 없습니다. 따라서 설정은 loadBalancer와 같은 단계, 서비스 아래에 작성해야 합니다. 수정한 설정은 별도 플래그 없이 시작됐습니다.

글쓴이는 두 백엔드를 9:1 가중치로 구성하고 카나리 쪽에 X-Canary: true를 설정했습니다. 순차 요청 200건에서는 안정 백엔드가 180건, 카나리가 20건을 처리했습니다. 헤더는 카나리 요청 20건 모두에 있었고 안정 요청 180건에는 없었습니다. 50개씩 병렬로 보낸 500건에서도 450 대 50으로 나뉘었고 헤더가 다른 분기로 새지 않았습니다.

요청별 백엔드 선택은 무작위 추출이 아니라 일정한 패턴을 반복했습니다. 글에서 관찰한 패턴은 대략 안정 서비스 9회 뒤 카나리 서비스 1회가 오는 형태입니다. 그래서 적은 요청만 손으로 보내면 카나리 요청을 한 번도 만나지 못할 수 있습니다. 가중치가 10%라는 사실만으로 각 요청이 독립적인 확률 추첨을 거친다고 해석할 수는 없습니다.

미들웨어 순서와 설정 오류

라우터 미들웨어는 X-Trace: router를 설정하고 카나리 서비스 미들웨어는 X-Trace: service로 덮어쓰도록 했습니다. 500건 모두에서 안정 분기는 router 값을, 카나리 분기는 service 값을 백엔드에 전달했습니다. 글쓴이는 이 결과로 라우터 미들웨어 다음에 서비스 미들웨어가 실행된다고 확인했습니다.

가중 서비스의 자식 항목 안에 middlewares를 직접 넣는 설정도 시험했습니다. 해당 항목을 표현하는 WRRService 구조체에는 Middlewares 필드가 없어 field not found 오류가 발생합니다. 이 오류는 해당 미들웨어만 무시하지 않습니다. 파일 제공자 설정 전체가 실패하므로 그 제공자가 관리하는 다른 라우터의 설정 갱신도 영향을 받습니다. 가중 서비스의 분기별 미들웨어를 쓰려면 카나리 분기를 canary-svc처럼 독립 서비스로 선언한 뒤 그 서비스에 미들웨어를 지정해야 합니다.

같은 설정을 기능 도입 전 버전인 Traefik 3.6.25에서도 시험하자 동일한 오류가 났습니다. 3.6은 새 설정을 무시하고 나머지를 적용하는 대신 파일 제공자 설정을 불러오지 못합니다.

API에서 확인할 때의 차이

글쓴이는 /api/http/middlewares 응답의 usedBy 항목도 확인했습니다. 카나리 서비스에 붙어 실제 요청을 처리하는 canary-header와 service-trace가 이 목록에서는 usedBy: None으로 나왔습니다. 반면 라우터에 붙인 router-trace는 라우터 이름이 표시됐습니다. 해당 목록이 서비스에 직접 연결된 미들웨어 사용처를 추적하지 못한 셈입니다. /api/http/services/canary-svc@file의 응답에는 두 서비스 미들웨어가 표시되므로 서비스별 API에서 연결 상태를 확인해야 합니다.

원문: dev.to / 번역·요약: Trawling