一.现象
公司kubenetes生产环境使用的ingress控制器是traefik,默认是通过deployment部署的,现在研发上反馈不能获取客户的真实源IP地址,通过x_forward_for获取的IP地址都是kubernetes集群内部的IP地址。
二.解决思路
通过查找traefik的官方文档
Traefik EntryPoints Documentation - Traefik
traefik传输客户源地址到后端需要配置Forwarded Headers参数,用于x_forwarded_for保存客户源IP地址
具体配置如下
yaml格式,用于启用的时候指定配置文件
- ## Static configuration
- entryPoints:
- web:
- address: ":80"
- forwardedHeaders:
- insecure: true
TOML格式,用于traefik启动的时候指定配置文件,这个文件在kubernetes中可以以comfigmap存在
- ## Static configuration
- [entryPoints]
- [entryPoints.web]
- address = ":80"
-
- [entryPoints.web.forwardedHeaders]
- insecure = true
命名行格式
- --entryPoints.web.address=:80
- --entryPoints.web.forwardedHeaders.insecure
三.问题处理
1.公司现有环境配置
- ---
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- annotations:
- meta.helm.sh/release-name: traefik
- meta.helm.sh/release-namespace: default
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- name: traefik
- namespace: default
- resourceVersion: '505763774'
- spec:
- progressDeadlineSeconds: 600
- replicas: 6
- revisionHistoryLimit: 10
- selector:
- matchLabels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/name: traefik
- strategy:
- rollingUpdate:
- maxSurge: 1
- maxUnavailable: 1
- type: RollingUpdate
- template:
- metadata:
- creationTimestamp: null
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- spec:
- containers:
- - args:
- - '--global.checknewversion'
- - '--global.sendanonymoususage'
- - '--entryPoints.traefik.address=:9000/tcp'
- - '--entryPoints.web.address=:8000/tcp'
- - '--entryPoints.websecure.address=:8443/tcp'
- - '--api.dashboard=true'
- - '--ping=true'
- - '--providers.kubernetescrd'
- - '--providers.kubernetesingress'
- image: 'traefik:2.3.3'
- imagePullPolicy: IfNotPresent
- livenessProbe:
- failureThreshold: 3
- httpGet:
- path: /ping
- port: 9000
- scheme: HTTP
- initialDelaySeconds: 10
- periodSeconds: 10
- successThreshold: 1
- timeoutSeconds: 2
- name: traefik
- ports:
- - containerPort: 9000
- name: traefik
- protocol: TCP
- - containerPort: 8000
- name: web
- protocol: TCP
- - containerPort: 8443
- name: websecure
- protocol: TCP
- readinessProbe:
- failureThreshold: 1
- httpGet:
- path: /ping
- port: 9000
- scheme: HTTP
- initialDelaySeconds: 10
- periodSeconds: 10
- successThreshold: 1
- timeoutSeconds: 2
- resources: {}
- securityContext:
- capabilities:
- drop:
- - ALL
- readOnlyRootFilesystem: true
- runAsGroup: 65532
- runAsNonRoot: true
- runAsUser: 65532
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- - mountPath: /data
- name: data
- - mountPath: /tmp
- name: tmp
- dnsPolicy: ClusterFirst
- restartPolicy: Always
- schedulerName: default-scheduler
- securityContext:
- fsGroup: 65532
- serviceAccount: traefik
- serviceAccountName: traefik
- terminationGracePeriodSeconds: 60
- volumes:
- - emptyDir: {}
- name: data
- - emptyDir: {}
- name: tmp
- status:
- availableReplicas: 6
- conditions:
- - lastTransitionTime: '2022-10-10T07:58:50Z'
- lastUpdateTime: '2022-10-10T07:58:50Z'
- message: Deployment has minimum availability.
- reason: MinimumReplicasAvailable
- status: 'True'
- type: Available
- - lastTransitionTime: '2020-11-25T22:53:59Z'
- lastUpdateTime: '2022-11-17T10:44:40Z'
- message: ReplicaSet "traefik-54bf67c74d" has successfully progressed.
- reason: NewReplicaSetAvailable
- status: 'True'
- type: Progressing
- observedGeneration: 13
- readyReplicas: 6
- replicas: 6
- updatedReplicas: 6
-
- ---
- apiVersion: v1
- kind: Service
- metadata:
- annotations:
- meta.helm.sh/release-name: traefik
- meta.helm.sh/release-namespace: default
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- name: traefik
- namespace: default
- resourceVersion: '505762379'
- spec:
- clusterIP: 10.96.252.108
- externalTrafficPolicy: Cluster
- ports:
- - name: web
- nodePort: 30079
- port: 80
- protocol: TCP
- targetPort: web
- selector:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/name: traefik
- sessionAffinity: None
- type: NodePort
- status:
- loadBalancer: {}
-
发现trafik启动的参数里面没有指定配置文件,也没有以comfigmap形式存在,所以只能考虑通过添加启动参数的方式(即命令行方式)解决问题
2.解决问题
在deployment部署中的traefik启动参数中添加 - '--entrypoints.web.forwardedHeaders.insecure'和- '--entrypoints.websecure.forwardedHeaders.insecure'启动参数,其中标红的web和websecure根据--entryPoints.web.address=:8000/tcp和--entryPoints.websecure.address=:8443/tcp要保持一致,有可能不一样。
修改后的derloyment的yaml文件如下:
- ---
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- annotations:
- meta.helm.sh/release-name: traefik
- meta.helm.sh/release-namespace: default
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- name: traefik
- namespace: default
- resourceVersion: '505763774'
- spec:
- progressDeadlineSeconds: 600
- replicas: 6
- revisionHistoryLimit: 10
- selector:
- matchLabels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/name: traefik
- strategy:
- rollingUpdate:
- maxSurge: 1
- maxUnavailable: 1
- type: RollingUpdate
- template:
- metadata:
- creationTimestamp: null
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- spec:
- containers:
- - args:
- - '--global.checknewversion'
- - '--global.sendanonymoususage'
- - '--entryPoints.traefik.address=:9000/tcp'
- - '--entryPoints.web.address=:8000/tcp'
- - '--entryPoints.websecure.address=:8443/tcp'
- - '--api.dashboard=true'
- - '--ping=true'
- - '--providers.kubernetescrd'
- - '--providers.kubernetesingress'
- - '--entrypoints.web.forwardedHeaders.insecure'
- - '--entrypoints.websecure.forwardedHeaders.insecure'
- image: 'traefik:2.3.3'
- imagePullPolicy: IfNotPresent
- livenessProbe:
- failureThreshold: 3
- httpGet:
- path: /ping
- port: 9000
- scheme: HTTP
- initialDelaySeconds: 10
- periodSeconds: 10
- successThreshold: 1
- timeoutSeconds: 2
- name: traefik
- ports:
- - containerPort: 9000
- name: traefik
- protocol: TCP
- - containerPort: 8000
- name: web
- protocol: TCP
- - containerPort: 8443
- name: websecure
- protocol: TCP
- readinessProbe:
- failureThreshold: 1
- httpGet:
- path: /ping
- port: 9000
- scheme: HTTP
- initialDelaySeconds: 10
- periodSeconds: 10
- successThreshold: 1
- timeoutSeconds: 2
- resources: {}
- securityContext:
- capabilities:
- drop:
- - ALL
- readOnlyRootFilesystem: true
- runAsGroup: 65532
- runAsNonRoot: true
- runAsUser: 65532
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
- volumeMounts:
- - mountPath: /data
- name: data
- - mountPath: /tmp
- name: tmp
- dnsPolicy: ClusterFirst
- restartPolicy: Always
- schedulerName: default-scheduler
- securityContext:
- fsGroup: 65532
- serviceAccount: traefik
- serviceAccountName: traefik
- terminationGracePeriodSeconds: 60
- volumes:
- - emptyDir: {}
- name: data
- - emptyDir: {}
- name: tmp
- status:
- availableReplicas: 6
- conditions:
- - lastTransitionTime: '2022-10-10T07:58:50Z'
- lastUpdateTime: '2022-10-10T07:58:50Z'
- message: Deployment has minimum availability.
- reason: MinimumReplicasAvailable
- status: 'True'
- type: Available
- - lastTransitionTime: '2020-11-25T22:53:59Z'
- lastUpdateTime: '2022-11-17T10:44:40Z'
- message: ReplicaSet "traefik-54bf67c74d" has successfully progressed.
- reason: NewReplicaSetAvailable
- status: 'True'
- type: Progressing
- observedGeneration: 13
- readyReplicas: 6
- replicas: 6
- updatedReplicas: 6
-
- ---
- apiVersion: v1
- kind: Service
- metadata:
- annotations:
- meta.helm.sh/release-name: traefik
- meta.helm.sh/release-namespace: default
- labels:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: traefik
- helm.sh/chart: traefik-9.11.0
- name: traefik
- namespace: default
- resourceVersion: '505762379'
- spec:
- clusterIP: 10.96.252.108
- externalTrafficPolicy: Cluster
- ports:
- - name: web
- nodePort: 30079
- port: 80
- protocol: TCP
- targetPort: web
- selector:
- app.kubernetes.io/instance: traefik
- app.kubernetes.io/name: traefik
- sessionAffinity: None
- type: NodePort
- status:
- loadBalancer: {}
3.验证测试
通过和研发和业务验证测试,通过x_forwarded_for获取的客户端源Ip地址格式如下

其中第一个公网IP地址是客户的真实IP地址,其他几个是经过的k8s节点和pod的IP地址,至此解决业务上获取真实客户IP地址的需求。