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

image

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)
	}
}

测试

外部流量

image

内部流量

image

posted on 2026-04-12 12:35  王景迁  阅读(4)  评论(0)    收藏  举报

导航