Docker 컨테이너 내부의 아웃바운드 트래픽을 다른 포트로 다시 매핑하고 싶습니다. 예: curl 1.2.3.4:8080
실제로 에게 요청하고 싶습니다 curl 1.2.3.4:8181
. (이는 쿠버네티스에서 kube-proxy가 수행하는 것과 유사합니다.)
나는 도커 컨테이너에서 다음을 실행할 수 있다는 것을 알고 있습니다.
iptables -t nat -A OUTPUT -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to-destination 1.2.3.4:8181
그러면 요청이 예상대로 실행됩니다. 그러나 동일한 기능을 얻기 위해 호스트에서 iptables 규칙을 편집하고 싶습니다.
ID가 있는 도커 네트워크가 있고 이를 호스트에서 실행 8e8799c36e69
하면 다음 규칙을 얻습니다.iptables-save | grep 8e8799c36e69
-A POSTROUTING -s 172.18.0.0/16 ! -o br-8e8799c36e69 -j MASQUERADE
-A DOCKER -i br-8e8799c36e69 -j RETURN
-A FORWARD -o br-8e8799c36e69 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-8e8799c36e69 -j DOCKER
-A FORWARD -i br-8e8799c36e69 ! -o br-8e8799c36e69 -j ACCEPT
-A FORWARD -i br-8e8799c36e69 -o br-8e8799c36e69 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-8e8799c36e69 ! -o br-8e8799c36e69 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-2 -o br-8e8799c36e69 -j DROP
이 네트워크 내에서 포트 재작성을 설정할 수 있도록 이러한 규칙을 추가할 수 있습니까? (이 행사가 옳은 일이었나요?)
어쩌면 그냥 이런 것 아닐까요?
iptables -t nat -I OUTPUT -o br-8e8799c36ec9 --src 0/0 --dst 1.2.3.4 -p tcp --dport 8080 -j REDIRECT --to-ports 8181
아니면 도커 브리지 네트워킹이 필요하지 않고 어떻게든 컨테이너 내부의 트래픽을 필터링할 수 있을까요?
편집하다:
Docker 컨테이너를 시작하면 다음 규칙이 생성됩니다.
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 8080 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:8080
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8080 -j ACCEPT
컨테이너에는 172.17.0.2
내 컴퓨터에 IP 주소가 있습니다. 그래서 다음 규칙을 추가했습니다.
sudo iptables -t nat -A OUTPUT -s 172.17.0.2/32 -p tcp -d 172.217.3.110 --dport 8080 -j DNAT --to-destination 172.217.3.110:80
172.217.3.110:8080
요청에 대한 테스트 요청을 보내려고 시도했지만 172.217.3.110:80
작동하지 않는 것 같습니다.
편집 2:
로컬 수신 서비스의 포트를 다시 쓰려고 하면 다음 명령을 사용할 수 있습니다.
LOCAL_IP=192.168.86.30
REQUESTED_PORT=80
DESTINATION_PORT=8080
CONTAINER_IP=172.17.0.2
sudo iptables -t nat -A OUTPUT -p tcp -d $LOCAL_IP --dport $REQUESTED_PORT -j DNAT --to-destination :$DESTINATIO_PORT
sudo iptables -t nat -I PREROUTING -s $CONTAINER_IP -d $LOCAL_IP -p tcp --dport $REQUESTED_PORT -j REDIRECT --to-ports $DESTINATION_PORT
이것은 로컬 IP에서만 작동하는 것 같습니다.
편집 3: kube-proxy 소스에는 접근 방식과 다양한 함정에 대한 추가 정보가 있습니다.
https://github.com/kubernetes/kubernetes/blob/84dc704/pkg/proxy/userspace/proxier.go#L1133-L1165
답변1
알았어, 알아냈어.
IP 주소가 있는 컨테이너 의 트래픽을 192.168.86.30:80
리디렉션 하려면 다음 규칙을 추가하면 됩니다.192.168.86.30:8084
172.17.0.2
sudo iptables -t nat -A PREROUTING --protocol tcp --destination 192.168.86.30 \
--dport 80 --source 172.17.0.2 \
--jump DNAT --to-destination 192.168.86.30:8084
이는 공용 외부 IP 주소에도 적용되는 것으로 보입니다.
REDIRECT
왜냐하면 작동하지 않는 것 같습니다.[원천]:
대상 IP를 들어오는 인터페이스의 기본 주소로 변경하여 패킷을 시스템 자체로 리디렉션합니다(로컬에서 생성된 패킷은 127.0.0.1 주소에 매핑됨).
여전히 무슨 일이 일어나고 있는지 완전히 확신할 수는 없지만 이것이 바로 REDIRECT가 로컬 서비스(특히 0.0.0.0에서 수신하는 모든 항목)의 일부 작업을 처리할 수 있지만 외부 IP는 처리할 수 없는 이유라고 생각합니다.