背景
某些应用会根据HTTP Header中的X-Real-IP和X-Forwarded-Host这两个字段来对客户端做一些特殊处理,如限流、分流等。当这些应用通过容器方式部署在k8s中时,这两个Header字段的值受ingress的影响。听同事提到,ingress并未将client-ip写入这两个字段,这就可能引起后端应用不能触发原本的控制逻辑。
有一篇参考的文章:https://blog.csdn.net/weixin_34150224/article/details/89545499
本文是去测试验证ingress的行为,也操练一把容器相关的部署。
环境
rancher:v2.3.2
docker:18.9.3
image build
构建一个基于flask的python http server应用,提供http协议的服务。
deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app
spec:
replicas: 1
selector:
matchLabels:
app: flask-app
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-app
image: "harbor.hwwt2.com/test/flask\_app:latest"
command: \["/bin/sh"\]
args: \["-c", "while true;do sleep 1;done"\]
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
#dnsPolicy: ClusterFirstWithHostNet
hostNetwork: false
restartPolicy: Always
Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: flask
spec:
rules:
- host: flask.com
http:
paths:
- backend:
serviceName: flask-app
servicePort: 80
path: /
service
apiVersion: v1
kind: Service
metadata:
annotations:
app: flask-app
name: flask-app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
app: flask-app
sessionAffinity: None
type: ClusterIP
app.py
from flask import Flask
app = Flask(\_\_name\_\_)
@app.route("/")
def index():
return "<h1 style='color:red'>Hello World</h1>"
if \_\_name\_\_ == "\_\_main\_\_":
app.run()
验证
在容器内抓包: tcpdump tcp port 5000 -i eth0 -w ./app.pcap
把包从容器里拿出来,看收包的http头如下:
看下当前环境下ingress的实现是openresty,看下openresty对头的处理:
set $best\_http\_host $http_host;
proxy_set_header X-Request-ID $req_id;
proxy_set_header X-Real-IP $the_real_ip;
proxy_set_header X-Forwarded-For $the_real_ip;
proxy_set_header X-Forwarded-Host $best_http_host;
可以看到openresty为请求增加了一个X-Request-ID字段,使用http_host为X-Real-IP和X-Forwarded-For、X-Forwarded-Host赋值
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。