kubernetes 网络解析

开头语

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

目前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网段,网络插件的网段,以及真实服务器的网段,都不能相同,如果相同就会出各种各样奇怪的问题,而且这些问题在集群做好之后是不方便改的,改会导致更多的问题,所以,就在搭建前将其规划好

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值