kubernetes 网络解析

发布时间:2024年01月09日

开头语

写在前面:如有问题,以你为准,

目前24年应届生,各位大佬轻喷,部分资料与图片来自网络

内容较长,页面右上角目录方便跳转

基础

Kubernetes 使用扁平网络模型,所有 Pod 都可以直接相互通信,无论它们运行在哪个节点上。
为了实现这一点,Kubernetes 设置了一个跨越集群中所有节点的虚拟网络,并为每个 Pod 分配了该网络中唯一的 IP 地址
① 一个 Pod 中容器之间通过
本地回路(loopback)通信。
② 集群网络在不同 Pod 之间提供通信;换言之,Pod 和 Pod 之间能互相通信(通过 calico 网络插件实现 Pod 之间网络的扁平化;当然,Node 节点之间的通信也是通过 calico 网络插件)。
③ Service 资源允许我们对外暴露 Pod 中运行的应用程序,以支持来自集群之外的访问;换言之,Service 和 Pod 之间能互相通信。
④ 可以使用 Service 来发布仅供集群内部使用的服务

网络架构

?

svc pod 之间的流量解析

service是如何把流量导入到pod
在目前1.28版本的k8s中使用的ipvsadm工具来实现集群流量转发

[root@master k8s]# kubectl get svc
NAME? ? ? ? ?TYPE? ? ? ? CLUSTER-IP? ?EXTERNAL-IP? ?PORT(S)? ?AGE
kubernetes? ?ClusterIP? ?10.96.0.1? ? <none>? ? ? ? 443/TCP? ?314d
[root@master k8s]# kubectl get svc,deploy,pod -n study
NAME? ? ? ? ? ? ? ? ? ? TYPE? ? ? ? CLUSTER-IP? ? ?EXTERNAL-IP? ?PORT(S)? ?AGE
service/pc-deployment? ?ClusterIP? ?10.105.69.90? ?<none>? ? ? ? 80/TCP? ? 18s

NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? READY? ?UP-TO-DATE? ?AVAILABLE? ?AGE
deployment.apps/pc-deployment? ?3/3? ? ?3? ? ? ? ? ? 3? ? ? ? ? ?7m14s

NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY? ?STATUS? ? RESTARTS? ?AGE
pod/pc-deployment-5cb65f68db-6p2jj? ?1/1? ? ?Running? ?0? ? ? ? ? 7m14s
pod/pc-deployment-5cb65f68db-khmnj? ?1/1? ? ?Running? ?0? ? ? ? ? 7m14s
pod/pc-deployment-5cb65f68db-xdtsz? ?1/1? ? ?Running? ?0? ? ? ? ? 7m14s
[root@master k8s]# curl 10.105.69.90
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
? ? body {
? ? ? ? width: 35em;
? ? ? ? margin: 0 auto;
? ? ? ? font-family: Tahoma, Verdana, Arial, sans-serif;
? ? }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

ipvs中的显示

[root@master k8s]# kubectl describe svc -n study
Name:? ? ? ? ? ? ? pc-deployment
Namespace:? ? ? ? ?study
Labels:? ? ? ? ? ? <none>
Annotations:? ? ? ?<none>
Selector:? ? ? ? ? app=nginx-pod
Type:? ? ? ? ? ? ? ClusterIP
IP Family Policy:? SingleStack
IP Families:? ? ? ?IPv4
IP:? ? ? ? ? ? ? ? 10.105.69.90
IPs:? ? ? ? ? ? ? ?10.105.69.90
Port:? ? ? ? ? ? ? <unset>? 80/TCP
TargetPort:? ? ? ? 80/TCP
Endpoints:? ? ? ? ?10.244.1.6:80,10.244.2.10:80,10.244.2.11:80
Session Affinity:? None
Events:? ? ? ? ? ? <none>
[root@master k8s]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
? -> RemoteAddress:Port? ? ? ? ? ?Forward Weight ActiveConn InActConn

