Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >获取客户端访问真实IP

获取客户端访问真实IP

作者头像
我是阳明
发布于 2020-06-15 09:51:04
发布于 2020-06-15 09:51:04
3.5K00
代码可运行
举报
文章被收录于专栏:k8s技术圈k8s技术圈
运行总次数:0
代码可运行

通常,当 Kubernetes 集群内的客户端连接到服务的时候,是支持服务的 Pod 可以获取到客户端的 IP 地址的,但是,当通过节点端口接收到连接时,由于对数据包执行了源网络地址转换(SNAT),因此数据包的源 IP 地址会发生变化,后端的 Pod 无法看到实际的客户端 IP,对于某些应用来说是个问题,比如,nginx 的请求日志就无法获取准确的客户端访问 IP 了,比如下面我们的应用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

直接创建后可以查看 nginx 服务被自动分配了一个 32761 的 NodePort 端口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        28d
nginx        NodePort    10.106.190.194   <none>        80:32761/TCP   48m
$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
nginx-54f57cf6bf-nwtjp            1/1     Running   0          3m      10.244.3.15    ydzs-node3   <none>           <none>
nginx-54f57cf6bf-ptvgs            1/1     Running   0          2m59s   10.244.2.13    ydzs-node2   <none>           <none>
nginx-54f57cf6bf-xhs8g            1/1     Running   0          2m59s   10.244.1.16    ydzs-node1   <none>           <none>

