36-k8s的网络解决方案

一、calico和flannel的区别

Flannel和Calico都是用Kubernetes的网络解决方案,它们各有特点和适用场景。
以下是它们之间的主要区别,工作原理和特性:
Flannel:
	-1.工作原理:
		Flannel基于VXLAN技术实现,通过创建一个覆盖网络(overlay network)来实现容器间的通信。
				
		每个节点分配一个唯一的子网,通过路由规则实现Pod之间的通信。
				
		Flannel在每个主机上运行一个flanneld守护进程,用于分配子网并存储网络配置信息。

	-2.网络拓扑结构:
		Flannel的网络拓扑结构是扁平的,所有节点都在同一个二层网络中。
				
		host-gw工作模式不能跨网段,如果非要跨网段则需要自行维护路由,得不偿失。使用vxlan模式可以跨网段,但是数据会封装2次,效率低。

	-3.支持的容器平台:
		Flannel支持多种容器平台,包括Kubernetes、Docker、Mesos等。

	-4.网络策略实现方式:
		Flannel的网络策略通过iptables规则实现。但是iptables想想都头疼,因此我们几乎默认flannel不支持网络策略!

Calico:
	-1.工作原理:
		Calico基于BGP协议实现容器间的通信,每个节点运行一个Calico agent来监控和管理网络,使用iptables和ipset进行网络安全策略控制。
				
		因此我们说calico在网络安全策略上是优于falnnel,因为falnnel仅支持iptables。

	- 2.网络拓扑结构:
		Calico的网络拓扑结构是层级的,使用BGP协议实现路由。说白了,能够实现动态路由,相当于falnnel的host-gw模式。

	- 3.支持的容器平台:
		Calico主要针对Kubernetes,OpenStack。

	- 4.网络策略实现方式:
		Calico的网络策略通过网络策略对象(Network Policy Object)实现。

性能表现:
	Flannel使用VXLAN进行封装会造成额外的CPU和网络开销,而Calico的路由方式较为高效,性能表现更好。
	
	
选择建议:
	根据具体需求和环境来决定选择Flannel还是Calico。
	
	1.如果网络通信需求较为简单,且需要支持多种容器平台,Flannel可能是一个不错的选择。
	
	2.如果网络通信需求复杂,且需要高性能的网络解决方案,Calico可能更适合。
	
	3.在选择时还应考虑性能、安全性、可扩展性等因素。

二、网络策略

1.什么是网络策略

	所谓的网络策略,指的是Pod之间访问实现网络控制,默认情况下,同一k8s集群的所有Pod是能够互相访问的。


	但有时候某些pod为了安全性是不允许或者只允许部分Pod来访问,这个时候就需要使用到网络策略。


推荐阅读:
	Kubeadm 的官方文档:
		https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/

	网络策略官网:
		https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/ 

2.实战案例

2.1 环境准备

[root@master231 networkpolciy]# cat deploy-xiuxian.yaml 
apiVersion: v1
kind: Namespace
metadata:
  labels:
    class: linux96
  name: dingzhiyan

---

apiVersion: v1
kind: Namespace
metadata:
  labels:
    school: dingzhiyan
  name: jasonyin

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xiuxian-v1
  namespace: dingzhiyan
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: v1
  template:
    metadata:
      labels:
        apps: v1
    spec:
      nodeName: worker232
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
        name: c1
---


apiVersion: apps/v1
kind: Deployment
metadata:
  name: xiuxian-v2
  namespace: jasonyin
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: v2
  template:
    metadata:
      labels:
        apps: v2
    spec:
      nodeName: worker233
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
        name: c1

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xiuxian-v3
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: v3
  template:
    metadata:
      labels:
        apps: v3
    spec:
      nodeName: master231
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v3
        name: c1
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl apply -f deploy-xiuxian.yaml 
namespace/dingzhiyan created
namespace/jasonyin created
deployment.apps/xiuxian-v1 created
deployment.apps/xiuxian-v2 created
deployment.apps/xiuxian-v3 created
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl get pods -A -l apps -o wide 
NAMESPACE   NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
default     xiuxian-v3-fbbcf9474-xngvg    1/1     Running   0          46s   10.100.160.137   master231   <none>           <none>
jasonyin    xiuxian-v2-768f95c4d8-nrzgf   1/1     Running   0          46s   10.100.140.69    worker233   <none>           <none>
dingzhiyan   xiuxian-v1-6545d56f7c-x4k8q   1/1     Running   0          46s   10.100.203.133   worker232   <none>           <none>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 

2.2 测试连通性,默认情况下都是可以正常访问的(三个名称空间的Pod两两测试验证连通性正常)

