kubernetes 网络解析

开头语

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

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

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

基础

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

网络架构

kubernetes 网络解析_第2张图片

kubernetes 网络解析_第3张图片 

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            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           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



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

ipvs中的显示

[root@master k8s]# kubectl describe svc -n study
Name:              pc-deployment
Namespace:         study
Labels:            
Annotations:       
Selector:          app=nginx-pod
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.69.90
IPs:               10.105.69.90
Port:                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:            
[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 创建过程kubernetes 网络解析_第4张图片

 flannel

使用vxlan技术
kubernetes 网络解析_第5张图片

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

kubernetes 网络解析_第6张图片
 

[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 隧道网卡

kubernetes 网络解析_第7张图片
 
iptable

kubernetes 网络解析_第8张图片
 
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

kubernetes 网络解析_第9张图片

当node过多后,bgp路由设置一个主bgp,这样就不需要实现全路由,不会导致大量的损耗
kubernetes 网络解析_第10张图片 

cni 配置文件

kubernetes 网络解析_第11张图片

多网络(pod 两张网卡)kubernetes 网络解析_第12张图片


multuskubernetes 网络解析_第13张图片

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

服务发现和DNS

kubernetes 网络解析_第14张图片
 
通过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              53/UDP,53/TCP,9153/TCP   320d   k8s-app=kube-dns
metrics-server   ClusterIP   10.98.165.172           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网段,网络插件的网段,以及真实服务器的网段,都不能相同,如果相同就会出各种各样奇怪的问题,而且这些问题在集群做好之后是不方便改的,改会导致更多的问题,所以,就在搭建前将其规划好

你可能感兴趣的:(kubernetes,kubernetes,网络,容器,云原生,运维)