Kubernetes(k8s)-externalTrafficPolicy介绍和应用

作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

图片

我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。

我们在svc的时候,svc有一种类型叫NodePort,它是会在每个node上都有对应的iptables规则去请求拦截,如果我们有20个,甚至200个节点的时候,我们应该去访问哪一个节点?或者当我们使用LoadBalance的时候,它必须要有后端RS,我们把这个200个节点都作为后端RS么,如果是这样管理就会比较复杂,好在Kubernetes给我们提供了一个字段叫做:externalTrafficPolicy,它不仅可以规定掉刚才问题,还可以规避掉经过NAT转换以后的源ip丢失的问题。

externalTrafficPolicy 是 Kubernetes 中 Service 资源的一个属性,它主要用于控制 Service 如何将流量路由到 Pod。这个属性对于类型为 LoadBalancer 和 NodePort 的服务特别重要,因为它影响客户端 IP 的保留以及流量的负载均衡方式。

externalTrafficPolicy 有两个可能的值:

  1. Cluster(默认)

    • 当 externalTrafficPolicy 设置为 Cluster 时,Kubernetes 的代理会从所有健康节点接收流量,并将其转发到后端 Pod。

    • 这意味着流量可能会被路由到任何节点上的任意一个合适的 Pod,不论该 Pod 是否在接收到请求的那个节点上运行。

    • 客户端的真实 IP 可能会在转发过程中丢失,因为流量通常通过内部 IP 在集群内传输。

  2. Local

    • 如果 externalTrafficPolicy 设置为 Local,那么只有运行了属于该服务的 Pod 的节点才会接收来自外部的流量。

    • 这种设置可以确保客户端的真实源 IP 传递给后端 Pod,因为流量直接到达承载 Pod 的节点。

    • 如果没有 Pod 在某个节点上运行,而流量指向了该节点,流量会被丢弃。这可能导致较低的资源利用率,但提供了更好的网络性能和保持客户端 IP 地址的能力。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort  # 添加此行以更改服务类型为 NodePort,未添加则是ClusterIP
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80        # 服务的集群内部端口
      targetPort: 80  # Pod 上的应用程序端口
      nodePort: 30008 # 可选:指定 NodePort 的端口号,如果不指定则自动分配

这里我们还是复用我们前面的配置,虽然我们并没有在svc的yaml文件里面定义externalTrafficPolicy,但是查看这个svc的详细信息,是可以看到这个字段的,并且自动给我们添加了默认值Cluster。

[root@master01 svc]# kubectl  get svc my-service -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2025-01-15T15:30:12Z"
  name: my-service
  namespace: default
  resourceVersion: "801401"
  selfLink: /api/v1/namespaces/default/services/my-service
  uid: 0b347fa0-a571-41d6-9fd5-ce960114f4e8
spec:
  clusterIP: 10.111.230.179
  clusterIPs:
  - 10.111.230.179
  externalTrafficPolicy: Cluster #自动添加的字段
  internalTrafficPolicy: Cluster #也是自动添加的,但是今天不讲这个字段
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30008
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

我们无论通过集群外访问还是集群内外访问,后端nginx获取的客户端ip地址都是CNI插件给我们分配的节点ip地址,如果我们的应用,需要客户端真实ip,使用这个配置则无法满足要求。

10.244.0.0 - - [15/Jan/2025:15:37:58 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.0.0 - - [15/Jan/2025:15:38:07 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.1.1 - - [15/Jan/2025:15:38:22 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.1.1 - - [15/Jan/2025:15:38:23 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

​​​​​​​

当我们把externalTrafficPolicy修改成Local,集群外访问已经可以获得客户端真实ip地址,集群内访问还是无法获取真实ip,不过这个需求一般很少,有兴趣可以下去研究下。

192.168.31.201 - - [15/Jan/2025:15:41:53 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.0.0 - - [15/Jan/2025:15:42:04 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.0.0 - - [15/Jan/2025:15:42:49 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

​​​​​​

#Pod所在节点iptables规则,正常转发
-A KUBE-XLB-FXIYY6OHUSNBITIX -m comment --comment "default/my-service" 
-j KUBE-SEP-RPL3ZC3VS2WNO5G6
#Pod不在节点的iptables规则,会拒绝请求
-A KUBE-XLB-FXIYY6OHUSNBITIX -m comment --comment "default/my-service 
has no local endpoints" -j KUBE-MARK-DROP

​​​​​​​

简单点说,现在的NodePort只有Pod所在节点能使用NodeIP+NodePort访问,其他没有Pod则不能访问,这样就可以减少LB的后端。比如200个节点,某Pod跑了5个副本(在不同的node),那么这个LB的后端就只有这个5个机器,就不会出现后端200个的情况,当然LB还必须要具备自动更新RS后端能力,因为Pod漂移会导致这个后端变更。

运维小路

一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!

关注微信公众号《运维小路》获取更多内容。

443446是同样的证书,修改成这样可行吗: apiVersion: v1 kind: Service metadata: name: vms-core-server-cloud-access-pa-fw-v1 namespace: dev3-vms annotations: service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: “Category=dev,Product=vms,ServiceType=biz” service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ap-southeast-1:242777933053:certificate/74ff9ed2-8bcc-492d-b845-15308bace4e8 service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: “ELBSecurityPolicy-TLS13-1-2-Res-2021-06” service.beta.kubernetes.io/aws-load-balancer-ssl-ports: “443” service.beta.kubernetes.io/aws-load-balancer-type: “external” service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: “ip” service.beta.kubernetes.io/aws-load-balancer-scheme: “internet-facing” labels: app.kubernetes.io/name: vms-core-server region: ap-southeast-1 spec: loadBalancerClass: service.k8s.aws/nlb selector: app.kubernetes.io/name: vms-core-server region: ap-southeast-1 ports: - port: 443 protocol: TCP name: cloud-access-443 targetPort: cloud-access - port: 446 protocol: TCP name: cloud-access-446 targetPort: cloud-access-short type: LoadBalancer externalTrafficPolicy: Cluster apiVersion: v1 kind: Service metadata: name: vms-core-server-cloud-access-pa-fw-v2 namespace: dev3-vms annotations: service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: “Category=dev,Product=vms,ServiceType=biz” service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ap-southeast-1:242777933053:certificate/e667c161-e7b0-4faa-a21e-23df5cb5f2d4 service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: “ELBSecurityPolicy-TLS13-1-2-Res-2021-06” service.beta.kubernetes.io/aws-load-balancer-ssl-ports: “443” service.beta.kubernetes.io/aws-load-balancer-type: “external” service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: “ip” service.beta.kubernetes.io/aws-load-balancer-scheme: “internet-facing” labels: app.kubernetes.io/name: vms-core-server region: ap-southeast-1 spec: loadBalancerClass: service.k8s.aws/nlb selector: app.kubernetes.io/name: vms-core-server region: ap-southeast-1 ports: - port: 443 protocol: TCP name: cloud-access-443 targetPort: cloud-access - port: 446 protocol: TCP name: cloud-access-446 targetPort: cloud-access-short type: LoadBalancer externalTrafficPolicy: Cluster
最新发布
10-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值