Kubernetes의 노드 포트에 투명하게 프록시

Kubernetes의 노드 포트에 투명하게 프록시

다음 컨테이너가 포함된 포드로 kubernetes를 설정했습니다.

  1. 오징어통
  2. 트랜삭(빨간 양말과 같은); 투명한 SOCKS 프록시

저는 이것을 Linux PC의 k3s에서 로컬로 실행하고 있으며 이 투명 프록시를 통해 PC에서 나가는 모든 트래픽을 투명하게 프록시 처리하려고 합니다. 따라서 나가는 호스트 트래픽은 kubernetes 포드의 transocks 포트로 강제 이동됩니다. 지금은 작동하지 않고 연결 시간이 초과됩니다.

나는 호스트 네트워킹을 사용하여 Docker에서 직접 위의 컨테이너를 실행할 때 작동했기 때문에 내가 사용하고 있는 iptables 규칙이 훌륭하다는 것을 알고 있습니다. squid 및 transocks 사용자는 uid 31 및 32였습니다. 다음과 같은 iptables 규칙을 만들었습니다.

#iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT
#iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT
#iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 12345
#iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 12345

12345는 포트 트랜삭이 수신 대기 중인 곳입니다. 다시 말하지만, 이러한 규칙은 호스트 네트워킹을 사용하는 Docker에서 잘 작동합니다. transock은 127.0.0.1:3128(오징어 포트)로 전달되며 투명하게 프록시됩니다. 그러나 nodeport(transocks의 경우 30345, squid의 경우 30128)를 사용하여 kubernetes 포드를 사용하여 시도하면 작동하지 않는 것 같습니다. 시간이 초과될 때까지 연결이 중단됩니다.

53에 대한 출력 트래픽을 포트 9053(Docker에 매핑된 DNS 포트)으로 리디렉션하는 DNS에서도 동일한 작업을 시도했으며 작동하지만 kubernetes에서 사용하고 nodeport(30053)로 리디렉션합니다. ) 같은 방식으로 중단됩니다. 따라서 어떤 이유로 트래픽을 리디렉션할 때 노드 포트가 작동하지 않는 것 같습니다. 누군가 내가 여기서 놓치고 있는 것이 무엇인지 말해 줄 수 있는지 궁금합니다. 나는 쿠버네티스 네트워킹을 잘 이해하지 못하는 것 같다.

누군가 내 kuebrnetes 매니페스트를 보고 싶어한다면 여기 있습니다.

전개

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "webfilter"
      }
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "webfilter"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "squid",
            "image": "jusschwa/squid-ssl:latest",
            "ports": [
              {
                "containerPort": 3128
              }
            ]
          }, {
            "name": "transocks",
            "image": "jusschwa/transocks-proxy:latest",
            "ports": [
              {
                "containerPort": 12345
              }
            ]
          }
        ]
      }
    }
  }
}

서비스

{
  "apiVersion": "v1",
  "kind": "Service",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "type": "NodePort",
    "selector": {
      "app": "webfilter"
    },
    "ports": [
      {
        "name": "squid",
        "protocol": "TCP",
        "port": 3128,
        "targetPort": 3128,
        "nodePort": 30128
      },
      {
        "name": "transocks",
        "protocol": "TCP",
        "port": 12345,
        "targetPort": 12345,
        "nodePort": 30345
      }
    ]
  }
}

iptables 규칙

iptables -t nat -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT # squid user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # transocks user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # unbound user
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 30053

도움을 주셔서 다시 한번 감사드립니다.

답변1

누구든지 관심이 있다면 노드 포트를 사용하는 것이 너무 어렵다는 것을 알았고 대신 트랜스삭을 자체 포드로 옮기고 위의 전달 규칙과 함께 호스트 네트워킹을 사용하여 이 작업을 수행하기로 결정했습니다. Transocks 포드에 사용한 매니페스트는 다음과 같습니다.

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "transocks"
  },
  "spec": {
    "hostNetwork": true,
    "dnsPolicy": "ClusterFirstWithHostNet",
    "containers": [
      {
        "name": "transocks",
        "image": "jusschwa/transocks-proxy"
      }
    ]
  }
}

이것은 내가 사용하고 있는 transocks toml입니다:

listen = "0.0.0.0:12345"

# Connect to HTTP Proxy
proxy_url = "http://127.0.0.1:30128"

[log]
level = "error"

30128은 오징어 프록시용 노드 포트입니다.

관련 정보