튜토리얼 Clash 입문 VPN 비교 프록시 초보 가이드

Clash 투명 프록시로 Docker Hub Pull 오류와 타임아웃 해결

2026년 7월 23일 업데이트: 2026년 7월 23일 약 10분 소요

서론: Docker Hub Pull 오류의 원인

Docker 이미지를 빌드하거나 컨테이너를 실행할 때 docker pull이 멈추고, 결국 i/o timeout, context deadline exceeded, TLS handshake timeout 같은 메시지가 표시되는 경우가 있습니다. 브라우저에서는 인터넷이 정상적으로 열리는데 Docker Hub만 접속되지 않는다면, 단순한 인터넷 끊김보다 Docker 데몬의 네트워크 경로와 Clash 프록시 적용 범위를 먼저 의심해야 합니다.

Docker CLI 명령을 실행하는 터미널에 시스템 프록시를 설정했다고 해서 Docker 데몬까지 자동으로 프록시를 사용하는 것은 아닙니다. 실제 이미지 다운로드는 백그라운드에서 실행 중인 Docker daemon이 담당하며, 이 프로세스는 일반 브라우저나 셸 환경과 별도의 네트워크 설정을 가질 수 있습니다. 따라서 Clash를 켜 둔 상태에서도 Docker Hub 요청은 직접 연결로 나가거나, 잘못된 DNS 응답을 받아 시간 초과가 발생할 수 있습니다.

핵심 요약

Docker Hub 문제는 Clash의 TUN 모드, Docker 데몬 프록시, DNS 응답, 규칙 우선순위를 각각 확인해야 정확하게 해결할 수 있습니다.

이 글에서는 Windows, macOS, Linux에서 공통으로 적용할 수 있는 진단 순서를 설명합니다. 배포판과 Docker Desktop 버전에 따라 메뉴 이름은 다를 수 있지만, 도메인 확인 → Clash 로그 확인 → 데몬 프록시 적용 → Docker 재시작 → Pull 재시험이라는 흐름은 대부분의 환경에서 유효합니다.

1오류 메시지로 문제 범위 좁히기

먼저 오류 문구를 기록해 두세요. 같은 “pull 실패”라도 DNS 문제인지, 연결은 되었지만 TLS 협상이 실패한 것인지에 따라 해결 방법이 달라집니다. 다음 표는 자주 나타나는 증상과 우선 점검할 지점을 정리한 것입니다.

오류 또는 증상 가능성이 높은 원인 첫 번째 점검 항목
lookup registry-1.docker.io DNS 해석 실패, fake-ip 충돌, DNS 누수 Clash DNS 로그와 nslookup 결과
i/o timeout Docker 데몬이 프록시를 사용하지 않음 데몬의 HTTP/HTTPS 프록시 환경 변수
TLS handshake timeout 직접 연결 차단, 불안정한 노드, MTU 문제 Clash 연결 로그와 노드 변경 결과
인증 토큰 단계에서 실패 auth.docker.io 규칙 누락 또는 IP 품질 문제 Docker Hub 관련 도메인 전체의 규칙 매칭
매니페스트는 받지만 레이어에서 중단 대용량 연결 불안정, 프록시 제한, 디스크 문제 레이어별 로그와 저장 공간

Linux에서는 다음 명령으로 Docker Hub의 주요 도메인이 해석되는지 확인할 수 있습니다.

getent hosts registry-1.docker.io getent hosts auth.docker.io curl -I https://registry-1.docker.io/v2/

curl 결과가 401 Unauthorized라면 오히려 서버에 도달했다는 뜻일 수 있습니다. Docker Registry는 인증 토큰 없이 요청하면 정상적으로 401을 반환하므로, 이 응답만으로 접속 실패라고 판단하지 마세요. 반대로 DNS 오류나 연결 시간 초과가 나온다면 아직 인증 단계까지 도달하지 못한 것입니다.

2Clash TUN 모드와 DNS 구성 확인

