Calico网络组件实践(BGP、RR、IPIP)

Kubernetes网络方案之 Calico

Calico是一个纯三层的数据中心网络方案,Calico支持广泛的平台,包括Kubernetes、OpenStack等。

Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。

此外,Calico 项目还实现了 Kubernetes 网络策略,提供ACL功能。

1、BGP概述

实际上,Calico项目提供的网络解决方案,与Flannel的host-gw模式几乎一样。也就是说,Calico也是基于路由表实现容器数据包转发,但不同于Flannel使用flanneld进程来维护路由信息的做法,而Calico项目使用BGP协议来自动维护整个集群的路由信息。

BGP英文全称是Border Gateway Protocol,即边界网关协议,它是一种自治系统间的动态路由发现协议,与其他 BGP 系统交换网络可达信息。

为了能让你更清楚理解BGP,举个例子:

在这个图中,有两个自治系统(autonomous system,简称为AS):AS 1 和 AS 2。

在互联网中,一个自治系统(AS)是一个有权自主地决定在本系统中应采用何种路由协议的小型单位。这个网络单位可以是一个简单的网络也可以是一个由一个或多个普通的网络管理员来控制的网络群体,它是一个单独的可管理的网络单元(例如一所大学,一个企业或者一个公司个体)。一个自治系统有时也被称为是一个路由选择域(routing domain)。一个自治系统将会分配一个全局的唯一的16位号码,有时我们把这个号码叫做自治系统号(ASN)。

在正常情况下,自治系统之间不会有任何来往。如果两个自治系统里的主机,要通过 IP 地址直接进行通信,我们就必须使用路由器把这两个自治系统连接起来。BGP协议就是让他们互联的一种方式。

2、Calico BGP实现

在了解了 BGP 之后,Calico 项目的架构就非常容易理解了,Calico主要由三个部分组成:

  • Felix:以DaemonSet方式部署,运行在每一个Node节点上,主要负责维护宿主机上路由规则以及ACL规则。
  • BGP Client(BIRD):主要负责把 Felix 写入 Kernel 的路由信息分发到集群 Calico 网络。
  • Etcd:分布式键值存储,保存Calico的策略和网络配置状态。
  • calicoctl:允许您从简单的命令行界面实现高级策略和网络。
3、Calico 部署
curl https://docs.projectcalico.org/v3.9/manifests/calico-etcd.yaml -o calico.yaml

下载完后还需要修改里面配置项:

具体步骤如下:

  • 配置连接etcd地址,如果使用https,还需要配置证书。(ConfigMap,Secret)
  • 根据实际网络规划修改Pod CIDR(CALICO_IPV4POOL_CIDR)
  • 选择工作模式(CALICO_IPV4POOL_IPIP),支持BGP,IPIP
查看证书所在位置:
[root@k8s-master1 ~]# ls /opt/etcd/ssl/
ca.pem          server-key.pem  server.pem

拼接ca密钥, ca的key以及数字证书内容为1条字符串:
[root@k8s-master1 ~]# cat /opt/etcd/ssl/ca.pem |base64 -w 0
[root@k8s-master1 ~]# cat /opt/etcd/ssl/server-key.pem |base64 -w 0
[root@k8s-master1 ~]# cat /opt/etcd/ssl/server.pem |base64 -w 0

[root@k8s-master1 ~]# vim calico.yaml

###etcd证书:
···
###第一处:
etcd-key: 对应如上server-key.pem生成的字符串
etcd-cert: 对应如上server.pem生成的字符串
etcd-ca: 对应如上ca.pem生成的字符串

###第二处:(直接删除注释即可)
  etcd_ca: "/calico-secrets/etcd-ca"
  etcd_cert: "/calico-secrets/etcd-cert"
  etcd_key: "/calico-secrets/etcd-key"

###第三处:可查看此文件:[root@k8s-master1 ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf中etcd的配置:
etcd_endpoints: "https://192.168.171.11:2379,https://192.168.171.12:2379,https://192.168.171.13:2379"
···

###修改Pod CIDR(查看:cat /opt/kubernetes/cfg/kube-controller-manager.conf 的 --cluster-cidr=10.244.0.0/16 \)
···
- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/16"
···

