容器网络硬核技术内幕 (18) 他山之石可以攻玉

2022-07-28 08:57:43 浏览数 (1)

在上一期《生命的火花》中,我们提到,一组pod可以通过service机制,对外提供一个名称。Kubernetes会将这个名称映射到带有同一个标签的Pod,将指向service的访问分发到各个pod上。

让我们看一个例子。

如图所示,我们创建了3个运行着elasticsearch的pod,对外的service名称为es1。

这3个pod的IP地址分别为:

172.17.50.101/24

172.17.50.104/24

172.17.50.113/24

它们对外提供服务的IP为 172.17.30.254/24。

在kubernetes中,我们可以通过yaml来配置它们:

代码语言:javascript复制
apiVersion: v1  #对象描述规范版本
kind: Service   #对象类型为service
metadata:
  name: es1     #service对象名称:es1
  labels:
    name: es    #该service对象对外的标签:es。有可能有其他service也使用这个标签。
spec:
  type: ClusterIP     #这里代表是ClusterIP类型的负载均衡方式
  clusterIP: 172.17.30.254 #对外提供服务的IP
  ports:
  - port: 80          #这里的端口是pod服务的监听端口。
    targetPort: 80  #这个端口是pod对外暴露服务的端口
    protocol: TCP
  selector:
    app: elasticsearch  #这个标签是后端pod组的标签

这样,就可以将一组具有elasticsearch的标签的Pod,以es1的名称对外发布为一个service,这个service名称将解析为IP地址 172.17.30.254,端口80。

我们注意到,service的type字段为ClusterIP。实际上,kubernetes可以支持三种service模式:

第一种为NodePort,是一种简单粗暴地将Node上的端口,一对一映射到Node内部的Pod上的方式。这种方式的问题在于,如果一个node上有两个pod,监听同样的端口,会造成冲突。

第二种是ClusterIP。这种方式实际上类似负载均衡的VIP。

实际上,ClusterIP方式下,对指向clusterip这个地址的请求,分发到各个pod的实现,是由kube-proxy实现的。

我们翻开厚厚的kubernetes文档,会发现,kube-proxy本质上是一个监视器,它监视pod的创建和销毁,并调用iptables或ipvs进行转发。

如下图:

如果我们有一组容器pod,具有标签MyApp,监听9376端口,kube-proxy只负责控制iptables或ipvs对请求进行转发。

当然,ipvs比iptables有更高的转发效率,LB算法也更丰富,只是要付出部署的代价。

但,clusterip仅限于在容器环境内部使用。如果我们需要将容器服务对容器环境外部,如互联网或公司企业内网开放,我们还需要第三种模式——

第三种是LoadBalancer。这种方式可以对接第三方的负载均衡。我们知道,无论是ipvs还是iptables,它的转发都需要消耗node上宿主机的CPU资源。而第三方专用负载均衡硬件,也恰好能够用专业的硬件实现专业的功能。正可谓:他山之石可以攻玉。

敬请期待下期详解。

0 人点赞