증상부터 정리하면

개발 현장에서는 이미지 풀이 오래도록 pulling 레이어만 맴돈다가 끝나거나, 곧바로 Error response from daemon: Get "https://registry-1.docker.io/v2/" 형태 로그와 함께 TLS handshake timeout · i/o timeout · dial tcp 패턴 메시지를 띄우는 경우를 자주 만납니다. docker compose pull 이나 CI에서도 동일한데, 사람들이 헷갈리는 포인트는 브라우저로 허브 사이트는 열렸는데 컨테이너 레지스트리 엔드포인트 하나만 답이 없거나, 간헐적으로 끊기는 상황에도 같은 로그 형태가 난다는 점입니다. 그래서 “프록시를 썼는데도 왜 허브만 불안정한지” 같은 질문이 반복해서 등장합니다.

이 글의 목표는 전역 망 속도까지 논하지 않고, 사용자가 검색했을 때 당장 따라올 만한 순서입니다. 즉 브라우저용 시스템 프록시 한 줄호스트 패킷이 실제 어디로 빠져나가는지 사이 간극을 Clash TUN 과 연결 패널로 좁히고, 같은 노드 종단이라도 레이어가 달라질 수 있는 Docker 데몬 트래픽 경로를 분리해서 점검하는 절차를 한국 독자의 표현 방식으로 풉니다. 과장된 처방이라기보다는 “증거를 남긴 채로 순서를 밟았을 때 헛걸음이 줄어든다”는 실무 형태입니다.

시스템 프록시만 넣어도 Docker는 조용히 그대로

데스크톱 사용자는 OS 설정이나 특정 브라우저 프로필에 HTTP 프록시를 넣고 끝난 듯하지만 Docker 엔진 데몬은 그 위치까지 자동 참조하지 않는 경우가 훨씬 많습니다. 데몬은 자체 업데이터 루프나 환경 변수·또는 daemon.json 이 주는 명시 신호 없이 회선 라우팅으로만 허브에 붙었을 수 있습니다. 이때 패킷 출구 ISP 경로에서는 TLS 핸드셰이크 패킷이 지연 또는 필터링될 가능성을 배제하지 못하므로, 문제는 “허브가 항상 장애”라기보다 보내는 동선이 회사망 차단 패턴 위에 놓였는지 여부에 가깝습니다.

다음으로 헷갈리는 변수는 브라우저가 깨지지 않던 이유입니다. 많은 회사 장비가 허브 웹 UI는 허용하지만 레지스트리 직링크는 과도 차단이라는 패턴입니다. 따라서 사람의 감각은 “네트워크 된다고 판단”하는데 레지스트리만 TLS 구간부터 막히는 패턴입니다. 사용자가 같은 자리에서 호스트 레이어 테스트를 돌린 뒤 Docker 레이어만 다른 경로면 설명 가능성이 높습니다.

용어 차이부터 맞춥니다. 이 글에서는 docker.io 와 레지스트리 호스트 문자열 같은 것을 줄여 “허브”라 표기합니다만, 실패 로그에 찍히는 호스트 문자열까지 그대로 기록해 두는 것이 이후 패턴 학습과 규칙 매칭에 유리합니다.

호스트 패킷을 한 번 더 보려면 TUN 레이어

앞서 인용했듯 많은 프로그램이 시스템 프록시 힌트를 따라가지 않습니다. 같은 맥에서 curl 테스트도 변수가 많아지는데 반해 TUN 계열 접근 방식은 패킷이 운영체제 스택을 통과하면서 선택된 라우팅과 규칙 엔진에 한 번 들어오게 하는 그림이라, “해당 프로그램이 프록시를 모른 채 회선 바깥까지 가버리는 상태”보다 디버깅이 수월합니다. 이해를 돕기 위해 말하면, TUN 입장에서는 가상 어댑터로 걸린 나가기 연결 요청을 규칙과 프록시 그룹이 나누는 파이프처럼 느껴집니다.

다만 TUN이라고 레지스트리 도메인이 자동 우회된다는 확정은 규칙 품질에 따라 갈립니다. DOMAIN 규칙이 DIRECT로 떨어지거나 DNS fake-ip 레이어마다 GeoIP 결과가 다른 경우, “TUN까지 켰는데도 여전히 느린” 상황이 생깁니다. 그 경우 UI 연결 패널이나 Mihomo 형태의 로깅에서 해당 호스트가 무엇과 매치됐는지 확인하는 편이 가장 현실적인 판별입니다. 지연 테스트 결과와 실제 패킷 정책을 혼동하지 않도록 기억하세요.