我们可以看到这个3个 Pod 被分配到了 3 个不同的节点,这个时候我们通过 master 节点的 NodePort 端口来访问下我们的服务,因为我这里只有 master 节点可以访问外网,这个时候我们查看 nginx 的 Pod 日志可以看到其中获取到的 clientIP 是 10.151.30.11,其实是 master 节点的内网 IP,并不是我们期望的真正的浏览器端访问的 IP 地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ kubectl logs -f nginx-54f57cf6bf-xhs8g
10.151.30.11 - - [07/Dec/2019:16:44:38 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"

这个是因为我们 master 节点上并没有对应的 Pod,所以通过 master 节点去访问应用的时候必然需要额外的网络跳转才能到达其他节点上 Pod,在跳转过程中由于对数据包进行了 SNAT,所以看到的是 master 节点的 IP。这个时候我们可以在 Service 设置 externalTrafficPolicy 来减少网络跳数:

代码语言:javascript
代码运行次数:0
运行
复制
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spec:
  externalTrafficPolicy: Local

如果 Service 中配置了 externalTrafficPolicy=Local,并且通过服务的节点端口来打开外部连接,则 Service 会代理到本地运行的 Pod,如果本地没有本地 Pod 存在,则连接将挂起,比如我们这里设置上该字段更新,这个时候我们去通过 master 节点的 NodePort 访问应用是访问不到的,因为 master 节点上并没有对应的 Pod 运行,所以需要确保负载均衡器将连接转发给至少具有一个 Pod 的节点。

但是需要注意的是使用这个参数有一个缺点,通常情况下,请求都是均匀分布在所有 Pod 上的,但是使用了这个配置的话,情况就有可能不一样了。比如我们有两个节点上运行了 3 个 Pod,假如节点 A 运行一个 Pod,节点 B 运行两个 Pod,如果负载均衡器在两个节点间均衡分布连接,则节点 A 上的 Pod 将接收到所有请求的 50%,但节点 B 上的两个 Pod 每个就只接收 25% 。

由于增加了externalTrafficPolicy: Local这个配置后,接收请求的节点和目标 Pod 都在一个节点上,所以没有额外的网络跳转(不执行 SNAT),所以就可以拿到正确的客户端 IP,如下所示我们把 Pod 都固定到 master 节点上:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      tolerations:
      - operator: "Exists"
      nodeSelector:
        kubernetes.io/hostname: ydzs-master
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
 externalTrafficPolicy: Local
  selector:
    app: nginx
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

更新服务后,然后再通过 NodePort 访问服务可以看到拿到的就是正确的客户端 IP 地址了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ kubectl logs -f nginx-ddc8f997b-ptb7b
182.149.166.11 - - [07/Dec/2019:17:03:43 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
在k8s中获取客户端真实IP实践
当需明确服务请求来源以满足业务需求时,则需后端服务能够准确获取请求客户端的真实源 IP。例如以下场景:
chen1900s
2022/07/17
7.1K0
kubernetes Service:让客户端发现pod并与之通信
service是k8s中的一个重要概念,主要是提供负载均衡和服务自动发现。 Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
没有故事的陈师傅
2020/06/09
3.1K0
kubernetes Service:让客户端发现pod并与之通信
Kubernetes 中数据包的生命周期 -- 第 3 部分
本文是 Kubernetes 中数据包的生命周期系列文章的第 3 部分。我们将讨论 Kubernetes 的 kube-proxy 组件如何使用 iptables 来控制流量。了解 kube-proxy 在 Kubernetes 环境中的作用以及它如何使用 iptables 来控制流量非常重要。
Se7en258
2022/06/24
1.1K0
Kubernetes 中数据包的生命周期 -- 第 3 部分
Kubernetes HPA 详解
在前面的学习中我们使用用一个 kubectl scale 命令可以来实现 Pod 的扩缩容功能,但是这个毕竟是完全手动操作的,要应对线上的各种复杂情况,我们需要能够做到自动化去感知业务,来自动进行扩缩容。为此,Kubernetes 也为我们提供了这样的一个资源对象:HorizontalPodAutoscaling(Pod水平自动伸缩),简称 HPA,HPA 通过监控分析一些控制器控制的所有 Pod 的负载变化情况来确定是否需要调整 Pod 的副本数量,这是 HPA 最基本的原理:
我是阳明
2020/06/15
4.5K0
Kubernetes HPA 详解
【K8S专栏】Kubernetes应用访问管理
在Kubernetes中,提供了Service和Ingress两种对象来实现应用间访问或外部对集群应用访问,这两种对象在实际的工作中会时长使用,非常重要的对象。
没有故事的陈师傅
2022/12/06
1.6K0
【K8S专栏】Kubernetes应用访问管理
如何在容器服务中获取客户端真实源IP
jokey,腾讯云容器产品工程师,热衷于云原生领域。目前主要负责腾讯云TKE 的售中、售后的技术支持,根据客户需求输出合理技术方案与最佳实践。 适用范围:腾讯云容器服务(Tencent Kubernetes Engine ,TKE), 以下简称 TKE。 为什么需要获取客户端真实源 IP? 当需要能感知到服务请求来源去满足一些业务需求时,就需要后端服务能准确获取到请求客户端的真实源 IP, 比如以下场景: 对服务请求的来源有做审计的需求,如异地登陆告警。 针对安全攻击或安全事件溯源需求,如 APT 攻击、
腾讯云原生
2020/10/19
7K4
kubernetes Service:让客户端发现pod并与之通信
  Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
yaohong
2019/09/09
2.9K0
[译]数据包在 Kubernetes 中的一生(3)
https://dramasamy.medium.com/life-of-a-packet-in-kubernetes-part-3-dd881476da0f
CNCF
2021/07/07
9910
【k8s】service服务和job服务
Xiongan-桃子
2023/06/10
3890
【k8s】service服务和job服务
深入玩转K8S之外网如何访问业务应用(nginx-ingress篇)
前面的文章介绍了如何安装kubernetes集群,集群部署完毕之后就可以在上面部署服务了。服务部署完之后如何访问集群中的服务呢?  访问部署在kubernetes中的服务有两种情况,一种是在kubernetes集群内部访问,另一种是在集群外部访问服务。
DevinGeng
2019/04/09
2.1K0
在 Kubernetes Pod 中如何获取客户端的真实 IP
这里选择 containous/whoami 作为后端服务镜像。在 Dockerhub 的介绍页面,可以看到访问其 80 端口时,会返回客户端的相关信息。在代码中,我们可以在 Http 头部中拿到这些信息。
CNCF
2021/03/15
4.8K0
在 Kubernetes Pod 中如何获取客户端的真实 IP
Kubernetes(k8s)-externalTrafficPolicy介绍和应用
作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
运维小路
2025/03/12
590
Kubernetes(k8s)-externalTrafficPolicy介绍和应用
附020.Nginx-ingress部署及使用
[root@master01 ingress]# git clone https://github.com/nginxinc/kubernetes-ingress/
木二
2020/06/04
1.2K0
k8s生产实践之获取客户端真实IP
通常web应用获取用户客户端的真实ip一个很常见的需求,例如将用户真实ip取到之后对用户做白名单访问限制、将用户ip记录到数据库日志中对用户的操作做审计等等
仙人技术
2021/08/31
4K0
k8s生产实践之获取客户端真实IP
K8s的Service详解
● 在kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这就意味着不方便直接采用Pod的IP对服务进行访问。
大忽悠爱学习
2022/09/28
1.3K0
K8s的Service详解
service mesh框架对比_k8s外部访问内部service
在kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这就意味着不方便直接采用Pod的IP对服务进行访问。
全栈程序员站长
2022/09/22
8780
service mesh框架对比_k8s外部访问内部service
kubernetes核心实战(八)--- service
13、service 四层网络负载 创建 [root@k8s-master-node1 ~/yaml/test]# [root@k8s-master-node1 ~/yaml/test]# vim my-app.yaml [root@k8s-master-node1 ~/yaml/test]# cat my-app.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: my-dep name: my-dep s
小陈运维
2022/08/19
1990
kubernetes核心实战(八)--- service
k8s集群客户端工具kubectl
由于网络原因,建议提前准备好容器镜像。本示例使用nginx:latest容器镜像。 编写用于创建Pod资源清单文件02-create-pod.yaml
兜兜转转
2023/03/08
1.3K0
k8s集群客户端工具kubectl
K8S基础搭建使用
由上可见,需要本地镜像仓库需要 pod-infrastructure:latest 这个 pod 基础镜像,所以需要在拉取镜像 docker pull tianyebj/pod-infrastructure,并且 push 到本地镜像仓库
cuijianzhe
2022/06/14
5360
K8S基础搭建使用
kubernetes 上手指南:概念篇
今天的主题:kubernetes 概念篇,通过一些示例,学习 kubernetes(k8s) 的一些核心概念。
谢伟
2019/12/13
7670
相关推荐
在k8s中获取客户端真实IP实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验