###选择工作模式
calico默认工作模式是IPIP,我们需要注释掉,然后默认就会改为BGP,Always改为Never即可
# Enable IPIP
- name: CALICO_IPV4POOL_IPIP
  value: "Nerver"

★★★ 修改完成如上配置文件后,因为flannel升级calico,flannel默认的一些路由策略还会依旧保存,我们需要先删除,不然路由策略依然还会走之前的,导致问题!! ★★★

[root@k8s-master1 ~]# ip link delete cni0
[root@k8s-master1 ~]# ip link delete flannel.1

查看路由表再次确认(每个node都需要检查一下):
[root@k8s-node2 ~]# ip route
default via 192.168.171.2 dev ens33 proto static metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.171.0/24 dev ens33 proto kernel scope link src 192.168.171.13 metric 100
或者手动删除一些静态路由:
[root@k8s-master1 ~]# ip route del 10.244.1.0/24 via 192.168.171.12 dev ens33
[root@k8s-master1 ~]# ip route del 10.244.2.0/24 via 192.168.171.13 dev ens33
[root@k8s-master1 ~]# ip route del 10.244.3.0/24 via 192.168.171.14 dev ens33

修改完后应用清单:

[root@k8s-master1 ~]# kubectl apply -f calico.yaml

[root@k8s-master1 ~]# kubectl get pods -n kube-system
NAME                                      READY   STATUS             RESTARTS   AGE
calico-kube-controllers-f68c55884-tx2km   1/1     Running            0          4m26s
calico-node-5kqcl                         1/1     Running            0          4m27s
calico-node-ck4gf                         1/1     Running            0          4m27s
calico-node-jp9kj                         1/1     Running            0          4m26s
calico-node-mnslt                         1/1     Running            0          4m27s
★★★

最后一点:当我们升级完毕,查看路由表时候,神奇的发现竟然没有任何路由!!

最终查找资料确认了其中的问题:现有容器需要重建!!

★★★

再次查看路由:

[root@k8s-master1 ~]# ip route
default via 192.168.171.2 dev ens33 proto static metric 100
10.244.36.64/26 via 192.168.171.12 dev ens33 proto bird
10.244.107.192/26 via 192.168.171.14 dev ens33 proto bird
blackhole 10.244.159.128/26 proto bird
10.244.159.132 dev calicc2e4908bc6 scope link
10.244.159.133 dev calid85356b2213 scope link
10.244.169.128/26 via 192.168.171.13 dev ens33 proto bird
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.171.0/24 dev ens33 proto kernel scope link src 192.168.171.11 metric 100

4、Calico 管理工具

下载工具:https://github.com/projectcalico/calicoctl/releases

# wget -O /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v3.9.1/calicoctl
# chmod +x /usr/local/bin/calicoctl
# mkdir /etc/calico
# vim /etc/calico/calicoctl.cfg  
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
  datastoreType: "etcdv3"
  etcdEndpoints: "https://192.168.31.61:2379,https://192.168.31.62:2379,https://192.168.31.63:2379"
  etcdKeyFile: "/opt/etcd/ssl/server-key.pem"
  etcdCertFile: "/opt/etcd/ssl/server.pem"
  etcdCACertFile: "/opt/etcd/ssl/ca.pem"

使用calicoctl查看服务状态:

[root@k8s-master1 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 192.168.171.12 | node-to-node mesh | up    | 14:33:24 | Established |
| 192.168.171.13 | node-to-node mesh | up    | 14:33:29 | Established |
| 192.168.171.14 | node-to-node mesh | up    | 14:33:26 | Established |
+----------------+-------------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.
[root@k8s-master1 ~]# calicoctl get nodes
NAME
k8s-master1
k8s-node1
k8s-node2
k8s-node3

查看 IPAM的IP地址池:

[root@k8s-master1 ~]# calicoctl get ippool -o wide
NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   SELECTOR
default-ipv4-ippool   10.244.0.0/16   true   Never      Never       false      all()
5、Calico BGP 原理剖析

Pod 1 访问 Pod 2大致流程如下:

  1. 数据包从容器1出到达Veth Pair另一端(宿主机上,以cali前缀开头);

  2. 宿主机根据路由规则,将数据包转发给下一跳(网关);

  3. 到达Node2,根据路由规则将数据包转发给cali设备,从而到达容器2。

路由表:

# node1
10.244.36.65 dev cali4f18ce2c9a1 scope link 
10.244.169.128/26 via 192.168.31.63 dev ens33 proto bird 
10.244.235.192/26 via 192.168.31.61 dev ens33 proto bird 
# node2
10.244.169.129 dev calia4d5b2258bb scope link 
10.244.36.64/26 via 192.168.31.62 dev ens33 proto bird
10.244.235.192/26 via 192.168.31.61 dev ens33 proto bird

其中,这里最核心的“下一跳”路由规则,就是由 Calico 的 Felix 进程负责维护的。这些路由规则信息,则是通过 BGP Client 也就是 BIRD 组件,使用 BGP 协议传输而来的。

不难发现,Calico 项目实际上将集群里的所有节点,都当作是边界路由器来处理,它们一起组成了一个全连通的网络,互相之间通过 BGP 协议交换路由规则。这些节点,我们称为 BGP Peer。

6、Route Reflector 模式(RR)

https://docs.projectcalico.org/master/networking/bgp

Calico 维护的网络在默认是(Node-to-Node Mesh)全互联模式,Calico集群中的节点之间都会相互建立连接,用于路由交换。但是随着集群规模的扩大,mesh模式将形成一个巨大服务网格,连接数成倍增加。

例如:

node1  node2  node3

node1 ==> node2 ==> node3
node2 ==> node1 ==> node3
node3 ==> node1 ==> node2
noden ...

如上路由模式是node-node,这种模式下整个集群的node需要控制在100台左右!!

也就是说node1上需要建立2条路由 node2上也需要建立node1和node3这2条路由,如集群很大,一旦增加1node,就需要成倍的路由需要建立!!

这时就需要使用 Route Reflector(路由器反射)模式解决这个问题。

这就类似一个nginx 后端的node作为负载,一旦有新的node只需要和路有反射的机器建立路由关系即可!!

确定一个或多个Calico节点充当路由反射器,让其他节点从这个RR节点获取路由信息。

具体步骤如下:

1、关闭 node-to-node BGP网格

★★★ 一旦更改,整个集群网路就会断掉!!!线上一定要先评估!! ★★★

添加 default BGP配置,调整 nodeToNodeMeshEnabled和asNumber:

cat << EOF | calicoctl create -f -
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: false  
  asNumber: 63400
EOF

ASN号可以通过获取:

# calicoctl get nodes --output=wide

2、配置指定节点充当路由反射器

为方便让BGPPeer轻松选择节点,通过标签选择器匹配。

给路由器反射器节点打标签:

[root@k8s-master1 ~]# kubectl label node k8s-node2 route-reflector=true
node/k8s-node2 labeled

然后编辑刚打了tag的node节点:

[root@k8s-master1 ~]# calicoctl get node k8s-node2 -o yaml > node2.yaml

然后配置路由器反射器节点routeReflectorClusterID:

[root@k8s-master1 ~]# vim node2.yaml
apiVersion: projectcalico.org/v3
kind: Node
metadata:
  annotations:
    projectcalico.org/kube-labels: '{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"k8s-node2","kubernetes.io/os":"linux","route-reflector":"true"}'
  creationTimestamp: 2019-12-25T14:02:11Z
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: k8s-node2
    kubernetes.io/os: linux
    route-reflector: "true"
  name: k8s-node2
  resourceVersion: "349138"
  uid: 9387fc14-f6f4-4809-a8f2-418ed81ba6ca
spec:
  bgp:
    ipv4Address: 192.168.171.13/24
    routeReflectorClusterID: 244.0.0.1   # 集群ID,保证唯一性
  orchRefs:
  - nodeName: k8s-node2
    orchestrator: k8s

应用:

[root@k8s-master1 ~]# calicoctl apply -f node2.yaml
Successfully applied 1 'Node' resource(s)

现在,很容易使用标签选择器将路由反射器节点与其他非路由反射器节点配置为对等:

[root@k8s-master1 ~]# vim setbgprr.yaml
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: peer-with-route-reflectors
spec:
  nodeSelector: all()
  peerSelector: route-reflector == 'true'
  
  
##创建规则:
[root@k8s-master1 ~]# calicoctl apply -f setbgprr.yaml
Successfully applied 1 'BGPPeer' resource(s)

查看节点的BGP连接状态:(只与171.13建立了连接,再次ping网路就通了)

[root@k8s-master1 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.171.13 | node specific | up    | 15:19:42 | Established |
+----------------+---------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.

查看规则:

[root@k8s-master1 ~]# calicoctl get bgppeer
NAME                         PEERIP   NODE    ASN
peer-with-route-reflectors            all()   0

==当然rr和nginx也是一致的,也需要高可用,所以我们尽量配置2台以上的节点!==

条件允许的话,最好找2台单独的机器!

[root@k8s-master1 ~]# kubectl label node k8s-node1 route-reflector=true
node/k8s-node1 labeled

[root@k8s-master1 ~]# calicoctl get node k8s-node1 -o yaml > node1.yaml
[root@k8s-master1 ~]# vim node1.yaml(增加和node2一致即可)
···
routeReflectorClusterID: 244.0.0.1   # 集群ID,保证唯一性
···

[root@k8s-master1 ~]# calicoctl apply -f node1.yaml
Successfully applied 1 'Node' resource(s)

再次查看:

[root@k8s-master1 ~]# calicoctl node status
Calico process is running.

IPv4 BGP status
+----------------+---------------+-------+----------+-------------+
|  PEER ADDRESS  |   PEER TYPE   | STATE |  SINCE   |    INFO     |
+----------------+---------------+-------+----------+-------------+
| 192.168.171.13 | node specific | up    | 15:19:42 | Established |
| 192.168.171.12 | node specific | up    | 15:26:13 | Established |
+----------------+---------------+-------+----------+-------------+


7、IPIP模式

和flannel的vxlan差不多模式,也是基于二层数据的封装和解封;也会创建一个虚拟网卡 tunl0

在前面提到过,Flannel host-gw 模式最主要的限制,就是要求集群宿主机之间是二层连通的。而这个限制对于 Calico 来说,也同样存在。

修改为IPIP模式:

# calicoctl get ipPool -o yaml > ipip.yaml
# vi ipip.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: default-ipv4-ippool
spec:
  blockSize: 26
  cidr: 10.244.0.0/16
  ipipMode: Always
  natOutgoing: true

# calicoctl apply -f ipip.yaml
# calicoctl get ippool -o wide

IPIP示意图:

Pod 1 访问 Pod 2大致流程如下:

  1. 数据包从容器1出到达Veth Pair另一端(宿主机上,以cali前缀开头);
  2. 进入IP隧道设备(tunl0),由Linux内核IPIP驱动封装在宿主机网络的IP包中(新的IP包目的地之是原IP包的下一跳地址,即192.168.31.63),这样,就成了Node1 到Node2的数据包;
  3. 数据包经过路由器三层转发到Node2;
  4. Node2收到数据包后,网络协议栈会使用IPIP驱动进行解包,从中拿到原始IP包;
  5. 然后根据路由规则,根据路由规则将数据包转发给cali设备,从而到达容器2。

路由表:

# node1
10.244.36.65 dev cali4f18ce2c9a1 scope link 
10.244.169.128/26 via 192.168.31.63 dev tunl0 proto bird onlink 
# node2
10.244.169.129 dev calia4d5b2258bb scope link 
10.244.36.64/26 via 192.168.31.62 dev tunl0 proto bird onlink

==不难看到,当 Calico 使用 IPIP 模式的时候,集群的网络性能会因为额外的封包和解包工作而下降。所以建议你将所有宿主机节点放在一个子网里,避免使用 IPIP。==

8、CNI 网络方案优缺点及最终选择

先考虑几个问题:

  • 需要细粒度网络访问控制? ==》 flannel不支持,calico支持(ACL);
  • 追求网络性能? ==》 flannel(host-gw),calico(BGP);
  • 服务器之前是否可以跑BGP协议? ==》 公有云有些不支持;
  • 集群规模多大? ==》 100台node左右推荐(flannel)维护方便;
  • 是否有维护能力? ==》 calico维护复杂,路由表!

小话题:办公网络与K8S网络如何互通

4.5 网络策略

1、为什么需要网络隔离?

CNI插件插件解决了不同Node节点Pod互通问题,从而形成一个扁平化网络,默认情况下,Kubernetes 网络允许所有 Pod 到 Pod 的流量,在一些场景中,我们不希望Pod之间默认相互访问,例如:

  • 应用程序间的访问控制。例如微服务A允许访问微服务B,微服务C不能访问微服务A
  • 开发环境命名空间不能访问测试环境命名空间Pod
  • 当Pod暴露到外部时,需要做Pod白名单
  • 多租户网络环境隔离

所以,我们需要使用network policy对Pod网络进行隔离。支持对Pod级别和Namespace级别网络访问控制。

路由器层面解决:

1、K8S集群测试环境在办公网路子网:
# ip route add 10.244.0.0/16 via <K8S-NODE1> dev A

2、K8S集群与办公网路不在同VLAN, 不同机房:
前提:三层可达
1)路由器添加路由表:10.244.0.0/16 <K8S-NODE1>
2) 路由器BGP与路由反射器建立连接;