보안 회사 장비에서는 먼저 정책을 확인해야 합니다. 회사 허브에서 전체 패킷 캡처나 TLS 검사 장비와 충돌하면 TUN 토글만 바꿔도 여전히 막히고, 무단 수정은 제재 가능성입니다. 따라서 가이드를 개인 테스트 환경 기준 서술한 전제입니다.

데스크톱 패키지를 쓰는 경우의 추가 허들

Mac이나 특정 플랫폼에서는 Docker가 리눅스 VM 위에서 돌도록 묶였습니다. 이 구조에서는 사용자가 호스트 OS에서 TUN을 켠 직후 docker pull 트래픽까지 같은 경로로 따라온다는 전제가 항상 맞지 않습니다. 호스트 curl 은 회사 프록시 뒤쪽 경로에서 연결 확인이 되더라도, VM 내부 데몬은 여전히 ISP 기본 회선만 쓰고 있었을 가능성까지 염두에 두세요. 순서에서는 먼저 호스트에서 연결 기준 상태를 깨끗이 확인한 뒤, 문제가 재현되면 레이어만 추가로 줄여 가는 접근법이 디버깅 스택 높이를 줄이기에 더 낫습니다.

실무적으로 접근하면 Docker 데스크톱 UI의 네트워크·프록시 섹션에서 분리된 레지스트리 출구 호스트 문자열까지 동일 종단 노드 또는 동일 회선 카테고리로 맞춰 주는 과정과, 또는 내부적으로 사용하는 호스트 접근 주소 변수를 통해 Mihomo가 열어둔 혼합 포트 쪽 연결 문자열 형태까지 정리해야 합니다. 여기까지가 “허브 풀이 TLS에서 멎는다” 증상에 대해 많은 사람이 미끄러지던 구간이라서, 과장하지 않도록 범위를 분리했습니다.

단계별로 따라가는 순서

증상 로그와 레지스트리 호스트 기록하기

docker pull 이나 docker compose pull 결과를 그대로 복사해 두면 이후 패턴 비교가 쉬워집니다. registry-1.docker.io, auth.docker.io 처럼 로그에 찍힌 URL을 그대로 메모했는지부터 확인하세요. 항상 동일 레이어 하나에서만 시간이 새는 것인지, 미러 문자열 때문에 호스트 하나가 교체되는 순간 막히는 것인지에 따라 접근 순서도 달라집니다.

docker pull busybox:latest
docker compose pull 

호스트 TLS 연결 테스트

TUN을 바꾸기 전이라도 레지스트리 엔드포인트까지 TLS가 막히면 아래처럼 먼저 확인할 수 있습니다.

curl -sI --max-time 25 https://registry-1.docker.io/v2/

Www-Authenticate 헤더나 401 응답은 정상에 가까운 패턴입니다. 반대로 항상 타임아웃이면 회선 레이블에서 패킷이 깨졌거나 중간 차단 패턴 가능성부터 짚습니다. TUN 활성 상태에서 같은 명령이 안정적으로 응답하고 Clash 패널에 해당 목적지가 우회 노드로 잡히면, 호스트에서는 원하는 종단까지 연결이 된다는 전제가 한 번 깔립니다.

Clash·Mihomo 계열 클라이언트에서 TUN 켜기

Windows는 초기 실행 시 관리자 권한을 요청하는 패턴이 흔하고, macOS는 네트워크 확장 권한 흐름이 따라옵니다. 토글을 켠 뒤에는 “어디까지 나가든 한 번 더 규칙을 통과하게 만든 상태”만 기억해 두세요. 과도 차단 회선이라면 속도 체커보다 레지스트리 경로처럼 짧은 테스트 한 번이 원인 레이블을 줄이기에 더 빠르기도 합니다.

레지스트리 도메인이 규칙 어디로 매치되는지

TUN이라도 기본 라우팅이 자동으로 해외 허브로 통일되지는 않습니다. 허브에서 쓰이는 문자열 패턴들이 우회 규칙보다 상단에서 DIRECT 규칙에 먼저 걸린다면, 패널에는 아무 이상 없어 보였는데 레지스트리만 막히는 패턴이 생깁니다. DNS 결과가 실제 접속 레이블과 어긋나면 GEOIP 판별도 빗나가서, 건강해 보였던 노드가 실패 로그와 무관하게 보일 수 있습니다. 패널의 매칭 기록 문자열 또는 코어 로그를 한 줄이라도 교차 검증하는 습관이 중요합니다.

