为AKS群集配置网络策略

时间:2023-02-23 16:15:57

网络策略是一种Kubernetes规范,其中针对Pod之间的通讯定义了访问策略。使用网络策略可以定义有关发送和接收流量的规则集,并将其应用到与一个或多个标签选择器相匹配的Pod集合。我们可以在Azure Kubernetes服务中使用网络策略,使用此功能,允许我们控制Pod之间的流量流。可以基于所分配的标签、命名空间或流量端口等设置,来允许或拒绝到Pod的流量。对于在AKS群集中的Pod之间流量的流动方式,应该使用最低权限原则。

今天主要和大家聊一下如何使用Kubernetes网络策略来控制AKS中Pod之间的流量流动方式。我们使用Calico网络策略。首先来检查下当前AKS群集的网络模式和网络策略,可以看到当前的网络模式为kubenet,已经启用了Calico网络策略:

为AKS群集配置网络策略

准备好启用网络策略的AKS群集以后,接下来开始定义网络策略

拒绝流向Pod的所有入站流量
创建演示资源

在定义规则以允许特定网络流量之前,需要先创建用于拒绝所有流量的网络策略。可以使用这个拒绝的网络策略作为起始点,然后仅为所需的流量创建允许列表。

首先我们先创建一个namespace来允许演示资源,运行如下命令创建

kubectl create ns dev

kubectl label ns/dev purpose=dev

为AKS群集配置网络策略

Namespace创建好以后,在创建一个运行Nginx的后端Pod。使用这个Pod模拟Web应用程序的后端。在dev命名空间中创建此Pod并打开80端口,用于web流量访问。在Pod上打上标签 app=webapp,role=backend,以便我们可在下一节中使用网络策略定向到它。

kubectl run backend --image=mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine --labels app=webapp,role=backend --namespace dev --expose --port 80

为AKS群集配置网络策略

创建另一个 Pod 并附加终端会话,然后运行wget命令,以测试是否可以成功访问默认的 NGINX 网页,可以看到当前能够成功访问到nginx网页:

kubectl run --rm -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11 network-policy --namespace dev
wget -qO- http://backend

为AKS群集配置网络策略


创建并应用网络策略

确定可以在后端Pod上使用基本的Nginx网页以后,接下来需要创建一个拒绝所有流量的网络策略。创建名为backend-policy.yaml的网络策略文件并粘贴以下 YAML 清单。 这个清单使用 podSelector 将策略附加到具有 app:webapp,role:backend标签的 Pod。Ingress下未定义任何规则,因此将拒绝流向 Pod 的所有入站流量

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: backend-policy
namespace: dev
spec:
podSelector:
matchLabels:
app: webapp
role: backend
ingress: []

使用kubectl apply -f 命令应用网络策略:

为AKS群集配置网络策略

网络策略应用完成以后,我们再测试下能否在后端Pod上使用Nginx网页,运行如下命令创建一个附加终端会话的Pod:

kubectl run --rm -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11 network-policy --namespace dev

为AKS群集配置网络策略

使用 ​​wget​​ 确认是否可以访问默认的 NGINX 网页。 这一次,将超时值设为 2 秒。 网络策略现在会阻止所有入站流量,因此无法加载页面,如以下示例中所示:

wget -O- --timeout=2 --tries=1 ​​http://backend​​

为AKS群集配置网络策略

允许基于Pod标签的流入流量

在前面的部分,我们已经部署了一个后端Nginx Pod并且使用网络策略拒绝了所有网络的入站流量,接下来让我们创建一个前端Pod并更新网络策略以允许来自前端Pod的流量。 首先让我们更新之前定义的网络策略,更新策略允许具有标签app:webapp, role:fronted的Pod的任何命名空间的流量:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: backend-policy
namespace: dev
spec:
podSelector:
matchLabels:
app: webapp
role: backend
ingress:
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
app: webapp
role: frontend

策略更新好以后,允许kubectl apply来更新网络策略:

为AKS群集配置网络策略

更新以后,允许一个带有app:webapp, role:fronted标签的Pod并打开终端会话:

为AKS群集配置网络策略

在shell提示符下,使用wget确认是否可以访问nginx网页, 可以看到,带有app:webapp, role:fronted标签的Pod可以正常访问到后端的nginx服务:

为AKS群集配置网络策略

此时,如果没有匹配标签的Pod是不可以访问后端Nginx的:

为AKS群集配置网络策略

仅允许来自特定命名空间的流量

前面的演示中,我们配置了后端Nginx服务允许特定标签的Pod流量。还有一个常见的需求是,将流量限制在特定的命名空间内

在前面的示例中,我们已创建拒绝所有流量的网络策略,然后更新了该策略,以允许来自具有特定标签的 Pod 的流量。 另一个常见需求是将流量限制在给定的命名空间内。 如果前面的示例适用于 dev 命名空间中的流量,那么就需要创建一个网络策略用于阻止来自另一命名空间(例如 production)的流量访问 Pod。

接下来让我们先更新之前定义的网络策略, 在Ingress规则namespaceSelector下,配置仅允许来自dev命名空内部的网络流量:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: backend-policy
namespace: dev
spec:
podSelector:
matchLabels:
app: webapp
role: backend
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: dev
podSelector:
matchLabels:
app: webapp
role: frontend

配置好以后,运行kubectl apply来应用策略:

为AKS群集配置网络策略

策略应用以后,我们可以在默认命名空间中启动一个Pod来测试是否可以访问dev命名空间中后端Nginx服务,可以看到,来自默认命名空间中的流量以及被拒绝:

为AKS群集配置网络策略

接下来让我们在dev命名空间中启动一个Pod来测试访问后端Nginx服务,可以看到dev命名空间中的pod可以访问后端nginx服务:

为AKS群集配置网络策略