在 AKS 中使用网络策略保护 Pod 之间的流量
在 Kubernetes 中运行最新的基于微服务的应用程序时,通常想要控制哪些组件可以相互通信。 应将最小特权原则应用于在 Azure Kubernetes 服务 (AKS) 群集中的 Pod 之间流动的流量。 假设你想要阻止直接流向后端应用程序的流量。 在 Kubernetes 中,使用网络策略功能可在群集中定义用于 Pod 之间的入口和出口流量的规则。
本文介绍如何安装网络策略引擎并创建 Kubernetes 网络策略,来控制 AKS 中各 Pod 之间的流量流。 网络策略可用于 AKS 中基于 Linux 或基于 Windows 的节点和 Pod。
开始之前
需要安装并配置 Azure CLI 2.0.61 或更高版本。 运行 az --version
即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。
卸载 Azure 网络策略管理器或 Calico(预览版)
要求:
- aks-preview Azure CLI 扩展版本 0.5.166 或更高版本。 请参阅安装 aks-preview Azure CLI 扩展。
- Azure CLI 2.54 或更高版本
- AKS REST API 版本 2023-08-02-preview 或更高版本
注意:
- 卸载过程不会删除 Calico 使用的自定义资源定义 (CRD) 和自定义资源 (CR)。 这些 CRD 和 CR 的名称以“projectcalico.org”或“tigera.io”结尾。 成功卸载 Calico 后,可以手动删除这些 CRD 和关联的 CR(在删除 Calico 之前删除 CRD 会中断群集)。
- 升级将不会删除群集中的任何 NetworkPolicy 资源,但在卸载后,这些策略不再强制执行。
警告
升级过程将触发每个节点池同时重新映像。 不支持单独升级每个节点池。 群集网络的任何中断会类似于节点映像升级或 Kubernetes 版本升级,其中节点池中的每个节点会重新映像。
若要从群集中删除 Azure 网络策略管理器或 Calico,请运行以下命令:
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy none
网络策略概述
默认情况下,AKS 群集中的所有 Pod 可以无限制地发送和接收流量。 为了提高安全性,可定义用来控制流量流的规则。 例如,后端应用程序通常只向所需的前端服务公开。 或者,数据库组件只能由连接到它们的应用层访问。
网络策略是一种 Kubernetes 规范,用于为 Pod 之间的通信定义访问策略。 使用网络策略时,可以定义一组有序的规则来发送和接收流量。 将规则应用于与一个或多个标签选择器匹配的 Pod 集合。
这些网络策略规则定义为 YAML 清单。 可以包含网络策略作为也会创建部署或服务的更丰富清单的一部分。
AKS 中的网络策略选项
Azure 提供了三个用于强制执行网络策略的网络策略引擎:
- Cilium,用于使用由 Cilium 提供支持的 Azure CNI 的 AKS 群集。
- Azure 网络策略管理器。
- Calico,一种由 Tigera 构建的开源网络和网络安全解决方案。
Cilium 是我们推荐的网络策略引擎。 Cilium 使用 Linux Berkeley 数据包筛选器 (BPF) 对流量强制执行网络策略,这通常比“IPTables”更有效。 有关详细信息,请参阅由 Cilium 提供支持的 Azure CNI 文档。
为了强制实施指定的策略,适用于 Linux 的 Azure 网络策略管理器会使用 Linux IPTables。 适用于 Windows 的 Azure 网络策略管理器使用主机网络服务 (HNS) ACLPolicies。 策略将转换为一系列允许和禁止的 IP 对。 然后,这些对作为 IPTable
或 HNS ACLPolicy
筛选规则进行编程。
网络策略引擎之间的差异:Cilium、Azure NPM 和 Calico
功能 | Azure 网络策略管理器 | Calico | Cilium |
---|---|---|---|
支持的平台 | Linux、Windows Server 2022 | Linux、Windows Server 2019 和 2022 | |
支持的网络选项 | Azure 容器网络接口 (CNI)。 | Azure CNI(Linux、Windows Server 2019 和 2022)和 kubenet (Linux)。 | Azure CNI。 |
符合 Kubernetes 规范 | 支持的所有策略类型 | 支持所有策略类型。 | 支持所有策略类型。 |
其他功能 | 无。 | 扩展的策略模型,包括全局网络策略、全局网络集和主机终结点。 有关使用 calicoctl CLI 管理这些扩展功能的详细信息,请参阅 calicoctl 用户参考。 |
无。 |
支持 | 受 Azure 支持和工程团队支持。 | 受 Azure 支持和工程团队支持。 | 受 Azure 支持和工程团队支持。 |
限制
Azure 网络策略管理器不支持 IPv6。 否则,Azure 网络策略管理器完全支持 Linux 中的网络策略规范。
在 Windows 中,Azure 网络策略管理器不支持:
- 命名端口。
- 流式传输控制传输协议 (SCTP)。
- 否定匹配标签或命名空间选择器(例如,除
debug=true
之外的所有标签)。 except
无类别域际路由选择 (CIDR) 块(具有异常的 CIDR)。
注意
如果创建了不受支持的策略,Azure 网络策略管理器 Pod 日志会记录错误。
缩放
对于适用于 Linux 的 Azure 网络策略管理器,我们不允许缩放超过 250 个节点和 20,000 个 Pod。 如果尝试缩放超出这些限制,可能会遇到“内存不足”(OOM) 错误。 若要提高内存限制,请创建支持票证。
创建 AKS 群集并启用网络策略
若要查看实际的网络策略,请创建支持网络策略的 AKS 群集,然后处理添加策略。
若要使用 Azure 网络策略管理器,必须使用 Azure CNI 插件。 Calico 既可与 Azure CNI 插件一起使用,也可与 Kubenet CNI 插件一起使用。
以下示例脚本使用系统分配的标识创建 AKS 群集,并使用 Azure 网络策略管理器启用网络策略。
[!Note} Calico 可与
--network-plugin azure
或--network-plugin kubenet
参数配合使用。
也可以使用用户分配的标识,而不是系统分配的标识。 有关详细信息,请参阅使用托管标识。
创建启用了 Azure 网络策略管理器的 AKS 群集 - 仅限 Linux
在本部分中,你将创建启用了 Linux 节点池和 Azure 网络策略管理器的群集。
开始时,请替换变量 $RESOURCE_GROUP_NAME
和 $CLUSTER_NAME
变量的值。
$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$LOCATION=canadaeast
创建 AKS 群集并为 network-plugin
和 network-policy
指定 azure
。
若要创建群集,请使用以下命令:
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--network-plugin azure \
--network-policy azure
创建启用了 Azure 网络策略管理器的 AKS 群集 - Windows Server 2022(预览版)
在本部分中,你将创建启用了 Windows 节点池和 Azure 网络策略管理器的群集。
注意
带 Windows 节点的 Azure 网络策略管理器仅在 Windows Server 2022 上可用。
安装 aks-preview Azure CLI 扩展
重要
AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
要安装aks-preview
扩展,请运行以下命令:
az extension add --name aks-preview
运行以下命令,以更新到已发布的最新扩展版本:
az extension update --name aks-preview
注册 WindowsNetworkPolicyPreview 功能标志
使用 WindowsNetworkPolicyPreview
命令注册 WindowsNetworkPolicyPreview
功能标志,如以下示例所示:
az feature register --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
状态显示为“已注册”需要几分钟时间。 使用 az feature show 命令验证注册状态:
az feature show --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
当状态反映“已注册”时,使用 az provider register 命令来刷新 Microsoft.ContainerService
资源提供程序的注册:
az provider register --namespace Microsoft.ContainerService
创建 AKS 群集
现在,替换变量 $RESOURCE_GROUP_NAME
、$CLUSTER_NAME
和 $WINDOWS_USERNAME
变量的值。
$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$WINDOWS_USERNAME=myWindowsUserName
$LOCATION=canadaeast
创建一个用户名,用作群集上 Windows Server 容器的管理员凭据。 以下命令提示输入用户名。 将其设置为 $WINDOWS_USERNAME
。 请记住,本文中的命令是输入到 Bash shell 中的。
echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
若要创建群集,请使用以下命令:
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--windows-admin-username $WINDOWS_USERNAME \
--network-plugin azure \
--network-policy azure
创建群集需要几分钟时间。 默认情况下,仅使用 Linux 节点池创建群集。 如果想要使用 Windows 节点池,可以进行添加。 下面是一个示例:
az aks nodepool add \
--resource-group $RESOURCE_GROUP_NAME \
--cluster-name $CLUSTER_NAME \
--os-type Windows \
--name npwin \
--node-count 1
创建已启用 Calico 的 AKS 群集
创建 AKS 群集并指定 --network-plugin azure
和 --network-policy calico
。 指定 --network-policy calico
可在 Linux 和 Windows 节点池上启用 Calico。
如果计划将 Windows 节点池添加到群集,请包括满足 Windows Server 密码要求的参数 windows-admin-username
和 windows-admin-password
。
重要
目前,在使用 Calico 3.17.2 的 Kubernetes 1.20 或更高版本的新集群上可以使用具备 Windows 节点的 Calico 网络策略,并且需要使用 Azure CNI 网络。 启用 Calico 的 AKS 群集上的 Windows 节点还默认启用 直接服务器返回 (DSR)。
对于使用早期版本 Calico 的只用 Linux 节点池运行 Kubernetes 1.20 的群集,Calico 版本将自动升级到 3.17.2。
创建一个用户名,用作群集上 Windows Server 容器的管理员凭据。 以下命令提示输入用户名。 将其设置为 $WINDOWS_USERNAME
。 请记住,本文中的命令是输入到 Bash shell 中的。
echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--windows-admin-username $WINDOWS_USERNAME \
--network-plugin azure \
--network-policy calico
创建群集需要几分钟时间。 默认情况下,仅使用 Linux 节点池创建群集。 如果想要使用 Windows 节点池,可以进行添加。 例如:
az aks nodepool add \
--resource-group $RESOURCE_GROUP_NAME \
--cluster-name $CLUSTER_NAME \
--os-type Windows \
--name npwin \
--node-count 1
在现有群集中安装 Azure 网络策略管理器或 Calico
此外,还支持在现有 AKS 群集上安装 Azure 网络策略管理器或 Calico。
警告
升级过程将触发每个节点池同时重新映像。 不支持单独升级每个节点池。 群集网络的任何中断会类似于节点映像升级或 Kubernetes 版本升级,其中节点池中的每个节点会重新映像。
安装 Azure 网络策略管理器的示例命令:
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy azure
安装 Calico 的示例命令:
警告
此警告适用于将已启用 Calico 的 Kubenet 群集升级到已启用 Calico 的 Azure CNI 覆盖的情况。
- 在已启用 Calico 的 Kubenet 群集中,Calico 用作 CNI 和网络策略引擎。
- 在 Azure CNI 群集中,Calico 仅用于网络策略强制执行,而不用作 CNI。 这可能会导致 Pod 启动和 Calico 允许来自 Pod 的出站流量之间出现短暂的延迟。
建议使用 Cilium 而不是 Calico 来避免此问题。 在由 Cilium 提供支持的 Azure CNI 中了解详细信息
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy calico
将已安装 Azure NPM 或 Calico 的现有群集升级到由 Cilium 提供支持的 Azure CNI
若要将已安装网络策略引擎的现有群集升级到由 Cilium 提供支持的 Azure CNI,请参阅将现有群集升级到由 Cilium 提供支持的 Azure CNI
验证网络策略设置
群集准备就绪后,使用 az aks get-credentials 命令将 kubectl
配置为连接到 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据:
az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME
若要开始验证网络策略,请创建示例应用程序并设置流量规则。
首先,创建名为 demo
的命名空间以运行示例 Pod:
kubectl create namespace demo
现在,在群集中创建名为 client
和 server
的两个 Pod。
注意
如果想在特定节点上计划客户端或服务器,请在 Pod 创建 kubectl run 命令中的 --command
参数之前添加以下位:
--overrides='{"spec": { "nodeSelector": {"kubernetes.io/os": "linux|windows"}}}'
创建 server
Pod。 此 Pod 在 TCP 端口 80 上提供服务:
kubectl run server -n demo --image=k8sgcr.azk8s.cn/e2e-test-images/agnhost:2.33 --labels="app=server" --port=80 --command -- /agnhost serve-hostname --tcp --http=false --port "80"
创建 client
Pod。 以下命令在 client
Pod 上运行 Bash:
kubectl run -it client -n demo --image=k8sgcr.azk8s.cn/e2e-test-images/agnhost:2.33 --command -- bash
现在,在一个单独的窗口中,运行以下命令来获取服务器 IP:
kubectl get pod --output=wide -n demo
输出应如下所示:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
server 1/1 Running 0 30s 10.224.0.72 akswin22000001 <none> <none>
在没有网络策略的情况下测试连接
在客户端的 shell 中,运行以下命令来验证与服务器的连接。 使用在运行上一个命令的输出中找到的 IP 来替换 server-ip
。 如果连接成功,则无任何输出。
/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp
使用网络策略测试连接
若要添加网络策略,请创建名为 demo-policy.yaml
的文件并粘贴以下 YAML 清单:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: demo-policy
namespace: demo
spec:
podSelector:
matchLabels:
app: server
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- port: 80
protocol: TCP
指定 YAML 清单的名称并使用 kubectl apply 应用该名称:
kubectl apply �f demo-policy.yaml
现在,在客户端的 shell 中,通过运行以下 /agnhost
命令来验证与服务器的连接:
/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp
由于服务器标记为 app=server
,但客户端未标记,因此与流量的连接将被阻止。 上面的连接命令将生成以下输出:
TIMEOUT
运行以下命令来标记 client
并验证与服务器的连接。 输出应不返回任何内容。
kubectl label pod client -n demo app=client
清理资源
在本文中,你创建了一个命名空间和两个 Pod,并应用了网络策略。 若要清理这些资源,请使用 kubectl delete 命令并指定资源名称:
kubectl delete namespace demo
后续步骤
有关网络资源的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 中应用程序的网络概念。
若要详细了解策略,请参阅 Kubernetes 网络策略。