...
TCP? master:http rr
? -> 10.244.1.6:http? ? ? ? ? ? ? Masq? ? 1? ? ? 0? ? ? ? ? 0
? -> 10.244.2.10:http? ? ? ? ? ? ?Masq? ? 1? ? ? 0? ? ? ? ? 0
? -> 10.244.2.11:http? ? ? ? ? ? ?Masq? ? 1? ? ? 0? ? ? ? ? 1
...
# InActConn 是刚刚访问的一次链接,从中可以看到刚刚访问的流量到达了 11 pod


pod 创建过程

?flannel

使用vxlan技术

跨节点通信,会创建一个udp隧道,但是实际还是走节点到节点(外层封装),内层封装vxlan header
yaml配置文件内


?

[root@master net.d]# ls /opt/cni/bin/

bandwidth? ? calico-ipam? firewall? ? ?host-local? ?loopback? ? ?ptp? ? ? ? ? tuning
bridge? ? ? ?dhcp? ? ? ? ?flannel? ? ? install? ? ? macvlan? ? ? sbr? ? ? ? ? vlan
calico? ? ? ?dummy? ? ? ? host-device? ipvlan? ? ? ?portmap? ? ? static? ? ? ?vrf


下图中 flannel.1 就是 udp 隧道网卡


?
iptable


?
cni 配置文件

{
? "name": "cbr0",
? "cniVersion": "0.3.1",
? "plugins": [
? ? {
? ? ? "type": "flannel",
? ? ? "delegate": {
? ? ? ? "hairpinMode": true,
? ? ? ? "isDefaultGateway": true
? ? ? }
? ? },
? ? {
? ? ? "type": "portmap",
? ? ? "capabilities": {
? ? ? ? "portMappings": true
? ? ? }
? ? }
? ]
}

run 环境

[root@node2 net.d]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.2.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true


calico

当node过多后,bgp路由设置一个主bgp,这样就不需要实现全路由,不会导致大量的损耗
?

cni 配置文件

多网络(pod 两张网卡)


multus

https://blog.csdn.net/qq_35487883/article/details/120864982
两张网卡,可以一张网络属于 calico ,一张属于flannel

服务发现和DNS


?
通过coredns 来实现集群内部的dns解析

[root@master k8s]# kubectl -n kube-system get svc -owide
NAME? ? ? ? ? ? ?TYPE? ? ? ? CLUSTER-IP? ? ? EXTERNAL-IP? ?PORT(S)? ? ? ? ? ? ? ? ? AGE? ? SELECTOR
kube-dns? ? ? ? ?ClusterIP? ?10.96.0.10? ? ? <none>? ? ? ? 53/UDP,53/TCP,9153/TCP? ?320d? ?k8s-app=kube-dns
metrics-server? ?ClusterIP? ?10.98.165.172? ?<none>? ? ? ? 443/TCP? ? ? ? ? ? ? ? ? 311d? ?k8s-app=metrics-server


# kube-dns? 即为集群得dns

通过查看nginx 内的 dns 地址可以看到其指向得是kube-dns
[root@master k8s]# kubectl get pod -n study
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY? ?STATUS? ? RESTARTS? ?AGE
pc-deployment-5cb65f68db-6p2jj? ?1/1? ? ?Running? ?0? ? ? ? ? 5d23h
pc-deployment-5cb65f68db-khmnj? ?1/1? ? ?Running? ?0? ? ? ? ? 5d23h
pc-deployment-5cb65f68db-xdtsz? ?1/1? ? ?Running? ?0? ? ? ? ? 5d23h

[root@master k8s]# kubectl exec -it -n study pc-deployment-5cb65f68db-xdtsz -c nginx -- cat /etc/resolv.conf
nameserver 10.96.0.10
search study.svc.cluster.local svc.cluster.local cluster.local
options ndots:5


查看其域名

[root@master k8s]# nslookup 10.96.0.10 10.96.0.10
10.0.96.10.in-addr.arpa name = kube-dns.kube-system.svc.cluster.local.

?自定义 pod 中 dns

