锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

K8S中的网络

时间:2022-08-08 17:30:01 53s光纤传感器

文章目录

  • 一、K8S集群通信的网络模型和网络模型
    • 1 K8S网络模型和实现方案
    • 2 pod 内容器通信
    • 3 pod与pod通信
      • 3.1 pod在同一主机
      • 3.2 pod 在不同的主机下
    • 4 pod 与service通信
    • 5 service 如何找到服务?
    • 6 外网与service通信
  • 二、k8s与网络插件集成(flannel calico canal kube-router romana cni-genie)
    • 1 flannel
    • 2 calico
  • 本实验的使用及k8s一个etcd集群
  • 建议使用一个单独的集群
    • 3 canal
    • 4 kube-router
    • 5 romana
    • 6 CNI-Genie
    • 7 组件小结
        • 总结:

引言: 再来一点知识

一、K8S集群通信的网络模型和网络模型

1 K8S网络模型和实现方案

k8s集群中的每一个Pod(最小调度单位)都有自己的IP地址,即ip-per-pod模型。
在ip-per-pod每个模型pod为了保持集群中的独特性,我们不需要在每个集群中都显式 Pod 之间创建链接, 从容器端口到主机端口的映射不需要处理。从端口分配、命名、服务发现、 从负载平衡、应用配置和迁移的角度来看,Pod 可视为独立虚拟机或物理主机。
如下图所示,两个容器从表面上看docker网络与k8s网络中与client通信形式。

在这里插入图片描述
k8s为了保持核心功能的简化(模块化)和适应不同业务用户的网络环境,是一个庞大的分布式系统,k8s通过CNI(Container Network Interface)即集成各种网络方案的容器网络接口。这些网络方案必须符合要求k8s网络模型要求:

节点上的 Pod 可以不通过 NAT 和其他任何节点上的 Pod 通信
节点代理(如系统保护过程)kubelet)节点上的一切都可以和Pod通信

注:只针对那些支持: Pods 运行在主机网络中的平台(如:Linux):

在节点主机网络中运行的主机 Pod可以不通过 NAT 在所有节点上 Pod 通信

这有点像美团吗?外包配送业务(CNI)对于三方公司(实现计划),我不在乎骑手通过哪种飞机炮(网络)送餐,只要符合及时、不泄漏(模型要求)等相关规则,这是一个合格的分销。

CNI 做两件事,容器创建时的网络分配,和当容器被删除时释放网络资源。 常用的 CNI 实现方案有 Flannel、Calico、Weave各种云制造商根据自己的网络推出CNI华为的插件 CNI-Genie、阿里云Terway。

2 pod 内容器通信

Pod内容器很简单,在同一个 Pod 内部,所有容器共享存储,网络使用相同 IP 地址和端口空间可以通过localhost发现对方。Pod 使用中间容器 Infra,Infra 在 Pod 首先创建,其他容器通过 Join Network Namespace 的方式与 Infra 容器相连。

我们有一个pod包含busybox、nginx这两个容器

kubectl get pod -n training NAME                                  READY    STATUS     RESTARTS    AGE pod-localhost-765b965cfc-8sh76   2/2       Running    0             2m56s 

在busybox中使用telnet连接nginx容器的 80端口看看。

kubectl exec -it  pod-localhost-765b965cfc-8sh76 -c container-si1nrb -n training -- /bin/sh  # telnet localhost 80 Connected to localhost 

一个pod有多个容器可以通过-c指定进入的容器名(通过describe通过容器名称),显然是通过localhost可以轻松访问同一个pod中的nginx容器80端口。这通常部署在许多密切相关的应用程序中pod中。

3 pod与pod通信

3.1 pod在同一主机

我们通过node两个选择器pod调度到同一个node中

 ...  nodeSelector:         kubernetes.io/hostname: node2  ... 

两个容器分别获得一个IP地址,也通过IP双方网络地址正常交换。

# kubectl get pod -o wide -n training  NAME                                  READY   STATUS    RESTARTS   AGE     IP              NODE                    NOMINATED NODE   READINESS GATES  pod-to-pod-64444686ff-w7c4g           1/1     Running   0          6m53s   100.82.98.206   node2                    pod-to-pod-busybox-7b9db67bc6-tl27c   1/1     Running   0          5m3s    100.82.98.250   node2                    # kubectl exec -it  pod-to-pod-busybox-7b9db67bc6-tl27c  -n training -- /bin/sh /# telnet 100.82.98.206 80 Connected to 100.82.98.206 

同一主机网络的pod以及我们以前学到的东西docker bridge相似,通过linux在网桥上添加虚拟设备 veth pair 连接容器和主机命名空间。
在k8s只是用灰色部分代替CNI方案实现。

3.2 pod 在不同的主机下

此时pod分布如下

kubectl get pod -o wide -n training  NAME                                               ` READY     STATUS     RESTARTS   AGE    IP                 NODE                    NOMINATED NODE   READINESS GATES  pod-to-pod-64444686ff-w7c4g                     1/1        Running    0            104m   100.82.98.206    node2                        pod-to-pod-busybox-node2-6476f7b7f9-mqcw9    1/1        Running     0            42s    100.91.48.208    node3                 # kubectl exec -it  pod-to-pod-busybox-node2-6476f7b7f9-mqcw9  -n training -- /bin/sh / # telnet 100.82.98.206 80 Connected to 100.82.98.206 

pod不同主机的通信依赖于不同主机的通信CNI插件,这里我们以Calico为例的做简单了解,从Calico架构图中可以看到每个node节点的自身依然采用容器网络模式,Calico在每个节点都利用Linux 内核实现了一个高效的虚拟路由器vRouter来负责数据转发。每个虚拟路由器将路由信息广播到网络中,并添加路由转发规则。同时基于iptables还提供了丰富的网络策略,实现k8s的Network Policy策略,提供容器间网络可达性限制的功能。

简单理解就是通过在主机上启动虚拟路由器(calico node),将每个主机作为路由器使用实现互联互通的网络拓扑。

Calico节点组网时可以直接利用数据中心的网络结构(L2或者L3),不需要额外的NAT、隧道或者Overlay Network,没有额外的封包解包,能够节约CPU运算,提高网络效率。

4 pod 与service通信

我们知道在k8s中容器随时可能被摧毁,pod的IP显然不是持久的,会随着扩展或缩小应用规模、或者应用程序崩溃以及节点重启等而消失和出现。service 设计就是来处理这个问题。service可以管理一组 Pod 的状态,允许我们跟踪一组随时间动态变化的 Pod IP 地址。而客户端只需要知道service这个不变的虚拟IP就可以了。

我们先来看看典型的service与pod使用,我们创建了一个service,标签选择器为app:nginx,将会路由到app=nginx标签的Pod上。

# kubectl get service -n training
NAME               		TYPE        	CLUSTER-IP      EXTERNAL-IP   	PORT(S)    	AGE
training-service   		ClusterIP   	10.96.229.238   	        		8881/TCP   10m

Service对外暴露的端口8881,这样在集群的中的pod即可通过8881访问到与service 绑定的label为app=nginx的pod

kubectl run -it --image nginx:alpine curl --rm /bin/sh
/ # curl 10.96.229.238:8881



Welcome to nginx!