Skip to content

Latest commit

 

History

History
57 lines (38 loc) · 4.95 KB

inter-pod-networking.md

File metadata and controls

57 lines (38 loc) · 4.95 KB

7.4 Pod间网络

  在Kubernetes中,每个pod具有可路由的IP,允许pod跨集群节点进行通信而无需NAT,也无需管理端口分配。由于每个pod都获得真实的IP地址,因此pod间可以在不使用代理或转换(例如NAT)的情况下进行通信。pod可以使用端口通信,也可以不使用更高级的服务发现机制进行通信。

  我们将pod间(也称为东西向流量)的通信分为两类:

  • pod可以直接与其他pod进行通信; 在这种情况下,请求通信的pod需要知道被请求pod的IP地址,并且有可能会重复此操作,因为”牲畜模式“。

  • 普遍地,pod通过service与其他pod进行通信。在这种情况下,该service提供了一个可以通过DNS发现的稳定的,虚拟IP地址。

  当一个容器试图获取网络接口的地址时,它看到的IP是与pod中任何其他容器看到的是同一个IP; 每个pod都有一个其他pod可以找到和使用的IP地址。通过使IP地址和端口在Pod内外相同,Kubernetes在整个集群中创建了一个编排的地址空间。有关此主题的更多详细信息,另请参阅Mark Betz撰写的文章“Understanding Kubernetes Networking: Pods”。

  现在我们来看看service,如图7-3所示。

图7-3 �Kubernetes中的service

  service为一组pod提供稳定的虚拟IP(VIP)地址。虽然Pod是经常变化的(扩容,缩容等),但service允许客户端通过使用VIP可靠地发现并连接到在Pod中正在运行的容器。VIP中的“虚拟”意味着它不是连接到网络接口的实际IP地址; 它的目的纯粹是充当稳定的”前端“,将流量转发到一个或多个Pod,因为service后端的pod的IP地址可能会不断变化。

  必须认识到VIP在网络堆栈中不存在的。例如,你不能ping它们。他们只是Kubernetes内部管理的实体。还要注意它的格式是IP:PORT,所以IP地址和端口一起构成了VIP。可以把VIP视为一种映射到实际IP地址的数据结构的索引。

  如图7-3所示,使用VIP 10.104.58.143的服务将流量路由到其中一个容器172.17.0.3或172.17.0.4。这里需要注意的是service和pod的属于不同的子网,现在,你可能想知道这实际上是如何工作的?

  您可以通过标签选择器指定service后端的一组pod,例如,spec.selector.app = someapp Kubernetes将创建一个service,该service的目标是带有标签app = someapp的所有pod。请注意,如果存在这样的选择器,那么对于每个目标Pod将创建一个Endpoint类型的子资源,并且如果不存在标签选择器,则不会创建Endpoint。例如,请参阅以下代码示例kubectl describe命令的输出。这种Endpoint也不是在所谓的Headless的service的情况下创建的,它允许您对IP管理和服务发现的发生进行很好的控制。

  保持最新的VIP和pod之间的映射是kube-proxy的工作(另请参阅kube-proxy文档),这是一个在kubernetes集群中的每个node节点上运行的进程。

  kube-proxy进程查询apiserver以了解群集中新的service,并相应地更新节点的iptables规则,以提供必要的路由信息。要了解更多service如何工作,请查看Kubernetes Services By Example

  让我们动手看看service是如何工作的:假设有一个名为webserver的deployment(例如,执行kubectl run webserver --image nginx),您可以自动创建一个服务,如下所示:

$ kubectl expose deployment/webserver --port 80
service "webserver" exposed
$ kubectl describe service/webserver
Name:               webserver
Namespace:          default
Labels:             run=webserver
Annotations:        <none>
Selector:           run=webserver
Type:               ClusterIP
IP:                 10.104.58.143
Port:               <unset>  80/TCP
TargetPort:         80/TCP
Endpoints:          172.17.0.3:8080,172.17.0.4:8080
Session Affinity:   None
Events:             <none>

$ kubectl get service -l run=webserver
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
webserver   ClusterIP   10.104.58.143   <none>        80/TCP    1m

  我们可以看到service已经拥有了一个集群内部的IP(10.104.58.143),EXTERNAL-IP列告诉你这个服务只能在集群内部使用,也就是说,没有来自群集外部的流量可以访问此service。

  在图7-4中,您可以在Kubernetes仪表板中看到该service。

图7-4 �Dashbord中的service