环境描述

生产环境通过gitlab-running实现自动化发布业务,现需要收集客户端的真实ip,需要将externaltrafficpolicy改为lacal模式(原来是cluster模式),前天开发反映无法发布业务(镜像拉取不成功)。想到就改动过externaltrafficpolicy所以考虑到了local模式和cluster模式的区别。

externaltrafficpolicy作用阐述

把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持【当我们的集群服务需要访问k8s之外的集群时,可以选择这种类型,然后把外部服务的IP及端口写入到k8s服务中来,k8s的代理将会帮助我们访问到外部的集群服务】

1 什么是external-traffic-policy

在k8s的Service对象(申明一条访问通道)中,有一个“externalTrafficPolicy”字段可以设置。有2个值可以设置:Cluster或者Local。

1)Cluster表示:流量可以转发到其他节点上的Pod。

2)Local表示:流量只发给本机的Pod。

图示一下:

2 这2种模式有什么区别

存在这2种模式的原因就是,当前节点的Kube-proxy在转发报文的时候,会不会保留原始访问者的IP。

2.1 选择(1)Cluster

注:这个是默认模式,Kube-proxy不管容器实例在哪,公平转发。

Kube-proxy转发时会替换掉报文的源IP。即:容器收的报文,源IP地址,已经被替换为上一个转发节点的了。



原因是Kube-proxy在做转发的时候,会做一次SNAT (source network address translation),所以源IP变成了节点1的IP地址。

ps:snat确保回去的报文可以原路返回,不然回去的路径不一样,客户会认为非法报文的。(我发给张三的,怎么李四给我回应?丢弃!)

这种模式好处是负载均衡会比较好,因为无论容器实例怎么分布在多个节点上,它都会转发过去。当然,由于多了一次转发,性能会损失一丢丢。

2.2 选择(2)Local

这种情况下,只转发给本机的容器,绝不跨节点转发。

Kube-proxy转发时会保留源IP。即:容器收到的报文,看到源IP地址还是用户的。



缺点是负载均衡可能不是很好,因为一旦容器实例分布在多个节点上,它只转发给本机,不跨节点转发流量。当然,少了一次转发,性能会相对好一丢丢。

注:这种模式下的Service类型只能为外部流量,即:LoadBalancer 或者 NodePort 两种,否则会报错。

同时,由于本机不会跨节点转发报文,所以要想所有节点上的容器有负载均衡,就需要上一级的Loadbalancer来做了。



不过流量还是会不太均衡,如上图,Loadbalancer看到的是2个后端(把节点的IP),每个Node上面几个Pod对Loadbalancer来说是不知道的。

想要解决负载不均衡的问题:可以给Pod容器设置反亲和,让这些容器平均的分布在各个节点上(不要聚在一起)。

affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values:
- my-app
topologyKey: kubernetes.io/hostname

像下面这样,负载均衡情况就会好很多~

3 两种模式该怎么选

要想性能(时延)好,当然应该选 Local 模式喽,毕竟流量转发少一次SNAT嘛。

不过注意,选了这个就得考虑好怎么处理好负载均衡问题(ps:通常我们使用Pod间反亲和来达成)。

如果你是从外部LB接收流量的,那么使用:Local模式 + Pod反亲和,一般是足够的

总结

同上上述的理论学习,问题可以明确的得出答案:externaltrafficpolicy的local模式,只转发给本机的容器,绝不跨节点转发,而我司的gitlab是部署在k8s环境的,分散于多节点。

参考文献

深入研究Kubernetes外部流量策略

https://www.asykim.com/blog/deep-dive-into-kubernetes-external-traffic-policies

K8s中的external-traffic-policy是什么?

https://bbs.huaweicloud.com/blogs/158642