Pod网络入口方向隔离

  • 基于Pod级网络隔离:只允许特定对象访问Pod(使用标签定义),允许白名单上的IP地址或者IP段访问Pod
  • 基于Namespace级网络隔离:多个命名空间,A和B命名空间Pod完全隔离。

Pod网络出口方向隔离

  • 拒绝某个Namespace上所有Pod访问外部
  • 基于目的IP的网络隔离:只允许Pod访问白名单上的IP地址或者IP段
  • 基于目标端口的网络隔离:只允许Pod访问白名单上的端口
2、网络策略概述

一个NetworkPolicy例子:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db      ##db的这个应用的容器
  policyTypes:
  - Ingress
  - Egress
  ingress:  ##访问pod的流量(入方向)
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16     ##此ip段可以访问
        except: ##除了如下这个IP段不可以访问
        - 172.17.1.0/24
    - namespaceSelector:    ##namespace
        matchLabels:
          project: myproject
    - podSelector:      ##pod
        matchLabels:
          role: frontend
    ports:      ##ports端口
    - protocol: TCP
      port: 6379
  egress:   ##出去的流量(出方向)
  - to:
    - ipBlock:  ##只能访问如下此网段
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP     ##且端口为5978
      port: 5978

配置解析:

  • podSelector:用于选择策略应用到的Pod组。

  • policyTypes:其可以包括任一Ingress,Egress或两者。该policyTypes字段指示给定的策略用于Pod的入站流量、还是出站流量,或者两者都应用。如果未指定任何值,则默认值为Ingress,如果网络策略有出口规则,则设置egress。

  • Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports是可以访问的端口。

  • Egress:这个Pod组可以访问外部的IP段和端口。

