我配置了一个外部HAproxy,以及一个Kubernetes节点集群(1个主节点和3个工作节点)。
Haproxy配置为透明模式。我在Haproxy后面的节点上获得客户端的真实的IP地址。这在kubernetes主节点上使用tcpdump进行验证,并尝试从外部连接Haproxy。所有其他工作节点也获得真实IP地址。
现在,我希望部署在K8s集群中的所有Pod也能收到客户端的真实的IP地址。至少可以说,这是有问题的(Kubernetes,你能简单一点吗?)
我已经遵循了这个例子:https://kubernetes.io/docs/tutorials/services/source-ip/
使用nodeport服务,并且该服务使用以下修补程序修补:kubectl patch svc nodeport -p '{"spec":{"externalTrafficPolicy":"Local"}}'
我得到了客户的真实的IP。
问题是这个例子没有提到如果您通过Ingress控制器进行连接该怎么做。
我已经临时创建了一个入口.yaml(我也在入口控制器使用tls终止)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ip-ingress
namespace: default
spec:
tls:
- hosts:
- "myip.mydomain.com"
secretName: filewithcertificate
ingressClassName: nginx
rules:
- host: "myip.mydomain.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nodeport
port:
number: 8080
以下是对命令的响应:curl -k --connect-timeout 1 -s https://myip.mydomain.com
CLIENT VALUES:
client_address=10.244.1.1 <-- ip internal to the cluster
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://myip.mydomain.com:8080/
SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001
HEADERS RECEIVED:
accept=*/*
host=myip.mydomain.com
user-agent=curl/7.74.0
x-forwarded-for=X.X.X.122 <-- real ip of the curl client
x-forwarded-host=myip.mydomain.com
x-forwarded-port=443
x-forwarded-proto=https
x-forwarded-scheme=https
x-real-ip=X.X.X.122 <-- real ip of the curl client
x-request-id=0d67fea66435e387015cf3e9b9700c0e
x-scheme=https
BODY:
-no body in request-
让我们忽略一个事实,即Haproxy是如此善良,用我的真实IP填充x-real-ip报头,但如果可以的话,我希望避免使用这些报头来获取真实IP。事实是,当使用入口规则时,Pod内的client_address是不正确的。
我想得到的结果是:
CLIENT VALUES:
client_address=X.X.X.122 <-- real client ip here....
command=GET
1条答案
按热度按时间8mmmxcuj1#
默认情况下,nginx入口控制器不保留客户端IP地址,您需要激活代理协议:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-proxy-protocol
您需要向入口yaml定义添加注解:
激活此选项后,接收http请求的Pod将收到以下报头之一:
X-Real-IP
或X-Forwarded-For
。