docker - Kubernetes 上的 Traefik 传入连接上的客户端 IP 错误
问题描述
我在 Kubernetes 上运行 Traefik,我创建了一个具有以下配置的 Ingress:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whitelist-ingress
annotations:
kubernetes.io/ingress.class: traefik
traefik.frontend.rule.type: PathPrefix
traefik.ingress.kubernetes.io/whitelist-source-range: "10.10.10.10/32, 10.10.2.10/23"
ingress.kubernetes.io/whitelist-x-forwarded-for: "true"
traefik.ingress.kubernetes.io/preserve-host: "true"
spec:
rules:
- host:
http:
paths:
- path: /endpoint
backend:
serviceName: endpoint-service
servicePort: endpoint-port
---
当我在上述端点上执行 POST 时,Traefik 会记录传入 IP 为 172.16.0.1,因此不会触发我的白名单。做一个 ifconfig 我看到 IP 属于 Docker
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.26.0.1 netmask 255.255.0.0 broadcast 172.26.255.255
如何保留原始 IP 而不是 docker 一?
编辑
Traefik 公开为 LoadBalancer,端口为 443 over SSL
这是它的 yml 配置
---
kind: Service
apiVersion: v1
metadata:
name: traefik
annotations: {}
# service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
spec:
selector:
k8s-app: traefik-ingress
ports:
- protocol: TCP
port: 80
targetPort: 80
name: http
- protocol: TCP
port: 443
targetPort: 443
name: https
type: LoadBalancer
externalTrafficPolicy: Local
externalIPs:
- <machine-ip>
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: default
labels:
k8s-app: traefik-ingress
spec:
replicas: 2
selector:
matchLabels:
k8s-app: traefik-ingress
template:
metadata:
labels:
k8s-app: traefik-ingress
name: traefik-ingress
spec:
hostNetwork: true
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 35
volumes:
- name: proxy-certs
secret:
secretName: proxy-certs
- name: traefik-configmap
configMap:
name: traefik-configmap
containers:
- image: traefik:1.7.6
name: traefik-ingress
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 200m
memory: 900Mi
requests:
cpu: 25m
memory: 512Mi
livenessProbe:
failureThreshold: 2
httpGet:
path: /ping
port: 80
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
failureThreshold: 2
httpGet:
path: /ping
port: 80
scheme: HTTP
periodSeconds: 5
volumeMounts:
- mountPath: "/ssl"
name: "proxy-certs"
- mountPath: "/config"
name: "traefik-configmap"
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: dashboard
containerPort: 8080
args:
- --logLevel=DEBUG
- --configfile=/config/traefik.toml
---
如您所见,这里是 kubectl get svc 的输出
traefik LoadBalancer 10.100.116.42 <machine-ip> 80:30222/TCP,443:31578/TCP <days-up>
请注意,Traefik 运行在单节点 kubernetes 集群中(同一节点上的 master/worker)。
解决方案
在 aws 上的 LoadBalancer 服务类型 doc ssl 支持中,您可以阅读以下语句:
HTTP 和 HTTPS 将选择第 7 层代理:ELB 将终止与用户的连接,解析 headers 并使用用户的 IP 地址注入 X-Forwarded-For header(pods 只会看到另一端 ELB 的 IP 地址其连接)在转发请求时。
因此,如果您将以下注释添加到您的 traeffik 服务:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https
它应该与ingress.kubernetes.io/whitelist-x-forwarded-for: "true"
入口配置中存在的注释一起使用,并且转发的标头由 aws 负载均衡器添加。
免责声明:我没有测试过该解决方案。
问候。
推荐阅读
- katalon-studio - 在新的 Katalon 项目中导入现有的测试用例
- django - 如何过滤具有完全匹配词的查询集数据?
- c# - 异步自定义视图模型验证。.net 核心无法通行?为什么?
- python - Python - 指定增量值的循环的最终通过
- openstreetmap - OSMnx:使用替代基础架构创建自定义查询
- html - 将元素展开到容器末尾
- c - Ubuntu x86-64:将缓冲区链接到在预定义地址中创建的内存部分
- php - 如何从 csv 中删除引号?
- django - 在 Django 中导入外部库(比如 pytube)
- google-sheets - 具有条件的上一个日期 Google 电子表格公式