3、入站、出站网络流量访问控制案例

Pod访问限制

准备测试环境,一个web pod,两个client pod

# kubectl create deployment nginxweb --image=nginx

# kubectl scale deployment nginxweb --replicas=3

# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS   AGE    LABELS
nginxweb-c5d5747f8-4wff9    1/1     Running   1          24h    app=nginxweb,pod-template-hash=c5d5747f8
nginxweb-c5d5747f8-6zbk6    1/1     Running   0          3m2s   app=nginxweb,pod-template-hash=c5d5747f8
nginxweb-c5d5747f8-xxfc9    1/1     Running   1          24h    app=nginxweb,pod-template-hash=c5d5747f8

需求将default命名空间携带run=nginxweb标签的Pod隔离,只允许default命名空间携带run=client1标签的Pod访问80端口。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginxweb
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: default 
    - podSelector:
        matchLabels:
          run: client1
    ports:
    - protocol: TCP
      port: 80
##创建如上规则
# kubectl apply -f networkpolicy.yaml
networkpolicy.networking.k8s.io/test-network-policy created

# kubectl run client1 --generator=run-pod/v1 --image=busybox --command -- sleep 36000      ##快速的启动一个测试容器

# kubectl exec -it client1 sh
/ # ping 10.244.169.143     ##从容器中测试访问另外的pod
PING 10.244.169.143 (10.244.169.143): 56 data bytes
64 bytes from 10.244.169.143: seq=0 ttl=62 time=0.639 ms
完全可以访问;