[root@master231 networkpolciy]# kubectl exec xiuxian-v3-fbbcf9474-xngvg -- curl -s 10.100.140.69 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl exec xiuxian-v3-fbbcf9474-xngvg -- curl -s 10.100.203.133 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v1</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: green">凡人修仙传 v1 </h1>
    <div>
      <img src="1.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl  -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s 10.100.160.137
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v3</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: pink">凡人修仙传 v3 </h1>
    <div>
      <img src="3.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl  -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s 10.100.203.133  
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v1</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: green">凡人修仙传 v1 </h1>
    <div>
      <img src="1.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl  -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s  10.100.160.137
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v3</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: pink">凡人修仙传 v3 </h1>
    <div>
      <img src="3.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl  -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s   10.100.140.69 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 

2.3.基于ipBlock定义黑名单网络访问策略

[root@master231 networkpolciy]# cat networkPolicy-ipBlock.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: dingzhiyan
spec:
  # 基于标签匹配指定的Pod,若不定义该字段则默认匹配当前名称空间下的所有Pod。
  podSelector:
    matchLabels:
      apps: v1
  # 表示给定的策略是应用于进入所选Pod的入站流量(Ingress)还是来自所选Pod的出站流量(Egress),或两者兼有。 
  # 如果 NetworkPolicy未指定policyTypes,则默认情况下始终设置Ingress。
  # 如果 NetworkPolicy有任何出口规则的话则设置Egress。
  # 此处我不仅仅使用入站流量,还使用了出站流量
  policyTypes:
  - Ingress
  - Egress
  # 定义Pod的入站流量,谁可以访问我?
  ingress:
    # 表示定义目标来源
  - from:
      # 基于IP地址匹配
    - ipBlock:
        # 指定特定的网段
        cidr: 10.100.0.0/16
        # 排除指定的网段,说白了 ,该网段加入了访问黑名单。
        except:
        - 10.100.140.0/24
    ports:
    - protocol: TCP
      port: 80
  # 定义匹配Pod的出站流量,表示我可以访问谁?
  egress:
    # 定义可以访问的目标
  - to:
      # 基于IP地址匹配目标
    - ipBlock:
        #cidr: 10.100.160.0/24
        cidr: 10.100.140.0/24
    # 定义可以访问的目标端口
    ports:
    - protocol: TCP
      port: 80
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl apply -f networkPolicy-ipBlock.yaml 
networkpolicy.networking.k8s.io/test-network-policy created
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl get pods -A -l apps -o wide 
NAMESPACE   NAME                          READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
default     xiuxian-v3-fbbcf9474-xngvg    1/1     Running   0          9m43s   10.100.160.137   master231   <none>           <none>
jasonyin    xiuxian-v2-768f95c4d8-nrzgf   1/1     Running   0          9m43s   10.100.140.69    worker233   <none>           <none>
dingzhiyan   xiuxian-v1-6545d56f7c-x4k8q   1/1     Running   0          9m43s   10.100.203.133   worker232   <none>           <none>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s  10.100.140.69
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s  10.100.203.133
^C
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s  10.100.160.137 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v3</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: pink">凡人修仙传 v3 </h1>
    <div>
      <img src="3.jpg">
    <div>
  </body>

</html>
[root@master231 networkpolciy]# 

2.4. 基于名称空间namespaceSelector实现白名单案例

[root@master231 networkpolciy]# cat networkPolicy-namespaceSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: dingzhiyan
spec:
  # 匹配Pod指定的Pod,若不定义该字段则默认匹配所有的Pod。
  podSelector:
    matchLabels:
      apps: v1
  # 表示给定的策略是应用于进入所选Pod的入站流量(Ingress)还是来自所选Pod的出站流量(Egress),或两者兼有。 
  # 如果 NetworkPolicy未指定policyTypes,则默认情况下始终设置Ingress。
  # 如果 NetworkPolicy有任何出口规则的话则设置Egress。
  policyTypes:
  - Ingress
  - Egress
  # 定义Pod的入站流量,谁可以访问我?
  ingress:
    # 表示定义目标来源
  - from:
      # 基于名称空间匹配Pod
    - namespaceSelector:
        matchLabels:
          school: dingzhiyan
    # 匹配目标来源的端口号,可以指定协议和端口
    ports:
    - protocol: TCP
      port: 80
  # 定义匹配Pod的出站流量,表示我可以访问谁?
  egress:
    # 定义可以访问的目标
  - to:
      # 基于IP地址匹配目标,只能访问该网段的Pod,说白了,优点类似于白名单。
    - ipBlock:
        cidr: 10.100.140.0/24
    # 定义可以访问的目标端口
    ports:
    - protocol: TCP
      port: 80
      # port: 22
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl apply -f  networkPolicy-namespaceSelector.yaml
networkpolicy.networking.k8s.io/test-network-policy created
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 


