Docker 컨테이너 VPN 라우팅 시 포트 사라짐 해결법
Gluetun을 사용하여 컨테이너를 VPN으로 라우팅할 때 포트가 사라지는 원인을 설명합니다. 네트워크 네임스페이스 공유로 인해 발생하는 문제를 해결하고, 정상적으로 작동하는 Docker Compose 설정 파일과 올바른 포트 매핑 방법을 상세히 안내합니다.
Docker 컨테이너를 VPN으로 라우팅할 때 포트가 사라지는 이유
Docker 컨테이너를 VPN으로 라우팅하려면 한 컨테이너에 터널을 제공한 다음, network_mode: "service:gluetun"을 사용하여 다른 컨테이너들을 해당 컨테이너의 네트워크 네임스페이스에 연결해야 합니다. 이 연결 과정에서 많은 사용자가 혼란을 겪습니다. 연결된 컨테이너는 더 이상 자체 네트워크를 가지지 않으므로, 해당 컨테이너의 게시된 포트와 Docker 서비스 이름도 함께 사라집니다. 포트를 VPN 컨테이너에 게시하면 다른 컨테이너들은 VPN 컨테이너의 이름을 통해 애플리케이션에 접근할 수 있습니다.
연결된 컨테이너에 ports: 블록을 남겨두면 Docker는 해당 컨테이너 생성을 거부합니다.
Error response from daemon: conflicting options: port publishing and the container type network mode여기서 사용하는 도구는 Gluetun입니다. 이 컨테이너는 WireGuard나 OpenVPN을 통해 상용 VPN(가상 사설망) 제공업체에 연결되며 자체 방화벽을 포함합니다. 2026년 8월 기준 최신 릴리스는 v3.41.3입니다. 예제에서는 WireGuard를 사용하는 Mullvad를 기준으로 하므로, 제공업체로부터 계정과 키를 발급받아야 합니다. 만약 직접 소유한 하드웨어에서 터널을 종료하고 싶다면 VPS에서 직접 WireGuard 서버 운영하기를 통해 반대편 종단점을 구축할 수 있으며, Docker에서 wg-easy 사용하기를 통해 웹 인터페이스로 이를 관리할 수 있습니다.
network_mode: "service:gluetun"의 실제 동작 방식
모든 Docker 컨테이너는 기본적으로 고유한 네트워크 네임스페이스를 할당받습니다. 여기에는 자체 인터페이스, 라우팅 테이블, 방화벽 규칙, 리스닝 소켓이 포함됩니다. service: 모드는 이 과정을 건너뛰고 gluetun의 네임스페이스 안에서 컨테이너를 시작합니다. 하나의 네임스페이스를 공유한다는 것은 하나의 IP 주소를 사용한다는 의미이며, 이는 다음 6가지 사항을 변화시킵니다.
- 애플리케이션은 고유 주소를 갖지 않습니다. 애플리케이션의 주소는 곧 gluetun의 주소가 됩니다.
- 애플리케이션은 어떤 Docker 네트워크에도 연결되지 않으므로, 서비스 이름이 등록되지 않으며 이름 해석도 불가능합니다. 다른 컨테이너들은 반드시
gluetun를 사용해야 합니다. - 같은 네임스페이스 안의 컨테이너들은
localhost을 통해 서로 통신합니다. - 하나의 네임스페이스 안에 있는 두 컨테이너는 동일한 포트에서 리스닝할 수 없습니다. Gluetun 문서에서는 이에 대해 우회 방법이 없다고 명시하고 있습니다.
- 권한(Capabilities)은 네임스페이스가 아닌 컨테이너에 귀속됩니다. Gluetun은 터널 인터페이스를 생성하므로
NET_ADMIN와/dev/net/tun권한을 보유합니다. 하지만 연결된 컨테이너는 이를 상속받지 않습니다. - Compose는 한 서비스가
network_mode과networks을 동시에 설정한 파일을 거부합니다. gluetun을 네트워크에 연결하면, 애플리케이션은 그 네트워크를 함께 사용하게 됩니다.
gluetun을 재시작하면 여기에 연결된 모든 컨테이너의 연결이 끊어집니다. 이는 문서화된 동작 방식이며, 연결 실패 시 gluetun이 프로세스를 종료하는 대신 컨테이너 내부에서 VPN 프로세스를 재시작하는 이유이기도 합니다. 사용자가 직접 gluetun을 재시작하거나 재생성한 후에는, gluetun에 연결된 컨테이너들도 함께 재시작하십시오.
작동하는 compose 파일
services:
gluetun:
image: qmcgaw/gluetun:v3
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=mullvad
- VPN_TYPE=wireguard
- SERVER_CITIES=Amsterdam
- TZ=Europe/Amsterdam
env_file:
- ./gluetun.env
volumes:
- ./gluetun:/gluetun
ports:
- 127.0.0.1:8080:8080/tcp
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: "service:gluetun"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Amsterdam
- WEBUI_PORT=8080
volumes:
- ./qbittorrent:/config
- ./downloads:/downloads
depends_on:
gluetun:
condition: service_healthy
restart: unless-stopped:v3 태그는 v3 시리즈의 최신 안정화 릴리스입니다. :latest 태그는 master 브랜치의 마지막 커밋을 가리키며, 이는 개발 중인 최신 버전입니다. 따라서 디버깅을 원치 않는 운영 환경의 서버라면 :v3 버전을 고정하여 사용하십시오.
WEBUI_PORT=8080은 게시된 포트와 일치해야 합니다. qBittorrent는 gluetun의 네임스페이스 내부에서 바인딩되며, 게시 규칙은 호스트 트래픽을 해당 네임스페이스의 8080 포트로 전달하기 때문입니다. 두 값 중 하나라도 다르게 설정하면 포트는 응답하지 않습니다. 127.0.0.1:8080:8080는 웹 인터페이스를 호스트의 루프백 주소에 유지합니다. 단순히 8080:8080만 설정하면 모든 인터페이스에 게시되고 자체 방화벽 규칙을 작성하게 되는데, 이것이 바로 Docker 게시 포트가 ufw를 우회하는 방식입니다.
서비스를 시작한 뒤 다음 순서로 확인하십시오:
docker compose up -d
docker compose ps
docker compose logs gluetun | tail -30docker compose ps를 실행하면 gluetun은 healthy로, qbittorrent는 running으로 표시되어야 합니다. 그 다음 네임스페이스 내부에서 나가는 주소를 확인하십시오. 이 확인 과정이 나머지 모든 동작의 정상 여부를 결정합니다:
docker run --rm --network=container:gluetun alpine:3.22 sh -c "apk add wget && wget -qO- https://ipinfo.io"해당 JSON의 ip 필드에는 VPN 제공업체의 주소가 표시되어야 합니다. 만약 서버 자신의 주소가 표시된다면, 애플리케이션이 터널 내부에 있지 않은 상태이므로 이후의 모든 동작은 설명과 다르게 작동할 것입니다.
키를 compose 파일 외부에 보관하기
gluetun.env은 자격 증명을 담고 있으며, git 저장소에 포함되지 않아야 합니다.
WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU=
WIREGUARD_ADDRESSES=10.64.222.21/32두 값 모두 제공업체의 계정 영역에서 생성한 WireGuard 설정 파일에서 가져옵니다. 파일 모드를 600으로 설정하십시오. 이 방식이 제공하는 이점을 명확히 이해해야 합니다. 키가 저장소에 포함되지는 않지만, docker inspect gluetun는 Docker 소켓에 접근할 수 있는 누구에게나 모든 환경 변수를 출력할 수 있습니다. Docker Compose의 환경 파일 및 보안 정보에서 더 강력한 보안 옵션을 다룹니다.
터널 외부의 컨테이너가 내부 컨테이너와 통신하는 방법
양방향 통신이 모두 가능하며, 각 방향마다 다른 이름을 사용합니다. 두 컨테이너는 Docker 네트워크를 공유해야 합니다. 연결된 컨테이너는 자체 네트워크가 없으므로 gluetun의 네트워크를 사용하게 됩니다. Docker Compose 네트워크 연결 방식에서 기본 설정을 다룹니다.
외부에서 내부로 통신할 때는 gluetun의 이름과 애플리케이션이 수신 대기 중인 포트를 사용합니다. 리버스 프록시 컨테이너는 gluetun:8080을 통해 qBittorrent 웹 인터페이스에 접근합니다. 컨테이너 간 트래픽은 Docker 네트워크 내부에서 처리되며 호스트 포트를 거치지 않으므로, 이 경우 ports: 항목은 필요하지 않습니다.
내부에서 외부로 통신할 때는 다른 컨테이너의 서비스 이름(예: postgres:5432)을 사용합니다. gluetun은 v3.41부터 네임스페이스 내부에서 다른 컨테이너 이름을 해석할 수 있습니다. 이름 해석이 되지 않는다면 해당 버전 이상으로 고정하십시오.
gluetun의 방화벽은 연결 허용 대상을 결정합니다. gluetun 자체 Docker 네트워크에서 발생하는 트래픽은 허용됩니다. 서로 다른 서브넷에 있는 클라이언트, LAN에 연결된 노트북, 또는 별도의 브리지 네트워크에 있는 컨테이너의 트래픽은 해당 서브넷을 명시하지 않으면 차단됩니다.
FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24문서화된 의미는 정확합니다. 이는 gluetun과 그 네트워크 스택을 공유하는 컨테이너가 접근할 수 있도록 허용된 서브넷을 쉼표로 구분하여 나열하는 것입니다.
인터넷에서 들어오는 인바운드 연결은 별개의 문제입니다. 토렌트 클라이언트의 피어는 VPN 측에서 들어오므로, 호스트에서 6881 포트를 게시하는 것은 아무런 효과가 없습니다. 서비스 제공업체로부터 포트 포워딩을 받아야 하며, 해당 포트를 FIREWALL_VPN_INPUT_PORTS에 기재해야 VPN 서버 측에서 포트가 허용됩니다. 이는 Docker Compose로 구축된 미디어 스택에서 가장 흔히 누락되는 부분입니다.
킬 스위치: 터널 연결이 끊어질 때 발생하는 일
이 패턴은 장애 발생 시 그 복잡함의 대가를 치릅니다. 연결된 컨테이너에는 두 번째 경로가 없습니다. 해당 컨테이너가 머신 외부로 나가는 유일한 경로는 공유하는 네임스페이스뿐이므로, 터널이 다운되면 대체할 경로가 전혀 없습니다. Gluetun의 방화벽은 반대편에서도 동일한 규칙을 강제합니다. 즉, 아웃바운드 트래픽은 터널을 통하거나 VPN 서버 엔드포인트로만 향해야 하며, 그 외의 모든 트래픽은 차단됩니다. 클라이언트가 재연결을 시도하는 동안 패킷이 일반 인터페이스로 유출되는 틈은 존재하지 않습니다.
Gluetun은 자신의 연결 상태를 감시합니다. 1분마다 HEALTH_ICMP_TARGET_IPS에 있는 주소로 ICMP 에코(ping)를 보내며, 기본값은 1.1.1.1,8.8.8.8입니다. 5분마다 HEALTH_TARGET_ADDRESSES(기본값 cloudflare.com:443,github.com:443)으로 전체 TCP 및 TLS(전송 계층 보안) 다이얼을 시도합니다. 이 과정이 실패하면 컨테이너 내부의 VPN을 재시작하고 다음과 같이 로그를 남깁니다.
WARN [vpn] restarting VPN because it failed to pass the healthcheck: periodic check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout이 순서를 염두에 두고 연결된 컨테이너의 로그를 읽으십시오. 애플리케이션 내부의 connection refused, operation not permitted, i/o timeout와 같은 줄은 터널이 죽어서 발생하는 결과일 뿐, 원인이 아닙니다. Gluetun 문서에서도 이 점을 명확히 밝히고 있는데, 많은 사용자가 결과만 보고 이를 해결하려 몇 시간씩 허비하기 때문입니다.
HEALTH_RESTART_VPN=on은 기본 설정이며 켜두어야 합니다. 특정 장애를 디버깅하는 동안에만 끄십시오. 이 설정을 끄면 터널이 죽었을 때 그대로 방치되기 때문입니다.
순서 지정: 터널이 연결되기 전에 스택이 시작되지 않도록 설정
이 이미지에는 Docker healthcheck가 포함되어 있습니다:
HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /gluetun-entrypoint healthcheck이 명령어는 gluetun의 단기 실행 복사본을 생성하여 실행 중인 gluetun의 상태 서버인 http://127.0.0.1:9999/에 질의합니다. 터널이 정상 작동하면 200 OK을 반환합니다. 연결이 끊기면 500 Internal server error와 함께 오류 문자열을 반환하며, 단 한 번의 실패로 컨테이너는 비정상(unhealthy) 상태로 표시됩니다.
condition: service_healthy는 이를 기다리는 설정입니다. 단순히 depends_on: [gluetun]만 사용하면 컨테이너가 시작되자마자 다음 단계로 넘어가는데, 이는 핸드셰이크가 완료되기 수 초 전입니다. 따라서 애플리케이션은 네트워크가 연결되지 않은 상태에서 시작되어 첫 연결 시도부터 실패하는 경우가 많습니다. Docker Compose의 Healthcheck에서 구문과 타이밍 필드에 대한 상세 내용을 확인할 수 있습니다.
사용자가 자주 겪는 제한 사항이 하나 있습니다. Compose는 컨테이너를 생성할 때 해당 조건을 한 번만 평가합니다. 이후 gluetun이 비정상 상태가 되어도 애플리케이션을 중지하거나 재시작하지 않습니다. 이 경우 gluetun 내부의 자동 복구 기능이 작동하며, 컨테이너 자체가 아닌 VPN 프로세스를 재시작하는 방식으로 대응합니다.
설정을 신뢰하기 전에 DNS 유출 여부를 확인하십시오
DNS(domain name system)는 올바르게 터널링을 구성해도 유출이 발생할 수 있는 지점입니다. Gluetun은 네임스페이스 내부에서 자체 리졸버를 실행하며, 기본적으로 DoT(DNS over TLS)를 통해 Cloudflare로 쿼리를 전달합니다(DNS_UPSTREAM_RESOLVER_TYPE=dot 및 DNS_UPSTREAM_RESOLVERS=cloudflare). 이 두 설정을 그대로 두면 조회 내용이 암호화되어 터널을 통해 전송됩니다.
이 설정을 무너뜨리는 주범은 DNS_UPSTREAM_PLAIN_ADDRESSES입니다. 이름 해석에 실패할 때 라우터나 ISP의 리졸버가 대신 응답하도록 하려는 사용자들이 이 설정을 변경하곤 합니다. Gluetun 문서에서는 이에 따른 대가를 명확히 경고합니다. 모든 DNS 트래픽이 VPN 터널을 통하지 않고 외부로 유출됩니다. 트래픽은 비공개로 유지되더라도, 방문하는 호스트 이름 목록은 노출됩니다. WireGuard에서 동일한 실수를 범하는 경우에 대해서는 WireGuard 터널에서 DNS 해석이 중단되는 문제를 참조하십시오.
테스트하려면 Gluetun에서 HTTPPROXY=on을 설정하고 8888:8888/tcp을 게시한 다음, 브라우저를 해당 프록시로 지정하고 DNS 유출 테스트 사이트를 로드하십시오. 결과에는 사용 중인 VPN 제공업체나 Cloudflare가 표시되어야 하며, 절대 홈 라우터가 표시되어서는 안 됩니다. Gluetun 자체 문서에서는 일부 유출 테스트 결과가 이상하게 나올 수 있다고 경고합니다. 네임스페이스 내부의 리졸버는 최종 응답 서버가 아니라 로컬 캐싱 중개자 역할을 하기 때문입니다. 결과에 다른 국가가 표시되거나 본인의 ISP 리졸버가 나타난다면, 이는 유출이 발생하고 있다는 확실한 신호입니다.
VPN 사이드카와 함께 Tailscale을 추가할 때 우선순위 결정
Tailscale은 자신의 장비에 접근하기 위해 WireGuard 기반으로 구축된 오버레이 네트워크이며, 관리자가 스택에 접근할 경로를 유지하기 위해 VPN 제공업체의 VPN과 함께 실행하는 경우가 많습니다. 이해할 가치가 있는 이유로 인해 두 서비스가 충돌하는 일은 드뭅니다. Tailscale의 문서는 기본 동작을 다음과 같이 명시합니다. Tailscale은 오버레이 네트워크로 작동하며, Tailscale을 실행 중인 장치 간의 트래픽만 라우팅하고 공용 인터넷 트래픽에는 관여하지 않습니다.
따라서 답은 하나의 설정에 달려 있습니다.
- 자체 컨테이너에서 실행되는 기본 설정의 Tailscale: 애플리케이션의 아웃바운드 트래픽을 전혀 보지 않습니다. 모든 트래픽은 Gluetun이 처리합니다. Tailscale은 다른 외부 컨테이너와 마찬가지로
gluetun:8080를 통해 애플리케이션에 도달합니다. network_mode: "service:gluetun"을 사용하여 Gluetun의 네임스페이스에 연결된 Tailscale: 네임스페이스에는 권한이 포함되지 않으므로 자체적인cap_add,net_admin,net_raw이 필요합니다. 기본 사용자 공간 네트워킹 모드에서TS_USERSPACE이 켜져 있으면 tailscaled는 인터페이스를 전혀 생성하지 않고 SOCKS5 또는 HTTP 프록시로 작동하므로 라우팅을 변경할 수 없습니다. 여전히 모든 트래픽은 Gluetun이 처리합니다.TS_USERSPACE=false을 사용한 동일한 구성: tailscaled가 터널 장치를 생성하고 경로를 설정하지만, 이는100.64.0.0/10범위의 tailnet과TS_ROUTES으로 광고하는 서브넷 경로에 대해서만 적용됩니다. 공용 트래픽은 여전히 Gluetun을 통해 나갑니다.- 위 설정 중 하나에서
sudo tailscale set --exit-node=<exit-node-ip>을 사용하여 출구 노드(exit node)를 선택한 경우: Tailscale이 기본 경로를 점유하며 우선권을 갖습니다. 이 설정을 Gluetun과 결합하지 마십시오. 기본 경로는 하나만 존재할 수 있으며 소유자도 하나여야 합니다.
광고된 경로가 목적이며, 장비 단독이 아닌 박스 뒤의 전체 사설 네트워크에 접근하려는 경우 VPS에서 Tailscale 서브넷 라우터 실행하기를 참조하십시오. 경로 승인, IP 포워딩, 그리고 TS_ROUTES만으로는 해결되지 않는 클라이언트 측 플래그 설정 방법을 다룹니다.
Tailscale의 목적이 경로가 아닌 관리 URL 제공이라면, tailscale serve 및 tailscale funnel를 사용하여 tailnet을 위한 gluetun:8080 앞에 HTTPS를 배치하고, funnel 기능을 통해서만 공용 인터넷에 노출할 수 있습니다.
한 가지 부작용은 Tailscale이 터널 내부에서 실행될 때 나타납니다. 피어들은 VPN 제공업체의 주소를 보게 되므로 릴레이 연결로 전환되는 빈도가 높아질 수 있습니다. 이러한 상황이 발생하면 tailscale status은 피어 옆에 direct 대신 relay "..."을 표시합니다. 연결은 작동하지만 속도는 더 느려집니다. 오버레이 네트워크만 필요한 경우라면 일반 WireGuard와 Tailscale의 차이점을 먼저 살펴보는 것이 좋습니다.
무엇이 문제이며 어떤 메시지가 나타나는가
Docker가 애플리케이션 컨테이너 생성을 거부합니다. Error response from daemon: conflicting options: port publishing and the container type network mode는 연결된 서비스에 ports: 블록이 여전히 남아 있음을 의미합니다. 이를 gluetun으로 옮기십시오.
Compose가 파일 전체를 거부합니다. 서비스는 network_mode와 networks를 동시에 설정할 수 없습니다. 네트워크 설정을 gluetun으로 옮기십시오.
다른 컨테이너가 애플리케이션을 해석(resolve)할 수 없습니다. curl: (6) Could not resolve host: qbittorrent은 정상적인 동작입니다. 연결된 컨테이너가 어떤 네트워크에도 참여하지 않았고 이름을 등록하지 않았기 때문입니다. gluetun와 포트를 사용하십시오.
두 번째로 연결된 컨테이너가 시작되지 않습니다. 동일한 네임스페이스 내의 두 프로세스는 같은 포트에 바인딩할 수 없으며, 실패한 쪽은 주소가 이미 사용 중이라는 오류를 보고합니다. 애플리케이션의 내부 포트를 변경하거나, 두 번째 gluetun을 실행하십시오.
gluetun을 건드린 후 애플리케이션의 네트워크가 끊겼습니다. gluetun을 재시작하거나 재생성하면 여기에 연결된 모든 컨테이너의 연결이 끊어집니다. 해당 컨테이너들을 재시작하십시오.
작은 페이지는 로드되지만 큰 페이지는 멈춥니다. 이는 MTU(maximum transmission unit) 문제입니다. 터널은 오버헤드를 추가하며, 경로상의 특정 지점에서 오류 메시지 없이 너무 큰 패킷을 폐기하기 때문입니다. WIREGUARD_MTU를 낮추고, 1400을 시도한 뒤, 1320을 적용해 보십시오.
gluetun이 정상 상태(healthy)가 되지 않습니다. 시작 확인 과정에서 첫 번째 의심 요소인 WARN [vpn] restarting VPN because it failed to pass the healthcheck: startup check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout을 지목합니다. 키가 만료되었는지 확인하고, 서버 목록이 오래되었는지, 호스트 방화벽이 아웃바운드 UDP를 차단하고 있는지 차례로 점검하십시오.
FAQ
Gluetun 뒤에서 컨테이너의 포트 포워딩이 작동하지 않는 이유는 무엇입니까?
network_mode: "service:gluetun"는 컨테이너를 Gluetun의 네트워크 네임스페이스 안으로 배치하기 때문입니다. 하나의 네임스페이스는 하나의 IP 주소와 하나의 리스닝 포트 세트만을 가집니다. 애플리케이션은 계속 리스닝 상태를 유지하지만, 포트 게시 규칙은 해당 네임스페이스를 소유한 컨테이너에 적용되어야 합니다. ports: 목록을 Gluetun 서비스로 옮기십시오. 만약 연결된 서비스에 그대로 두면 Docker는 컨테이너를 생성하지 못합니다: Error response from daemon: conflicting options: port publishing and the container type network mode.
VPN 터널 내부의 컨테이너에 외부 컨테이너에서 접근하려면 어떻게 해야 합니까?
Gluetun의 서비스 이름과 애플리케이션이 리스닝하는 포트를 사용하십시오. 예: gluetun:8080. 연결된 컨테이너는 자체적인 Docker 네트워크를 가지지 않으므로 해당 컨테이너의 이름으로는 주소 해석이 되지 않습니다. 컨테이너 간 통신을 위해 포트를 게시할 필요는 없습니다. 반대로, 네임스페이스 내부의 컨테이너가 외부 컨테이너에 접근할 때는 Gluetun v3.41 이상 버전에서 서비스 이름을 사용하십시오. 예: postgres:5432. LAN에 있는 노트북과 같이 다른 서브넷에 있는 클라이언트는 FIREWALL_OUTBOUND_SUBNETS에 해당 서브넷을 추가하기 전까지 Gluetun 방화벽에 의해 차단됩니다.
VPN 연결이 끊어질 때 Gluetun이 킬 스위치(kill switch) 역할을 합니까?
네, 두 가지 이유로 동시에 작동합니다. 연결된 컨테이너는 공유 네임스페이스 내의 경로 외에는 다른 경로를 가지지 않으므로, 터널이 끊어지면 외부로 나가는 경로가 사라집니다. 또한 Gluetun의 방화벽은 터널과 VPN 서버 엔드포인트를 통해서만 아웃바운드 트래픽을 허용합니다. Gluetun은 종료되는 대신 내부적으로 VPN을 재시작하며 WARN [vpn] restarting VPN because it failed to pass the healthcheck를 로그에 남깁니다. Gluetun 자체가 재시작될 때 연결된 모든 컨테이너의 네트워크가 끊기기 때문입니다.
Tailscale과 Gluetun을 같은 스택에서 사용할 때, 어느 쪽이 아웃바운드 트래픽을 처리합니까?
한 가지 경우를 제외하고는 항상 Gluetun이 처리합니다. Tailscale은 기본적으로 tailnet 내의 장치 간 트래픽만 라우팅하며 공용 트래픽은 건드리지 않습니다. 컨테이너 이미지의 기본 사용자 공간 모드에서는 인터페이스를 생성하지 않으므로 라우팅에 영향을 줄 수 없습니다. TS_USERSPACE=false을 사용하면 100.64.0.0/10 및 광고된 서브넷에 대해서만 경로를 설정합니다. 예외는 출구 노드(exit node)입니다. sudo tailscale set --exit-node=<exit-node-ip>을 사용하면 Tailscale이 기본 경로가 되며, 이때는 Tailscale이 우선합니다. 두 제품을 쌓아서 사용하기보다 기본 경로를 담당할 제품을 하나만 선택하십시오.