Docker 데몬이 별도 프록시 설정 없이도 Clash를 통과하게 만들려면 시스템 전체 트래픽을 가로채는 TUN 모드가 유용합니다. 일반 시스템 프록시는 브라우저나 일부 GUI 애플리케이션에만 적용되지만, TUN은 가상 네트워크 인터페이스를 통해 프로세스의 TCP 요청을 Clash로 전달합니다.

  1. Clash Verge Rev 또는 사용 중인 Clash 클라이언트에서 TUN Mode를 켭니다.
  2. 관리자 권한 또는 시스템 권한 요청이 나타나면 승인합니다.
  3. 모드가 Rule인지 확인합니다. Global은 진단에는 편리하지만 모든 트래픽을 프록시로 보내므로 장기 사용에는 적합하지 않을 수 있습니다.
  4. DNS 설정에서 원격 DNS 서버와 가상 IP 모드를 확인합니다.

fake-ip 모드는 도메인 기반 규칙을 적용하기 쉽지만, 일부 Docker 환경이나 로컬 네트워크 도메인과 충돌할 수 있습니다. 반대로 redir-host는 실제 IP를 반환하므로 특정 프로그램과의 호환성이 좋아질 수 있습니다. 한 모드에서 계속 실패한다면 설정을 백업한 뒤 다른 모드로 바꾸어 비교해 보세요.

DNS 설정에서 확인할 항목
  • DNS 활성화: Clash가 DNS 요청을 처리하도록 설정되어 있는지 확인합니다.
  • 원격 서버: 신뢰할 수 있는 HTTPS 또는 TLS DNS를 사용하고, 응답이 차단된 로컬 DNS로 되돌아가지 않는지 확인합니다.
  • nameserver-policy: 사설 도메인과 공용 Docker Hub 도메인을 같은 정책으로 무리하게 묶지 않습니다.
  • IPv6: IPv6 경로가 불안정하면 일시적으로 비활성화하여 IPv4와 결과를 비교합니다.

주의사항

TUN 모드를 켰더라도 Docker Desktop의 가상 머신 네트워크가 Clash의 가상 인터페이스를 우회할 수 있습니다. 이 경우 Docker 데몬에 명시적인 프록시를 설정해야 합니다.

3Docker 데몬에 프록시 적용하기

가장 재현성이 높은 방법은 Docker 데몬이 직접 Clash의 HTTP 또는 SOCKS 포트로 연결하도록 설정하는 것입니다. Clash의 포트 번호는 클라이언트마다 다르지만 일반적으로 HTTP 포트는 7890, SOCKS 포트는 7891처럼 표시됩니다. 반드시 Clash 화면의 실제 포트를 확인하세요.

Linux: systemd 환경

Linux에서 Docker가 systemd 서비스로 실행된다면 drop-in 디렉터리와 설정 파일을 만듭니다. 아래 예시는 Clash가 호스트의 7890 포트에서 HTTP 프록시를 제공한다고 가정합니다.

sudo mkdir -p /etc/systemd/system/docker.service.d sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

파일에는 다음 내용을 입력합니다. 127.0.0.1 대신 Docker가 실행되는 호스트에서 접근 가능한 Clash 주소를 사용해야 하는 경우도 있습니다.

[Service] Environment="HTTP_PROXY=http://127.0.0.1:7890" Environment="HTTPS_PROXY=http://127.0.0.1:7890" Environment="NO_PROXY=localhost,127.0.0.1,::1,.local"

저장한 뒤 데몬을 다시 읽고 Docker를 재시작합니다.

sudo systemctl daemon-reload sudo systemctl restart docker sudo systemctl show --property=Environment docker

마지막 명령에서 프록시 환경 변수가 실제로 표시되는지 확인하세요. 설정 파일을 작성했지만 재시작하지 않으면 기존 Docker 프로세스에는 변경 사항이 반영되지 않습니다.

Windows와 macOS: Docker Desktop

Docker Desktop은 내부 Linux 가상 머신에서 데몬을 실행하므로 호스트의 명령 프롬프트 환경 변수만으로는 충분하지 않습니다. Docker Desktop의 Settings → Resources → Proxies 또는 버전에 따라 Settings → Proxies 메뉴를 열고 수동 프록시를 설정하세요.

  1. HTTP Proxy와 HTTPS Proxy에 Clash HTTP 주소를 입력합니다. 예: http://127.0.0.1:7890
  2. Docker Hub에만 적용할 것인지, 모든 컨테이너 트래픽에도 적용할 것인지 선택합니다.
  3. 설정을 저장한 후 Docker Desktop을 완전히 재시작합니다.
  4. 터미널에서 docker info를 실행해 프록시 항목이 표시되는지 확인합니다.

