1、网络的命名空间:Linux 在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命名空间中,彼此间无法通信;Docker 利用这一特性,实现不容器间的网络隔离。
2、Veth 设备对:也叫虚拟网络接口对。Veth设备对的引入是为了实现在不同网络命名空间的通信。
3、Iptables/Netfilter:Netfilter 负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核 模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中 Netfilter 的各种规则表;通过二者的配合来实现整个 Linux 网络协议栈中灵活的数据包处理机制。
4、网桥:网桥是一个二层网络设备,通过网桥可以将 linux 支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。
5、路由:Linux 系统包含一个完整的路由功能,当IP层在处理数据发送或转发的时候,会使用路由表来决定发往哪里。
kubectl get svc --selector app=nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx ClusterIP 172.19.0.166 <none> 80/TCP 1mkubectl describe svc nginxName: nginxNamespace: defaultLabels: app=nginxAnnotations: <none>Selector: app=nginxType: ClusterIPIP: 172.19.0.166Port: <unset> 80/TCPTargetPort: 80/TCPEndpoints: 172.16.2.125:80,172.16.2.229:80Session Affinity: NoneEvents: <none>
上述信息中该 svc 后端代理了2个Pod实例:172.16.2.125:80,172.16.2.229:80
这里未列出 node ip 概念,由于其本身是物理机的网卡IP。因此可理解为nodeip就是物理机IP。
该Port非一般意义上的TCP/IP中的Port概念,它是特指Kubernetes中Service的port,是Service间的访问端口,例如Mysql的Service默认3306端口。它仅对进群内容器提供访问权限,而无法从集群外部通过该端口访问服务。
kind: ServiceapiVersion: v1metadata:name: mallh5-servicenamespace: abcdockerspec:selector:app: mallh5webtype: NodePortports:protocol: TCPport: 3017targetPort: 5003nodePort: 31122
root@node-1:/opt/bin# route -nKernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Iface0.0.0.0 172.23.100.1 0.0.0.0 UG 0 0 0 eth010.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel.1 #flannel 网络内跨节点的通信会交给 flannel.1 处理10.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0 #flannel 网络内节点内的通信会走 docker0
如下图所示:
这种情况下,同一个pod内共享网络命名空间,容器之间通过访问 127.0.0.1:(端口)即可。图中的 veth* 即指veth对的一端(另一端未标注,但实际上是成对出现),该veth对是由 Docker Daemon 挂载在 docker0 网桥上,另一端添加到容器所属的网络命名空间,图上显示是容器中的eth0。
图中演示了 bridge 模式下的容器间通信。docker1 向 docker2 发送请求,docker1,docker2 均与 docker0 建立了 veth 对进行通讯。
当请求经过 docker0 时,由于容器和 docker0 同属于一个子网,因此请求经过 docker2与docker0的veth*对,转发到docker2,该过程并未跨节点,因此不经过eth0。
同节点 pod 间通信
由于 Pod 内共享网络命名空间(由 pause 容器创建),所以本质上也是同节点容器间的通信。同时,同一 Node 中 Pod 的默认路由都是 docker0 的地址,由于它们关联在同一个 docker0 网桥上,地址网段相同,所有它们之间应当是能直接通信的。来看看实际上这一过程如何实现。如上图,Pod1 中容器 1和容器 2 共享网络命名空间,因此对pod 外的请求通过 pod1 和 Docker0 网桥的 veth对(图中挂在eth0和ethx上)实现。
跨节点通信
CNI:容器网络接口
通信方式
通过将 Service 的类型设置为 NodePort,就可以在 Cluster 中的主机上通过一个指定端口暴露服务。注意通过 Cluster 中每台主机上的该指定端口都可以访问到该服务,发送到该主机端口的请求会被 Kubernetes 路由到提供服务的 Pod 上。采用这种服务类型,可以在 Kubernetes cluster 网络外通过主机 IP:端口的方式访问到服务。
kind: ServiceapiVersion: v1metadata:name: influxdbspec:type: NodePortports:- port: 8086nodePort: 31112selector:name: influxdb
apiVersion: extensions/v1beta1kind: Ingressmetadata:name: testannotations:: /spec:rules:host: test.name.comhttp:paths:path: /testbackend:serviceName: service-1servicePort: 8118path: /namebackend:serviceName: service-2servicePort: 8228
apiVersion: extensions/v1beta1kind: Ingressmetadata:name: testannotations:: /spec:rules:host: foo.bar.comhttp:paths:path: /foobackend:serviceName: s1servicePort: 80path: /barbackend:serviceName: s2servicePort: 80
- END -
推荐阅读
图解 | Kubernetes 中应用平滑升级4种方式 6 张图带你搞懂 DevOps CI/CD 流水线 常用开源监控系统分析推荐(必备知识) Kubermetrics — 使集群可视化变的很简单! Zabbix 通过 API 监控 Kubernetes Kubernetes 平台中的日志如何收集? Kubernetes 生产环境最佳实践 容器技术学习的实践结论分享 一篇文章讲清楚云原生图景及发展路线 Kubernetes 实现灰度和蓝绿发布 K8s中大量Pod是Evicted状态,这是咋回事?
Prometheus + Grafana 实现服务器的可视化
K8s运维锦囊,19个常见故障解决方法
线上 K8s Ingress 访问故障排查思路
Kubernetes 生态架构图
Kubernetes 在企业中的应用场景
订阅,一起成长
K8s生态圈
点在看,K8s一年不出问题👇