iptables实现容器内proxy转发从而实现pod内sidecar容器转发到业务容器

proxy和server都是二进制直接运行在节点容器上。
iptables规则
# client在外部,流量dnat
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 8081
# client在内部,流量dnat
iptables -t nat -A OUTPUT -p tcp --dport 8080 -j REDIRECT --to-port 8081
server.go
package main
import (
"log"
"net/http"
)
func handlerA(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("a"))
}
func handlerB(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("b"))
}
func main() {
http.HandleFunc("/a", handlerA)
http.HandleFunc("/b", handlerB)
port := ":8080"
log.Printf("Business service starting on port %s", port)
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatalf("Server failed to start: %v", err)
}
}
proxy.go
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
target, err := url.Parse("http://localhost:8080")
if err != nil {
log.Fatal(err)
}
proxy := httputil.NewSingleHostReverseProxy(target)
originalDirector := proxy.Director
proxy.Director = func(req *http.Request) {
originalDirector(req)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/a":
r.URL.Path = "/b"
case "/b":
r.URL.Path = "/a"
}
proxy.ServeHTTP(w, r)
})
port := ":8081"
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatalf("Proxy failed to start: %v", err)
}
}
测试
外部流量

内部流量

浙公网安备 33010602011771号