flannel,canal,网络控制

docker网络:

  bridge 自连网络名称空间

  joined 与另外容器共享使用网络名称空间

  open 容器直接共享宿主机的网络名称空间

  none 不使用任何网络名称空间

 

k8s网络通信模型

  1. 容器间网络通信:同一个pod内的多个容器间的通信,lo
  2. pod间通信: pod ip <--> pod ip 直连
  3. podservice通信 pod ip <--> clusterip   iptables实现
  4. service与集群外部客户端的通信 nodeport ingress loadblance实现

 

CNI 容器网络接口

  1. flannel 仅支持地址分配
  2. calico 支持地址分配 也支持网络策略
  3. canal  flannel+calico
  4. kube-router

 

解决方案:

虚拟网桥

多路复用:MacVLAN

硬件交换:SR-IOR 虚拟出多个硬件网卡

 

名称空间隔离的是权限,不会隔离网络,podpod之间网络的隔离要用网络策略实现

 

flannel不支持网络策略

网络插件使用: kubelet /etc/cni/net.d/***   比如  kubelet /etc/cni/net.d/10-flannel.conflist --help

 

flannel网络

默认vxlan作为后端传输机制

1.原生vxlan overray  node 跨网段

2.Drirectrouting  node即支持同一网段也支持跨网段overray, 跨网段由就用vxlan overray,同一网段就是直接路由,如果node间同一网段,就用直接路由模式,如果跨了网段,就自动降为vxlan overray,直接路由方式就是用的 host_gw,类似于桥接方式

 

host_gw: Host Gateway  node仅支持同一网段,直接走nodenode_gateway网关,node的物理网络IP作为路由,即直接路由

 

udp 普通报文

 

flannel.1 封装后端协议报文的

 

flannel网络配置参数

kubectl get  configmaps -n kube-system

kubectl get  configmaps -n kube-system kube-flannel-cfg  -o yaml

Network: flannel使用的cidr格式的网络地址,用于为pod配置网络功能 10.244.0.0/16 -->master: 10.244.0.0/24 node1:10.244.1.0/24 .. node255:10.244.255.0/24

                        或者 10.0.0.0/8  --> 10.0.0.0/24  10.255.255.0/24

 

Subnetlen:network切分子网供供给各节点使用时,使用多长的掩码进行切分,默认为24位;

Subnetmin: 10.244.10.0/24 起始子网

Subnetmax: 10.244.100.0/24 结束子网

Backend:后端通信方式 vxlan(vxlandirectrouting), host-gw, udp

 

查看网桥

yum install brctls-utils  -y

brctl show cni0

 

到各node抓包分析

跨节点nodepod ping测试

yum install tcpdump -y

tcpdump -i cni0 icmp

 

pod -->node1下的cni0 --->node1下的flannel.1 -->node2下的flannel.1-->node2下的cni0  --> pod

ip route show

10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink

10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink

tcpdump -i flannel.1 -nn

 

抓包分析node间物理网络

tcpdump -i ens33  -nn host 192.168.81.30

12:18:23.231595 IP node2.55445 > node1.otv: OTV, flags [I] (0x08), overlay 0, instance 1

IP myapp-1.myapp-svc.default.svc.cluster.local > myapp-0.myapp-svc.default.svc.cluster.local: ICMP echo reply, id 3840, seq 20, length 64

看出是overlay网络,即用的vxlan模型 且有pod的通信包 即隧道转发

 

实验

flannel改成vxlan-directrouting通信

1.通过jsonconfig

mkdir flannel  && cd flannel/  

vim net-conf.json

{

  "Network": "10.244.0.0/16",

   "Backend": {

      "Type": "vxlan",

      "Directrouting": "true"

   }

}

 

2.edit

kubectl -n kube-system edit configmaps kube-flannel-cfg

"Backend": {

        "Type": "vxlan",

        "Directrouting": true

      }

 

ip route show 查看路由

flannel重读配置文件生效

 

3.重新声明yaml清单

 vim kube-flannel.yml

 net-conf.json: |

    {

      "Network": "10.244.0.0/16",

      "Backend": {

        "Type": "vxlan",

        "Directrouting": true

      }

    }

kubectl delete -f kube-flannel.yml

kubectl apply -f kube-flannel.yml

ip route show

10.244.1.0/24 via 192.168.81.20 dev ens33

10.244.2.0/24 via 192.168.81.30 dev ens33  直接路由生效了

 

新建pod测试

kubectl delete -f deploy-demo.yaml

kubectl apply -f deploy-demo.yaml

kubectl exec -it myapp-deploy-55b78d8548-8dtpv -- /bin/sh

ping 10.244.2.131  ping另一节点新创建的pod

node上抓包

tcpdump -i ens33 -nn host  192.168.81.30 已经按不到overay网络包了,说明走的直接路由, node的物理网络IP作为路由

 

flannel改成vxlan-directrouting通信

vim kube-flannel.yml

 net-conf.json: |

    {

      "Network": "10.244.0.0/16",

      "Backend": {

        "Type": "host-gw”

      }

}

kubectl delete -f kube-flannel.yml

kubectl apply -f kube-flannel.yml

ip route show

10.244.1.0/24 via 192.168.81.20 dev ens33

10.244.2.0/24 via 192.168.81.30 dev ens33

 

canal部署

https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/flannel

 

kubectl  apply  -f  https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml

 

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml

 

kubectl get pods -n kube-system

 

控制网络策略

kubectl explain networkpolicy

kubectl explain networkpolicy.spec

 

出站

kubectl explain networkpolicy.spec.egress

kubectl explain networkpolicy.spec.egress.ports

kubectl explain networkpolicy.spec.egress.to

 

入站

kubectl explain networkpolicy.spec.ingress

 

policyTypes <[]string>

kubectl explain networkpolicy.spec.policyTypes

 

ingress控制

mkdir networkpolicy && cd networkpolicy/

 vim ingress-def.yaml

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: deny-all-ingress

 # namespace: dev

spec:

  podSelector: {}  空,表示选名称空间中所有的pod

policyTypes: 定义使用哪个策略

- Ingress 表示启用ingress 如果没写ingress规则,表示拒绝所有ingress。如果policyType下面没写- engress,表示不控制engress,放开所有engress

 

创建ns

kubectl create namespace dev

kubectl create namespace prod

 

创建规则

kubectl apply -f ingress-def.yaml -n dev  外面指定namespace

查询规则

kubectl  get networkpolicy  -n dev

 

验证

vim pod-a.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod1

spec:

  containers:

  - name: myapp

    image: ikubernetes/myapp:v1

 

dev空间创建一个pod

kubectl apply -f pod-a.yaml -n dev

curl 10.244.1.7 不能访问 dev定义了ingress 拒绝了

 

kubectl apply -f pod-a.yaml -n prod

curl 10.244.1.8

Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

 

vim ingress-def.yaml

spec:

  podSelector: {}

  ingress: 定义ingress规则

  - {}  没写内容,表示放行所有

 

kubectl apply -f ingress-def.yaml -n dev

 curl 10.244.1.7

Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>  又能访问了

 

打上标签

kubectl label pods pod1 app=myapp -n dev

 

vim allow-netpolicy-demo.yaml

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: allow-maypp-ingress

spec:

  podSelector:  选择控制哪些pod 通过pod标签

    matchLabels:

      app: myapp

  ingress:  ingress规则

  - from:  远端的地址

    - ipBlock: 地址块

        cidr: 10.244.0.0/16  允许cidr类这个网段都放行

        except:  除了这个

        - 10.244.1.2/32

   ports:  允许的端口

    - protocol: TCP

      port: 80  没写就表示所有端口都放行

 

创建规则

kubectl apply -f allow-netpolicy-demo.yaml  -n dev

 

egress控制

cp ingress-def.yaml egress-def.yaml

vim egress-def.yaml

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: deny-all-egress

spec:

  podSelector: {}

  policyTypes:

  - Egress 使用出站规则 如果没定义egress,表示拒绝所有

 

网络访问控制规则在 prod空间生效

kubectl apply -f egress-def.yaml -n prod

测试

kubectl exec -it -n prod pod1  -- /bin/sh

ping  10.244.0.60  ping不出去,因为egress拒绝出站了

 

vim egress-def.yaml

spec:

  podSelector: {}

  egress: 定义了egress规则,写的为空,表示放行所有出去

  - {}

  policyTypes:

  - Egress

 

 kubectl apply -f egress-def.yaml -n prod

测试

kubectl exec -it -n prod pod1  -- /bin/sh

ping  10.244.0.60  ping

 

网络策略:

名称空间: 拒绝所有出站入站;放行所有本名称空间pod的出站入站规则

posted on 2019-08-13 01:04  SZ_文彬  阅读(756)  评论(0编辑  收藏  举报