레지스트리만 느렸던 케이스 상당수는 “프록시 그룹은 맞지만 특정 규칙 때문에 DIRECT에서 ISP 경로만 계속 새는 상태”처럼 단순한 설명 한 줄로 끝나기도 합니다.

호스트는 되고 docker pull 만 남았을 때

Docker 데몬은 호스트 테스트와 같은 출구를 쓴다는 관측이 항상 맞진 않습니다. 데스크톱 앱이라면 설정에서 레지스트리 출구 문자열까지 동일한 프록시 힌트를 주거나, 순간 테스트로 환경 변수를 덧입혀 패턴 차이부터 좁히는 접근법이 많이 씁니다. 아래는 일회성 확인용 예제에 가까우며 숫자는 본인 Clash 설정의 혼합 포트 문자로 바꾸세요.

HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 docker pull alpine:latest

리눅스에서 Docker 엔진을 직접 돌린다면, 서비스 유닛 또는 팀 표준 스크립트에 프록시를 고정해 재현 패턴까지 맞추는 접근도 흔합니다. 위 단계처럼 “호스트·데몬·규칙”을 레이블로 분리했다면 디버깅 비용 자체가 이미 줄어든 상태입니다.

IPv6·MTU처럼 겉으로 안 보이는 변수

A 레코드가 IPv6 우선이라면 회선 패턴 때문에 IPv6 종단까지 갔다가 TLS 핸드셰이크 단계만 멎는 패턴도 있습니다. 패널에 IPv6 흔적이 반복된다면 운영체제나 클라이언트에서 IPv6 우선 순위를 줄이거나, DNS 모드를 바꿔 교차 검증해 보세요. 특정 회선에서는 MTU가 맞지 않아 조각화 이슈처럼 보이며, 이때 작은 단위 테스트는 성공하지만 무거운 풀이 막히는 경우도 교차 테스트해 볼 여지가 있습니다.

자주 묻는 질문

Q. macOS에서 호스트만 TUN 켠 뒤에도 Docker Desktop의 docker pull 만 그대로인가요? 데몬 출구 경로가 Linux VM이라 호스트 패킷과 다를 수 있어서 그렇습니다. Docker Desktop 설정의 프록시나 호스트 루프백 접근 문자열 같은 보완이 필요할 때가 많습니다.

Q. 시스템 프록시가 되면 Docker까지 따라와야 하는 것 아니에요? 데몬은 브라우저와 같은 힌트를 기본 따라가지 않는 경우가 많아서 레이블이 달라집니다. 그래서 TUN으로 호스트를 먼저 고정 검증하고, 필요하면 데몬 단 프록시를 덧입히는 순서입니다.

Q. TUN 때문에 IPv6·DNS가 더 꼬이기도 하나요? 설정 조합을 잘못 맞추면 fake-ip 방식 때문에 매칭이 엇나갈 수 있습니다. 문제가 재현된다면 패널과 로그로 실제 접속 흐름을 함께 따라가세요.

정리하면

상용 레지스트리 미러 문자열을 붙였다 떼었다 하며 억지로 빙 돌리는 방식은 팀마다 문서가 갈라지고 기억에만 남기 쉽습니다. 반면 Clash·Mihomo 생태계는 규칙 기반 분기TUN으로 호스트 트래픽을 한 파이프에 모으는 경험을 같이 제공해, “브라우저만 되고 컨테이너는 아니다” 같은 차이를 패널에서 설명 가능한 형태로 만듭니다. 단순 VPN 토글 하나로 전체를 터널하기만 하면 국내 서비스까지 해외로 돌아가 느려지는 부작용이 생기기 쉬운데, 의도한 도메인만 우회로 보내는 정책과 TUN을 같이 쓰면 개발용 프록시 경로를 맞추기가 훨씬 수월합니다.

오래된 일부 클라이언트는 규칙 공급이나 코어 연동이 느려 최신 전송 프로토콜을 따라가기 어렵고, 연결 화면에서 매칭 결과를 보기도 힘듭니다. 반면 최신 Clash 계열 앱은 지연 테스트·규칙 세트·TUN 토글을 한곳에 묶어 두어서 docker pull 같은 반복 작업이 막혔을 때 원인 레이블을 빨리 좁힐 수 있습니다. 공식 배포 페이지에서 OS에 맞는 빌드를 받아 TUN을 켠 뒤, 이 글의 순서대로 호스트 검증과 데몬 경로만 나눠 보시면 됩니다.

Clash 클라이언트 무료 다운로드 →