【发布时间】:2018-01-11 20:43:51
【问题描述】:
我有一个位于集群前面的虚拟机。目前它正在运行 HAProxy(使用use-proxy-protocol: "true")。我的最终目标是允许与默认后端关联的 pod 能够读取实际的源客户端源 IP。
以下是打开use-proxy-protocol 的示例日志:
10.244.0.0 - [10.244.0.0] - - [10/Jan/2018:23:06:42 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" 367 0.002 [upstream-default-backend] 10.244.3.101:80 16 0.002 200
10.244.0.0 - [10.244.0.0] - - [10/Jan/2018:23:06:59 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "curl/7.54.0" 91 0.074 [upstream-default-backend] 10.244.3.101:80 16 0.074 200
10.244.0.0 - [10.244.0.0] - - [10/Jan/2018:23:09:51 +0000] "PROXY TCP4 127.0.0.1 127.0.0.1 43088 80" 400 173 "-" "-" 0 0.001 [] - - - -
10.244.0.0 - [10.244.0.0] - - [10/Jan/2018:23:09:59 +0000] "PROXY TCP4 127.0.0.1 127.0.0.1 43092 80" 400 173 "-" "-" 0 0.001 [] - - - -
10.244.0.0 - [10.244.0.0] - - [10/Jan/2018:23:10:09 +0000] "PROXY TCP4 127.0.0.1 127.0.0.1 43096 80" 400 173 "-" "-" 0 0.002 [] - - - -
I0110 23:11:42.050971 5 controller.go:211] backend reload required
I0110 23:11:42.054732 5 event.go:218] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"nginx-configuration", UID:"7539f546-f599-11e7-bee6-fa163e2f1153", APIVersion:"v1", ResourceVersion:"127044", FieldPath:""}): type: 'Normal' reason: 'UPDATE' ConfigMap ingress-nginx/nginx-configuration
I0110 23:11:42.138901 5 controller.go:220] ingress backend successfully reloaded...
127.0.0.1 - [127.0.0.1] - - [10/Jan/2018:23:11:56 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "curl/7.47.0" 86 0.003 [upstream-default-backend] 10.244.3.101:80 16 0.003 200
142.xx.xxx.xx - [142.xx.xxx.xx] - - [10/Jan/2018:23:15:50 +0000] "GET / HTTP/1.1" 500 21 "-" "curl/7.47.0" 78 0.020 [upstream-default-backend] 10.244.3.101:80 21 0.020 500
142.xx.xxx.xx - [142.xx.xxx.xx] - - [10/Jan/2018:23:16:02 +0000] "GET /platform/bitcoin HTTP/1.1" 200 45 "-" "curl/7.47.0" 94 0.165 [upstream-default-backend] 10.244.3.101:80 45 0.165 200
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:16:16 +0000] "GET / HTTP/1.1" 500 21 "-" "curl/7.54.0" 78 0.002 [upstream-default-backend] 10.244.3.101:80 21 0.002 500
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:16:30 +0000] "GET /platform/bitcoin HTTP/1.1" 200 45 "-" "curl/7.54.0" 94 0.002 [upstream-default-backend] 10.244.3.101:80 45 0.002 200
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:16:43 +0000] "GET /platform/bitcoin HTTP/1.1" 200 45 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" 370 0.049 [upstream-default-backend] 10.244.3.101:80 45 0.049 200
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:16:44 +0000] "GET /favicon.ico HTTP/1.1" 404 9 "http://142.xx.xxx.xx/platform/bitcoin" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" 324 0.013 [upstream-default-backend] 10.244.3.101:80 9 0.013 404
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:17:04 +0000] "GET /platform/bitcoin HTTP/1.1" 200 45 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" 370 0.002 [upstream-default-backend] 10.244.3.101:80 45 0.002 200
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:17:07 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" 367 0.002 [upstream-default-backend] 10.244.3.101:80 16 0.002 200
216.249.49.20 - [216.249.49.20] - - [10/Jan/2018:23:17:56 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "curl/7.54.0" 91 0.002 [upstream-default-backend] 10.244.3.101:80 16 0.002 200
Logs from 1/10/18 10:17 PM to 1/10/18 11:17 PM UTC
142.xx.xxx.xx 是 HAProxy 虚拟机的 IP
216.249.49.20 是来自大学的外部 IP。如您所见,入口 pod 可以读取从 HAProxy 传递的外部 IP,使用 use-proxy-protocol: "true" 就可以了。
但是当我 curl HAProxy vm 的地址时,我得到:
demonfuse@Williams-MacBook-Pro ~/N/K/NGINX> curl 142.xx.xxx.xx/platform/ping
pong2 10.244.2.6
10.244.2.6 是入口 pod 的 IP。 我现在确信 ingress-nginx 拥有真正的源 IP。
有没有办法通过 configmaps 将标头和真实源 IP 转发到 ingress-nginx 后面的 pod?据我所知here 大部分应该默认开启。
如何重现:
- 按照指南here在全新集群上安装ingress-nginx
- 将流量从 HAProxy/外部负载均衡器重定向到 ingress-nginx
- Go 脚本
如下:
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
//...
)
func main() {
app := iris.New()
app.Get("/platform/ping", func(ctx context.Context) {
fmt.Println("connected with " + ctx.RemoteAddr() + "!")
ctx.WriteString("pong2 " + ctx.RemoteAddr())
})
//...
app.Run(iris.Addr(":80"), iris.WithoutServerError(iris.ErrServerClosed))
}
其他信息:
环境:Internet -> Dedicated HAProxy VM -> Bare metal OVH K8S Cluster (1 master, 2 worker)
configmap.yaml
apiVersion: v1
data:
proxy-set-headers: "ingress-nginx/custom-headers"
use-proxy-protocol: "true"
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app: ingress-nginx
custom_headers.yaml
apiVersion: v1
data:
X-Forwarded-For: "142.xx.xxx.xxx"
kind: ConfigMap
metadata:
name: custom-headers
namespace: ingress-nginx
haproxy 配置
global
maxconn 4096
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
defaults
log global
mode http
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
frontend TestServerTest
bind 142.xx.xxx.xxx:80
mode tcp
default_backend TestServernodes
backend TestServernodes
mode tcp
server TestServer01 142.xx.xxx.xxx:80 send-proxy
我在哪里以及如何犯了错误?
我尝试将 X-Forwaded-For 与内部入口 pod IP、与入口服务关联的外部 IP 以及 HAProxy vm 的公共 IP 结合使用。到目前为止,卷曲 HAProxy 的外部 IP 仍然返回 pong2 10.244.2.6(入口 pod 的内部 IP)
【问题讨论】:
-
haproxy 是否配置为
tcp或http/https代理? ingress-nginx 的访问日志中有哪些源 IP? -
@Nickolay tcp(请参阅附加的 haproxy 配置)
-
@Nickolay
216.249.49.12 - [216.249.49.12] - - [11/Jan/2018:20:59:00 +0000] "GET /platform/ping HTTP/1.1" 200 16 "-" "curl/7.54.0" 91 0.003 [upstream-default-backend] 10.244.3.101:80 16 0.003 200例如216.249.49.12是客户端的源ip,10.244.3.101是默认后端的pod的IP
标签: nginx networking kubernetes haproxy devops