성공 확인

docker info에 HTTP Proxy와 HTTPS Proxy가 보이고 Clash 연결 로그에 Docker Hub 도메인이 나타나면 데몬 프록시 적용이 성공한 것입니다.

4Docker Hub 규칙을 만들고 직접 테스트하기

이제 실제로 손을 움직여 규칙과 Pull 동작을 함께 확인합니다. Docker Hub는 이미지 저장소, 인증 서버, CDN이 서로 다른 도메인을 사용할 수 있으므로 docker.io 하나만 등록하는 방식은 충분하지 않을 수 있습니다.

단계별 테스트 절차
  1. Clash에서 현재 선택된 노드의 지연 시간과 연결 상태를 확인합니다.
  2. Clash 모드를 잠시 Global로 바꾼 뒤 docker pull hello-world를 실행합니다.
  3. Global 모드에서 성공하면 TUN 또는 Docker 규칙의 문제일 가능성이 높습니다.
  4. Rule 모드로 돌아가 Docker 전용 규칙을 추가한 뒤 다시 Pull합니다.
  5. 성공 후에는 로그에서 실제 매칭된 규칙과 사용된 노드를 확인합니다.

YAML의 rules에 넣을 수 있는 기본 예시는 다음과 같습니다. 사용 중인 프록시 그룹 이름이 Docker-Proxy가 아니라면 자신의 설정에 맞게 바꾸세요.

# Docker Hub 관련 도메인 - DOMAIN-SUFFIX,docker.io,Docker-Proxy - DOMAIN-SUFFIX,docker.com,Docker-Proxy - DOMAIN-SUFFIX,registry-1.docker.io,Docker-Proxy - DOMAIN-SUFFIX,auth.docker.io,Docker-Proxy - DOMAIN-SUFFIX,hub.docker.com,Docker-Proxy - DOMAIN-KEYWORD,docker,Docker-Proxy

규칙은 위에서 아래로 평가되므로 Docker 관련 규칙을 너무 아래에 배치하지 마세요. 앞에 있는 GEOIP,CN,DIRECT, MATCH,DIRECT 또는 광범위한 DOMAIN-SUFFIX,io,DIRECT 규칙이 먼저 매칭되면 Docker 전용 그룹에 도달하지 않습니다.

규칙 순서 주의

MATCH,DIRECT는 항상 마지막에 두세요. 이 규칙을 중간에 넣으면 뒤에 작성한 Docker Hub 규칙이 전혀 실행되지 않습니다.

테스트 이미지가 작아서 성공하더라도 실제 대형 이미지에서 실패할 수 있습니다. 다음처럼 레이어가 여러 개인 이미지를 별도로 시험하고, 실패한 레이어의 재시도 여부와 속도도 관찰하세요.

docker pull hello-world docker pull alpine:latest docker pull nginx:latest docker system info

5Clash와 Docker 로그로 마지막 원인 찾기

설정을 바꾼 뒤에도 실패한다면 추측보다 로그를 우선해야 합니다. Clash의 Connections 또는 Logs 화면을 열고 Pull 명령을 다시 실행하세요. registry-1.docker.io, auth.docker.io, CDN으로 보이는 호스트가 기록되는지 확인합니다.

  • 로그가 전혀 없음: Docker 데몬이 Clash를 통과하지 않거나, Docker Desktop 가상 네트워크가 우회하는 상태일 수 있습니다.
  • DIRECT로 표시됨: 규칙이 적용되지 않았거나 앞선 규칙에 의해 이미 결정된 것입니다.
  • 프록시 연결 후 실패: 선택한 노드의 IP 품질, 원격 서버의 TLS 처리, MTU 또는 대역폭 제한을 점검합니다.
  • DNS 로그만 반복됨: DNS 서버가 응답하지 않거나 fake-ip 예외 목록이 잘못 구성되었을 수 있습니다.