---
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
??name: pc-deployment # deployment的名称
??namespace: study # 命名类型
spec: # 详细描述
??replicas: 3 # 副本数量
??selector: # 选择器,通过它指定该控制器可以管理哪些Pod
????matchLabels: # Labels匹配规则
??????app: nginx-pod
??template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
????metadata:
??????labels:
????????app: nginx-pod
????spec:
??????containers:
????????- name: nginx # 容器名称
??????????image: nginx:1.17.1 # 容器需要的镜像地址
??????????ports:
????????????- containerPort: 80 # 容器所监听的端口
??????dnsPolicy: "None"
??????dnsConfig:
????????nameservers:
????????- 1.2.3.4
[root@master k8s]# kubectl get pod -n study
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY? ?STATUS? ? ? ? ? ? ? RESTARTS? ?AGE
pc-deployment-5cb65f68db-6p2jj? ?1/1? ? ?Running? ? ? ? ? ? ?0? ? ? ? ? 5d23h
pc-deployment-5cb65f68db-xdtsz? ?1/1? ? ?Running? ? ? ? ? ? ?0? ? ? ? ? 5d23h
pc-deployment-7bb545f6b7-bdlg5? ?0/1? ? ?ContainerCreating? ?0? ? ? ? ? 3s
pc-deployment-7bb545f6b7-vbb9l? ?1/1? ? ?Running? ? ? ? ? ? ?0? ? ? ? ? 12s
[root@master k8s]# kubectl exec -it -n study pc-deployment-7bb545f6b7-bdlg5 -c nginx -- cat /etc/resolv.conf
nameserver 1.2.3.4


网络插件 calico flannel 对比


Flannel


(1)引入了多个网络组件,在网络通信时需要转到flannel0网络接口,再转到用户态的flanneld程序,到对端后还需要走这个过程的反过程,所以也会引入一些网络的时延损耗。
(2)Flannel模型默认采用了UDP作为底层传输协议,UDP本身是非可靠协议,虽然两端的TCP实现了可靠传输,但在大流量、高并发的应用场景下还建议多次测试

Calico

(1)节点组网时可以直接利用数据中心的网络结构(L2或者L3),不需要额外的NAT、隧道或者Overlay Network,没有额外的封包解包,能够节约CPU运算,提高网络效率
(2) 在小规模集群中可以直接互联,在大规模集群中可以通过额外的BGP route reflector来完成
(3) 基于iptables或ipvs还提供了丰富的网络策略,实现了Kubernetes的Network Policy策略,提供容器间网络可达性限制的功能

总结

目前比较常用的时flannel和calico,flannel的功能比较简单,不具备复杂网络的配置能力,calico是比较出色的网络管理插件,单具备复杂网络配置能力的同时,往往意味着本身的配置比较复杂,所以相对而言,比较小而简单的集群使用flannel,考虑到日后扩容,未来网络可能需要加入更多设备,配置更多策略,则使用calico更好

原理解析

https://www.cnblogs.com/xiaohaoge/p/16556301.html


Kubernetes通信问题

1.容器间通信:即同一个Pod内多个容器间通信,通常使用loopback来实现。
2.Pod间通信:K8s要求,Pod和Pod之间通信必须使用Pod-IP 直接访问另一个Pod-IP
3.Pod与Service通信:即PodIP去访问ClusterIP,当然,clusterIP实际上是IPVS或iptables规则的虚拟IP,是没有TCP/IP协议栈支持的。但不影响Pod访问它.
4.Service与集群外部Client的通信,即K8s中Pod提供的服务必须能被互联网上的用户所访问到。
需要注意的是,k8s集群初始化时的service网段,pod网段,网络插件的网段,以及真实服务器的网段,都不能相同,如果相同就会出各种各样奇怪的问题,而且这些问题在集群做好之后是不方便改的,改会导致更多的问题,所以,就在搭建前将其规划好

文章来源:https://blog.csdn.net/weixin_48297181/article/details/135483227
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。