# kubectl run client2 --generator=run-pod/v1 --image=busybox --command -- sleep 36000      ##再次启动一个client2pod,按照规则client2是不允许访问80端口的

[root@k8s-master1 ~]# kubectl exec -it client2 sh
/ # wget 10.244.36.73
Connecting to 10.244.36.73 (10.244.36.73:80)
^C      ##看来是不可以访问的

##再来测试下client1
[root@k8s-master1 ~]# kubectl exec -it client1 sh
/ # wget 10.244.36.73
Connecting to 10.244.36.73 (10.244.36.73:80)
saving to 'index.html'
index.html           100% |***********************************************************************************************************************|   612  0:00:00 ETA
'index.html' saved      
/ # ping 10.244.36.73
PING 10.244.36.73 (10.244.36.73): 56 data bytes
^C
--- 10.244.36.73 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
如上可以看得出:##可以访问!!但是不可以ping;

看来如上策略就生效了,达到了预期的效果,只可以访问80, 其余均不可以!

隔离策略配置:

Pod对象:default命名空间携带run=web标签的Pod

允许访问端口:80

允许访问对象:default命名空间携带run=client1标签的Pod

拒绝访问对象:除允许访问对象外的所有对象

命名空间隔离

需求default命名空间下所有pod可以互相访问,但不能访问其他命名空间Pod,其他命名空间也不能访问default命名空间Pod。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces 
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

podSelector: {}:default命名空间下所有Pod

from.podSelector: {} : 如果未配置具体的规则,默认不允许

解除如上的规则:
[root@k8s-master1 ~]# kubectl delete -f networkpolicy.yaml
networkpolicy.networking.k8s.io "test-network-policy" deleted
[root@k8s-master1 ~]# kubectl exec -it client2 sh
/ # ping 10.244.36.73   ##现在已经可以ping了
PING 10.244.36.73 (10.244.36.73): 56 data bytes
64 bytes from 10.244.36.73: seq=0 ttl=63 time=0.313 ms
64 bytes from 10.244.36.73: seq=1 ttl=63 time=0.083 ms

如上我们的新需求是:default命名空间下所有pod可以互相访问,但不能访问其他命名空间Pod,其他命名空间也不能访问default命名空间Pod。

# kubectl run client3 --generator=run-pod/v1 -n kube-system --image=busybox --command -- sleep 36000
pod/client3 created     ##在kube-system环境中创建一个pod

[root@k8s-master1 ~]# kubectl exec -it client3 sh -n kube-system
/ # ping 10.244.36.73       ##也是可以访问default空间的pod
PING 10.244.36.73 (10.244.36.73): 56 data bytes
64 bytes from 10.244.36.73: seq=0 ttl=62 time=1.394 ms
64 bytes from 10.244.36.73: seq=1 ttl=62 time=0.425 ms
^C
--- 10.244.36.73 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.425/0.909/1.394 ms

##应用如上规则:
[root@k8s-master1 ~]# kubectl apply -f ns22.yaml
networkpolicy.networking.k8s.io/deny-from-other-namespaces created

[root@k8s-master1 ~]# kubectl exec -it client3 sh -n kube-system
/ # ping 10.244.36.73       ##再次访问就不可以了!!
PING 10.244.36.73 (10.244.36.73): 56 data bytes
^C
--- 10.244.36.73 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

文末彩蛋:

来讲下我们目前公司的网路架构吧: - calico(BGP)一个集群支持上千个节点问题不大; - 将所有机房的网路打通; - 3台路由反射器,对接每个节点的网关路由器进行BGP模式下的路由交换,这样就会将整个的pod_ip全部暴露在网路中; - LVS对pod做负载均衡;



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!