프록시를 적용했는데도 TLS 오류가 반복되면 우선 다른 노드로 바꾸어 비교합니다. 특정 노드에서만 실패한다면 Docker 설정 자체보다 해당 노드의 국제 회선, 공유 IP 평판, 연결 유지 정책 문제일 가능성이 큽니다. 여러 노드에서 동일하게 실패한다면 Docker Desktop 프록시 주소가 가상 머신에서 접근 가능한지 확인해야 합니다.

또한 컨테이너 내부의 인터넷 연결과 Docker Hub Pull은 서로 다른 문제입니다. 이미지 Pull은 Docker 데몬의 프록시 설정을 따르지만, 실행된 컨테이너의 패키지 설치나 API 호출은 컨테이너 환경 변수와 네트워크 설정의 영향을 받습니다. 따라서 Pull 성공 후에도 컨테이너에서 외부 통신이 필요하다면 별도로 HTTP_PROXY, HTTPS_PROXY, NO_PROXY를 전달해야 합니다.

docker run --rm \ -e HTTP_PROXY=http://host.docker.internal:7890 \ -e HTTPS_PROXY=http://host.docker.internal:7890 \ alpine:latest wget -qO- https://example.com

Linux에서는 host.docker.internal 지원 여부가 환경에 따라 다르므로, 필요하면 --add-host=host.docker.internal:host-gateway를 사용하거나 호스트의 실제 게이트웨이 주소를 지정하세요. 사내 저장소, Kubernetes 내부 서비스, 로컬 데이터베이스는 NO_PROXY에 추가하여 불필요하게 외부 프록시를 거치지 않도록 하는 것이 안전합니다.

6자주 묻는 질문

TUN 모드만 켜면 Docker Hub가 항상 해결되나요?

항상 그렇지는 않습니다. Docker Desktop은 별도의 가상 머신이나 네트워크 계층을 사용하므로 TUN 트래픽을 우회할 수 있습니다. TUN 모드로도 Clash 로그에 Docker Hub 요청이 나타나지 않는다면 Docker Desktop의 프록시 메뉴에서 HTTP와 HTTPS 프록시를 직접 설정하는 편이 확실합니다.

SOCKS 포트와 HTTP 포트 중 무엇을 사용해야 하나요?

Docker 데몬의 표준 프록시 설정에는 보통 HTTP 프록시 주소를 사용하는 것이 호환성이 좋습니다. Clash가 HTTP 포트를 제공한다면 먼저 http://127.0.0.1:7890 형식으로 설정하세요. SOCKS만 사용할 수 있는 환경이라면 Docker 버전과 Desktop 설정이 SOCKS를 지원하는지 확인한 뒤 사용해야 하며, 지원되지 않으면 Clash의 mixed 포트나 HTTP 포트를 활성화하는 방법이 더 안정적입니다.

Docker Hub 도메인을 모두 프록시로 보내야 하나요?

인증과 레이어 다운로드가 서로 다른 호스트를 사용할 수 있으므로 최소한 registry-1.docker.io, auth.docker.io, hub.docker.com은 함께 점검하는 것이 좋습니다. 실제 Pull 로그에 표시되는 CDN 도메인이 있다면 그 도메인도 규칙 대상에 추가하세요. 다만 모든 트래픽을 무조건 프록시로 보내기보다 Docker 관련 도메인만 전용 그룹에 배정하는 편이 속도와 관리 측면에서 유리합니다.

설정을 바꾼 뒤 Docker를 반드시 재시작해야 하나요?

systemd drop-in이나 Docker Desktop의 프록시 설정을 변경했다면 반드시 Docker 데몬 또는 Docker Desktop을 재시작해야 합니다. Clash의 규칙만 수정한 경우에도 설정을 Reload하고 기존 연결을 정리한 뒤 Pull을 다시 실행하세요. 이전에 실패한 연결이 계속 유지되면 새 규칙이 적용되지 않은 것처럼 보일 수 있습니다.

최종 점검 순서

Clash 실행 상태 → TUN 및 DNS → Docker 데몬 프록시 → Docker Hub 규칙 순서 → Clash 로그 → Docker 재시작 순서로 확인하면 대부분의 Pull 타임아웃을 빠르게 분리할 수 있습니다.

Clash 무료 다운로드 — 원활한 인터넷 경험을 시작하세요 →