我正在单节点Kubernetes集群上运行Traefik 1.7.3,我试图从X-Forwarded-For
标头中获取真实的用户IP,但是我得到的是X-Forwarded-For: 10.244.0.1
,它是我的k8s群集中的IP。
这是我的Traefik部署和服务:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-conf
data:
traefik.toml: |
# traefik.toml
debug = true
logLevel = "DEBUG"
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
compress = true
[entryPoints.http.forwardedHeaders]
trustedIPs = [ "0.0.0.0/0" ]
entryPoint = "https"
[entryPoints.https]
address = ":443"
compress = true
[entryPoints.https.forwardedHeaders]
trustedIPs = [ "0.0.0.0/0" ]
[entryPoints.https.tls]
[acme]
email = "xxxx"
storage = "/acme/acme.json"
entryPoint = "https"
onHostRule = true
#caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
acmeLogging = true
[[acme.domains]]
main = "xxxx"
[acme.dnsChallenge]
provider = "route53"
delayBeforeCheck = 0
[persistence]
enabled = true
existingClaim = "pvc0"
annotations = {}
accessMode = "ReadWriteOnce"
size = "1Gi"
[kubernetes]
namespaces = ["default"]
[accessLog]
filePath = "/acme/access.log"
[accessLog.fields]
defaultMode = "keep"
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: default
labels:
k8s-app: traefik-ingress-lb
spec:
replicas: 1
selector:
matchLabels:
k8s-app: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
name: traefik-ingress-lb
env:
- name: AWS_ACCESS_KEY_ID
value: xxxx
- name: AWS_SECRET_ACCESS_KEY
value: xxxx
- name: AWS_REGION
value: us-west-2
- name: AWS_HOSTED_ZONE_ID
value: xxxx
ports:
- name: http
containerPort: 80
- name: admin
containerPort: 8080
args:
- --api
- --kubernetes
- --configfile=/config/traefik.toml
volumeMounts:
- mountPath: /config
name: config
- mountPath: /acme
name: acme
volumes:
- name: config
configMap:
name: traefik-conf
- name: acme
persistentVolumeClaim:
claimName: "pvc0"
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: default
spec:
externalIPs:
- x.x.x.x
externalTrafficPolicy: Local
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 443
name: https
- protocol: TCP
port: 8080
name: admin
type: NodePort
这是我的入口:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: headers-test
namespace: default
annotations:
ingress.kubernetes.io/proxy-body-size: 500m
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: xxxx
http:
paths:
- path: /
backend:
serviceName: headers-test
servicePort: 8080
我读到我只需要添加[entryPoints.http.forwardedHeaders]
和一个trustedIPs
的列表,但这似乎不起作用。我想念什么吗?
答案 0 :(得分:0)
如果将NodePort用于Traefik Ingress服务,则必须将service.spec.externalTrafficPolicy设置为“本地”。否则,当您的连接进入K8s集群时,您将拥有SNAT。如果传入连接不在同一节点上运行,则必须使用此SNAT将传入连接转发到您的Pod。
但是请注意,将service.spec.externalTrafficPolicy设置为“ Local”,只有执行Traefik Pod的节点会接受80、443、8080上的请求。没有从其他节点转发到Pod的请求。不再。连接到服务时,这可能会导致奇怪的延迟。为了避免这种情况,您的Traefik将需要在HA设置(DaemonSet)中运行。请记住,您需要K / V-Store来进行分布式Traefik设置,以使Letsencrypt正常工作。
如果service.spec.externalTrafficPolicy设置仍无法解决您的问题,则可能还需要将kubernetes覆盖网络配置为不执行任何SNAT。
service.spec.externalTrafficPolicy在这里得到了很好的解释: https://kubernetes.io/docs/tutorials/services/source-ip/