externaltrafficpolicy的有关问题说明的更多相关文章

  1. 【转】干货,Kubernetes中的Source Ip机制。

    准备工作 你必须拥有一个正常工作的 Kubernetes 1.5 集群,用来运行本文中的示例.该示例使用一个简单的 nginx webserver 回送它接收到的请求的 HTTP 头中的源 IP 地址 ...

  2. Centos7 使用 kubeadm 安装Kubernetes 1.13.3

    目录 目录 什么是Kubeadm? 什么是容器存储接口(CSI)? 什么是CoreDNS? 1.环境准备 1.1.网络配置 1.2.更改 hostname 1.3.配置 SSH 免密码登录登录 1.4 ...

  3. bluemix创建docker容器

    简介: bluemix是基于kubernetes来服务的免费云空间.绑定信用卡后可以创建一个月的集群,一个月后会被删除. 下面示例介绍如何使用kubernetes dashboard来创建一个容器,并 ...

  4. Kubernetes 服务入口管理与 Nginx Ingress Controller

    Kubernetes 具有强大的副本,动态扩容等特性,每一次 Pod 的变化 IP 地址都会发生变化,所以 Kubernetes 引进了 Service 的概念.Kubernetes 中使用 Serv ...

  5. kubespray -- k8s集群dashboard 访问方式

    1.参考这篇文章: https://github.com/kubernetes/dashboard/wiki/Creating-sample-user 创建用户 2.获取token 3.kubectl ...

  6. Kubernetes 选择 IPVS

    什么是 IPVS ? IPVS (IP Virtual Server)是在 Netfilter 上层构建的,并作为 Linux 内核的一部分,实现传输层负载均衡. IPVS 集成在 LVS(Linux ...

  7. service几种访问类型(集群外负载均衡访问LoadBalancer , 集群内访问ClusterIP,VPC内网负载均衡LoadBalancer ,集群外访问NodePort)

    一.集群外访问(负载均衡) kind: ServiceapiVersion: v1spec: ports: - protocol: TCP port: 4341 targetPort: 8080 no ...

  8. 理解kubernetes环境的iptables

    node节点的iptables是由kube-proxy生成的,具体实现可以参见kube-proxy的代码 kube-proxy只修改了filter和nat表,它对iptables的链进行了扩充,自定义 ...

  9. helm 安装prometheus operator 并监控ingress

    1.helm安装 curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.shchmod 7 ...

随机推荐

  1. Cyber Security - Palo Alto Firewall Interface Types

    Multiple options to integrate the Palo Alto Firewall into your: Network Layer 2 interfaces and VLAN ...

  2. Linux 后台启动 Redis

    1. 修改 redis.conf 首先,这里有一个坑 ! 不同的 redis版本,在安装的时候,redis.conf 的路径稍微有些不同 redis.conf 可能出现的三个位置: /etc/redi ...

  3. 毫无基础的人入门Python,Python入门教程

    随着人工智能的发展,Python近两年也是大火,越来越多的人加入到Python学习大军,对于毫无基础的人该如何入门Python呢?这里整理了一些个人经验和Python入门教程供大家参考. 如果你是零基 ...

  4. Java瞬态变量transient

      我们都知道,阳光是看得见却摸不着的.它真实的存在,但是却无法将其装在罐子里,这是因为光子不具有静止质量.这注定我们只能利用光子而不能将其捕获(或许只是暂时).在Java中,有一种变量就像光子一样, ...

  5. Tomcat Script(python)

    由于刚接触 Python,所以使用Python 书写一些小的脚本,进行备忘同时分享给大家 #!/usr/bin/env python # _*_coding:utf-8_*_ # author: 'l ...

  6. PHP date_timezone_get() 函数

    ------------恢复内容开始------------ 实例 返回给定 DateTime 对象的时区: <?php$date=date_create(null,timezone_open( ...

  7. luogu P4008 [NOI2003]文本编辑器 splay 块状链表

    LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...

  8. 唯一约束 UNIQUE KEY

    目录 什么是唯一约束 与主键的区别 创建唯一约束 唯一性验证 什么是唯一约束 Unique Key:它是 MySQL 中的唯一约束,是指在所有记录中字段的值不能重复出现.例如,为 id 字段加上唯一性 ...

  9. hdu6787(骰子+往回推的传输带问通过方案,dp)

    题:http://acm.hdu.edu.cn/showproblem.php?pid=6787 题意:有1~n标号的格子,上面有m个传输带(传送带传的位置要传到之前去,1位置不能有格子)1~11的骰 ...

  10. OJ评测状态

    Pending/Waiting 排队等待中 Pending Rejudge 答案重判中 Compiling 正在编译 Running/Judging 运行判断中 Accepted(AC) 程序通过 C ...