[root@master231 ~]# kubectl get pods -A -l apps -o wide 
NAMESPACE   NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
default     xiuxian-v3-fbbcf9474-xngvg    1/1     Running   0          15m   10.100.160.137   master231   <none>           <none>
jasonyin    xiuxian-v2-768f95c4d8-nrzgf   1/1     Running   0          15m   10.100.140.69    worker233   <none>           <none>
dingzhiyan   xiuxian-v1-6545d56f7c-x4k8q   1/1     Running   0          15m   10.100.203.133   worker232   <none>           <none>
[root@master231 ~]# 
[root@master231 ~]# kubectl get ns -l school=dingzhiyan
NAME       STATUS   AGE
jasonyin   Active   15m
[root@master231 ~]# 
[root@master231 ~]# 
[root@master231 ~]# kubectl exec xiuxian-v3-fbbcf9474-xngvg -- curl -s 10.100.203.133 
^C
[root@master231 ~]# 
[root@master231 ~]# kubectl -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s 10.100.203.133 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v1</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: green">凡人修仙传 v1 </h1>
    <div>
      <img src="1.jpg">
    <div>
  </body>

</html>
[root@master231 ~]# 
[root@master231 ~]# kubectl -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s 10.100.160.137 
^C
[root@master231 ~]# 
[root@master231 ~]# kubectl -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s 10.100.140.69 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master231 ~]# 

2.5.基于Pod的标签podSelector进行访问

[root@master231 networkpolciy]# cat  networkPolicy-podSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: dingzhiyan
spec:
  # 此策略针对哪些Pod生效
  podSelector:
    matchLabels:
      apps: v1
  policyTypes:
  - Ingress
  - Egress
  # 匹配default名称标签为'apps=v3'的所有Pod
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: default
    - podSelector:
        matchLabels:
          apps: v3
  egress:
  - to:
    - ipBlock:
        cidr: 10.100.140.0/24
    ports:
    - protocol: TCP
      port: 80
      # port: 22
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl apply -f networkPolicy-podSelector.yaml 
networkpolicy.networking.k8s.io/test-network-policy configured
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# 
[root@master231 networkpolciy]# kubectl get netpol -n dingzhiyan 
NAME                  POD-SELECTOR   AGE
test-network-policy   apps=v1        13m
[root@master231 networkpolciy]# 

[root@master231 ~]# kubectl get pods -A -l apps -o wide  --show-labels
NAMESPACE   NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES   LABELS
default     xiuxian-v3-fbbcf9474-xngvg    1/1     Running   0          35m   10.100.160.137   master231   <none>           <none>            apps=v3,pod-template-hash=fbbcf9474
jasonyin    xiuxian-v2-768f95c4d8-nrzgf   1/1     Running   0          35m   10.100.140.69    worker233   <none>           <none>            apps=v2,pod-template-hash=768f95c4d8
dingzhiyan   xiuxian-v1-6545d56f7c-x4k8q   1/1     Running   0          35m   10.100.203.133   worker232   <none>           <none>            apps=v1,pod-template-hash=6545d56f7c
[root@master231 ~]# 
[root@master231 ~]# 
[root@master231 ~]# kubectl exec xiuxian-v3-fbbcf9474-xngvg -- curl -s 10.100.203.133   # default名称空间的pod可以正常访问
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v1</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: green">凡人修仙传 v1 </h1>
    <div>
      <img src="1.jpg">
    <div>
  </body>

</html>
[root@master231 ~]# 
[root@master231 ~]# kubectl -n jasonyin exec xiuxian-v2-768f95c4d8-nrzgf -- curl -s 10.100.203.133    # 非default名称空间的pod无法正常访问



[root@master231 ~]# kubectl -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s  10.100.140.69 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>yinzhengjie apps v2</title>
    <style>
       div img {
          width: 900px;
          height: 600px;
          margin: 0;
       }
    </style>
  </head>

  <body>
    <h1 style="color: red">凡人修仙传 v2 </h1>
    <div>
      <img src="2.jpg">
    <div>
  </body>

</html>
[root@master231 ~]# 
[root@master231 ~]# kubectl -n dingzhiyan exec xiuxian-v1-6545d56f7c-x4k8q -- curl -s  10.100.160.137  # 无法访问!
posted @ 2025-05-21 13:25  丁志岩  阅读(42)  评论(0)    收藏  举报