在 Azure Kubernetes 服务 (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

网络策略概述

默认情况下,AKS 群集中的所有 Pod 可以无限制地发送和接收流量。 为了提高安全性,可定义用来控制流量流的规则。 例如,后端应用程序通常只向所需的前端服务公开。 或者,数据库组件只能由连接到它们的应用层访问。

网络策略是一种 Kubernetes 规范,其中针对 Pod 之间的通信定义了访问策略。 通过使用网络策略,可以定义一组有序的规则来发送和接收流量,并将其应用于与一个或多个标签选择器匹配的 Pod 集合。

这些网络策略规则定义为 YAML 清单。 可以包含网络策略作为也会创建部署或服务的更丰富清单的一部分。

AKS 中的网络策略选项

Azure 提供两种实现网络策略的方法。 创建 AKS 群集时,请选择“网络策略”选项。 创建群集后无法更改策略选项:

  • Azure 自身的实现,称为“Azure 网络策略管理器 (NPM)”。
  • Calico 网络策略 - 由 Tigera 建立的开源网络和网络安全解决方案。

Azure NPM for Linux 使用 Linux IPTables 来强制实施指定的策略,Azure NPM for Windows 使用“主机网络服务(HNS) ACLPolicies”来强制实施指定的策略。 策略将转换为一系列允许和禁止的 IP 对。 然后,这些 IP 对作为 IPTable/HNS ACLPolicy 筛选规则进行编程。

Azure NPM 和 Calico 网络策略及其功能之间的差异

功能 Azure NPM Calico 网络策略
支持的平台 Linux Linux
支持的网络选项 Azure CNI Azure CNI(Windows Server 2019 和 Linux)和 kubenet (Linux)
符合 Kubernetes 规范 支持的所有策略类型 支持的所有策略类型
其他功能 扩展的策略模型,包括全局网络策略、全局网络集和主机终结点。 有关使用 calicoctl CLI 管理这些扩展功能的详细信息,请参阅 calicoctl 用户参考
支持 由 Azure 支持部门和工程团队提供支持 由 Azure 社区提供支持。 有关其他付费支持的详细信息,请参阅 Project Calico 支持选项
日志记录 可通过 kubectl log -n kube-system 命令获得的日志 有关详细信息,请参阅 Calico 组件日志

的限制:

Azure 网络策略管理器 (NPM) 不支持 IPv6。 否则,Azure NPM 完全支持 Linux 中的网络策略规范。

  • 在 Windows 中,Azure NPM 不支持以下内容:
    • 命名端口
    • SCTP 协议
    • 否定匹配标签或命名空间选择器(例如,除“debug=true”之外的所有标签)
    • “except”CIDR 块(具有异常的 CIDR)

备注

  • 如果创建了不受支持的策略,Azure NPM Pod 日志将记录错误。

规模:

对 Azure NPM for Linux 设置当前限制后,它最多可以扩展到 500 个节点和 40k 个 Pod。 你可能会看到 OOM 终止超过此规模。 若要提高内存限制,请在 aks-can-github 上联系我们。

创建 AKS 群集并启用“网络策略”

若要查看实际的网络策略,请创建支持网络策略的 AKS 群集,然后处理添加策略。

重要

只能在创建群集时启用网络策略功能。 无法在现有 AKS 群集上启用网络策略。

若要使用 Azure NPM,必须使用 Azure CNI 插件。 Calico 网络策略可与此 Azure CNI 插件配合使用,也可与 Kubenet CNI 插件配合使用。

以下示例脚本:

  • 创建具有系统分配的标识的 AKS 群集并启用“网络策略”。
    • 使用“Azure NPM”选项。 若要改用 Calico 作为“网络策略”选项,请使用 --network-policy calico 参数。 注意:Calico 既可与 --network-plugin azure 一起使用,也可与 --network-plugin kubenet 一起使用。

也可以使用用户分配的标识,而不是系统分配的标识。 有关详细信息,请参阅使用托管标识

创建启用了 Azure NPM 的 AKS 群集 - 仅限 Linux

本部分将介绍如何创建启用了 Linux 节点池和 Azure NPM 的群集。

首先,应替换 $RESOURCE_GROUP_NAME 和 $CLUSTER_NAME 变量的值。

$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$LOCATION=chinaeast2

创建 AKS 群集并为 network-pluginnetwork-policy 指定 azure。

使用以下命令来创建群集:

az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-count 1 \
    --network-plugin azure \
    --network-policy azure

创建群集需要几分钟时间。 群集准备就绪后,使用 az aks get-credentials 命令将 kubectl 配置为连接到 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据:

az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME

为 Calico 网络策略创建 AKS 群集

创建 AKS 群集,并为网络插件指定 azure,为网络策略指定 calico。 使用 calico 作为网络策略可在 Linux 和 Windows 节点池上启用 Calico 网络。

如果计划将 Windows 节点池添加到群集,请包括参数 windows-admin-usernamewindows-admin-password ,以满足Windows Server 密码要求

重要

目前,在使用 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

验证“网络策略”设置

群集准备就绪后,使用 az aks get-credentials 命令将 kubectl 配置为连接到 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据:

az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME

若要开始验证“网络策略”,请先创建示例应用程序并设置流量规则。

首先,让我们创建一个名为演示的命名空间来运行示例 Pod:

kubectl create namespace demo

我们现在将在群集中创建两个名为“client”和“server”的 Pod。

注意

如果想在特定节点上计划客户端或服务器,请在 Pod 创建 kubectl run 命令中的 --command 参数之前添加以下位:

--overrides='{"spec": { "nodeSelector": {"kubernetes.io/os": "linux|windows"}}}'

创建服务器 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"

创建客户端 Pod。 以下命令将在客户端 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

输出应如下所示:

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 中,通过执行以下命令来验证与服务器的连接。 将 server-ip 替换为在执行上一个命令的输出中找到的 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

运行以下命令来标记客户端并验证与服务器的连接(输出不应返回任何内容)。

kubectl label pod client -n demo app=client

清理资源

在本文中,我们创建了一个命名空间和两个 Pod,并应用了网络策略。 若要清理这些资源,请使用 kubectl delete 命令并指定资源名称:

kubectl delete namespace demo

后续步骤

有关网络资源的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 中应用程序的网络概念

若要详细了解策略,请参阅 Kubernetes 网络策略