开头语
写在前面:如有问题,以你为准,
目前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 18sNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/pc-deployment 3/3 3 3 7m14sNAME 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: # 选择器,通过它指定该控制器可以管理哪些PodmatchLabels: # Labels匹配规则app: nginx-podtemplate: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本metadata:labels:app: nginx-podspec: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网段,网络插件的网段,以及真实服务器的网段,都不能相同,如果相同就会出各种各样奇怪的问题,而且这些问题在集群做好之后是不方便改的,改会导致更多的问题,所以,就在搭建前将其规划好