关于Kubernetes的一些困惑


最近在学习magnum和kubernetes。有一些疑问,发在这里,请大家帮忙来解答,一起讨论。
  1. 比如minionA/B上分别有serviceA的podA/B。那么访问minionA的kube-proxy是不是也会被导流到minionB上的podB上?
  2. service的重要部件proxy就是起到了个负载均衡和反向代理的作用。这个角色是不是直接可以用haproxy/nginx这样的软件代替呢?
已邀请:

杨章显 - 思科系统运维工程师

赞同来自: 徐新坤 wangzi19870227 FanLin MapleWang aidenzhang styshoo shenlanse jacksunsong更多 »


hi ,
<ol><li>比如minionA/B上分别有serviceA的podA/B。那么访问minionA的kube-proxy是不是也会被导流到minionB上的podB上?</li></ol><strong>由于通过Service IP + Service Port访问Service,Service不关心Pod运行在哪个节点上,所以Proxy可能分发到minionB。</strong>
<ol><li>service的重要部件proxy就是起到了个负载均衡和反向代理的作用。这个角色是不是直接可以用haproxy/nginx这样的软件代替呢?</li></ol> <strong>直接替代应该不行,proxy除了代理,还做了一些其他工作,如初始化iptables,service注册到proxy,更新service的podlist更新等,所以如果要替换,这部分工作得自己实现。</strong>

hjianhao

赞同来自: 徐新坤 FanLin styshoo


可以参考一下我翻译的这篇文章,里面有比较清楚的介绍:http://dockone.io/article/520

另外haproxy/nginx代替是比较麻烦的,这个涉及到整个Kubernetes的架构。需要做修改。我们自己的实现中是通过nginx来做的。

在微服务架构中,后台服务的交互可以使用Kubernetes这套机制来完成,比通过nginx来说避免了集中转发。

jolestar

赞同来自: 徐新坤 YoungLiu


我补充下

第一. 会
直接访问service的clusterIP, 由于clusterIP是虚IP,会被iptables 的nat策略转发到当前minion的kube-proxy监听的端口上
比如这条kube-proxy的iptables

<pre>
Chain KUBE-PORTALS-HOST (1 references)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- <span> <span> 0.0.0.0/0 10.254.0.10 /<span> kube-system/kube-dns:dns-tcp <span>/ tcp dpt:53 to:10.0.3.11:40995
</pre>

<pre>
netstat -ntpl|grep 40995
tcp6 0 0 :::40995 :::* LISTEN 904/kube-proxy
</pre>
kube-proxy监听的端口是40995, 对service 10.254.0.10:50 的请求 被转发到 10.0.3.11:40995。 然后kube-proxy会通过内置的loadbalancer转发请求给后面的endpoint,默认策略是round-robin。

第二. kube-proxy 是内置LB的,不过kube-proxy提供的功能要超越单纯的LB,同意 @FanLin 的说法。但这个LB和k8s的 external LB 需要解决的问题不一样,并且这种tcp代理模式对性能影响是比较大的。 最新的k8s中正在将tcp代理完全用 iptables 实现:https://github.com/kubernetes/ ... /3760

MapleWang

赞同来自: 徐新坤 lyn


关于kube-proxy或者service的load balance功能,我有一点想说一下。我觉得kube-proxy应该是自己没有LB的,请看下面一段官方对于service的描述:

> On cloud providers which support external load balancers, this should
> be as simple as setting thecreateExternalLoadBalancer flag of the
> Service to true. This sets up a cloud-specific load balancer and
> populates thepublicIPs field (see below). Traffic from the external
> load balancer will be directed at the backend Pods, though exactly how
> that works depends on the cloud provider. For cloud providers which do
> not support external load balancers, there is another approach that is
> a bit more "do-it-yourself" - the publicIPs field. Any address you put
> into the publicIPs array will be handled the same as the portal IP -
> the kube-proxy will install iptables rules which proxy traffic through
> to the backends. You are then responsible for ensuring that traffic to
> those IPs gets sent to one or more Kubernetes Nodes. As long as the
> traffic arrives at a Node, it will be be subject to the iptables
> rules.

对于支持kubenetes并且有自己load balancer的云平台比如GCE或者AWS,那么不用你费心,只要稍作配置就可以了。
但是如果没有这样的平台,那么对不起,你需要自己设置一个external LB了,上文中提到的的在service中设置public IP,kube-proxy只是在iptable里面做了一点手脚,确保每一个minion上的pod都可以被某一个public IP所访问到,但是如何把traffic均匀分布到这些pod上,kube-proxy是不管的,你需要额外的部件去实现它。

当然上面的描述不是最新的,你可以参考最新的文档,查看“external service”这一节:
https://github.com/GoogleCloud ... es.md

就我看来本质上这个情况仍然没有改变,还是需要自己设置LB。

所以对于你的两个问题:

1 traffic一旦到达minion A,它是不会被forward到其他minion B上去的,因为kube-proxy没有这样的功能,traffic被forward到哪一个node上是你设置的外部load balancer要做的事情

2 这里已经不是一个替代的问题,而是你必须要有一个像haproxy这样的东西来帮你做load balance,这里有篇实践的文章供你参考,用的是haproxy来为kubenetes的replicationcontroller中 replca pod做LB:

http://www.dasblinkenlichten.c ... 93353

FanLin - Docker&CoreOS爱好者

赞同来自: 徐新坤


其实说来,Proxy的主要功能并不是负载均衡,而是为Service找到真正的后端服务容器提供一个渠道,只不过因为同时存在多个容器支持一个Service的情况,因此从外部看起来就相当于实现负载均衡的效果。

杨章显老师在(http://www.infoq.com/cn/articl ... uction)对Proxy的介绍也写得很好:

> Proxy提供TCP/UDP sockets的proxy,每创建一种Service,Proxy主要从etcd获取Services和Endpoints的配置信息,然后根据配置信息在Minion上启动一个Proxy的进程并监听相应的服务端口,当外部请求发生时,Proxy会根据Load Balancer将请求分发到后端正确的容器处理。

Proxy不但解决了同一主宿机相同服务端口冲突的问题,还提供了Service转发服务端口对外提供服务的能力。

_Tube_

赞同来自:


欢迎加入kubernets技术讨论qq群:Google/Kubernetes技术 319807078

要回复问题请先登录注册