在 Azure Stack HCI 和 Windows Server 上的 Azure Kubernetes 服务中使用网络策略保护 Pod 之间的流量

使用此分步指南验证和试用基本的 pod 到 pod 连接,并在群集中使用 Calico 网络策略。 在本指南中,你将了解如何执行以下操作:在 Linux 和 Windows 节点上创建客户端 Pod 和服务器 Pod,验证 Pod 之间的连接性,以及应用基本网络策略隔离 Pod 流量。

必备条件

若要在 Azure Stack HCI 和 Windows Server 上部署 Azure Kubernetes 服务 (AKS),请按照在 Azure Stack HCI 和 Windows Server 上安装 AKS 的步骤操作。

要使用本指南,你将需要:

  • Azure Stack HCI 和 Windows Server 上的 AKS 工作负载群集。
  • 在群集中部署至少一个 Windows 工作器节点。
  • 在群集中部署至少一个 Linux 工作器节点。
  • 在创建工作负载群集时启用 Calico 网络插件。 如果未启用此插件,请参阅 New-AksHciCluster 了解相关说明。

在 Linux 节点上创建 Pod

首先在 Linux 节点上创建客户端 Pod“busybox”和服务器 Pod“nginx” 。

创建名为 policy-demo-linux.yaml 的 YAML 文件


apiVersion: v1
kind: Namespace
metadata:
  name: calico-demo

---

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox
  name: busybox
  namespace: calico-demo
spec:
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 360000
    image: busybox:1.28
    imagePullPolicy: Always
    name: busybox
  nodeSelector:
    beta.kubernetes.io/os: linux

---

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: calico-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.8
    ports:
    - containerPort: 80
  nodeSelector:
    beta.kubernetes.io/os: linux

将 policy-demo-linux.yaml 文件应用到 Kubernetes 群集

打开 PowerShell 窗口,并使用 Get-AksHciCredential 命令加载目标群集的凭据。

接下来使用 kubectl 应用 policy-demo-linux.yaml 配置,如下所示:

kubectl apply -f policy-demo-linux.yaml

在 Window 节点上创建 Pod

在 Windows 节点上创建客户端 Pod“pwsh”和服务器 Pod“porter” 。

注意

Pod 的清单使用基于 mcr.microsoft.com/windows/servercore:1809 的映像。 如果使用的是最新的 Windows Server 版本,请更新清单,以使用与你的 Windows Server 版本相匹配的 Server Core 映像。

创建 policy-demo-windows.yaml


apiVersion: v1
kind: Pod
metadata:
  name: pwsh
  namespace: calico-demo
  labels:
    app: pwsh
spec:
  containers:
  - name: pwsh
    image: mcr.microsoft.com/windows/servercore:1809
    args:
    - powershell.exe
    - -Command
    - "Start-Sleep 360000"
    imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows
---
apiVersion: v1
kind: Pod
metadata:
  name: porter
  namespace: calico-demo
  labels:
    app: porter
spec:
  containers:
  - name: porter
    image: calico/porter:1809
    ports:
    - containerPort: 80
    env:
    - name: SERVE_PORT_80
      value: This is a Calico for Windows demo.
    imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows

将 policy-demo-windows.yaml 文件应用到 Kubernetes 群集

打开 PowerShell 窗口,并使用 Get-AksHciCredential 命令加载目标群集的凭据。

接下来使用 kubectl 应用 policy-demo-windows.yaml 配置:

kubectl apply -f policy-demo-windows.yaml

验证这四个 Pod 已创建并且正在运行

注意

启动 Windows Pod 可能要花费一段时间,具体取决于你的网络下载速度。

打开 PowerShell 窗口,并使用 Get-AksHciCredential 命令加载目标群集的凭据。

接下来使用 kubectl 列出 calico-demo 命名空间中的 Pod:

kubectl get pods --namespace calico-demo

你应该会看到与以下内容相似的输出:

NAME      READY   STATUS              RESTARTS   AGE
busybox   1/1     Running             0          4m14s
nginx     1/1     Running             0          4m14s
porter    0/1     ContainerCreating   0          74s
pwsh      0/1     ContainerCreating   0          2m9s

每隔几分钟重复该命令,直到输出显示 4 个 Pod 都处于运行状态。

NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          7m24s
nginx     1/1     Running   0          7m24s
porter    1/1     Running   0          4m24s
pwsh      1/1     Running   0          5m19s

检查 Linux 和 Windows 节点上的 Pod 之间的连接性

现在客户端和服务器 Pod 既在 Linux 节点上运行,也在 Windows 节点上运行,请验证 Linux 节点上的客户端 Pod 是否可以访问 Windows 节点上的服务器 Pod。

  1. 打开 PowerShell 窗口,并使用 Get-AksHciCredential 命令加载目标群集的凭据。

  2. 使用 kubectl 确定 porter Pod 的 IP 地址:

    kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}'
    
  3. 登录到 Pod“busybox”,并在端口 80 上尝试访问 Pod“porter” 。 将“<porter_ip>”标记替换为上一命令返回的 IP 地址。

    kubectl exec --namespace calico-demo busybox -- nc -vz <porter_ip> 80
    

    还可以合并上述两个步骤:

    kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}') 80
    

    如果 Pod“busybox”与 Pod“porter”成功连接,你将获得如下所示的输出:

    192.168.40.166 (192.168.40.166:80) open
    

    注意

    返回的 IP 地址将根据环境设置而有所不同。

  4. 验证 Pod“pwsh”是否可以访问 Pod“nginx”:

    kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po nginx -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5
    

    如果成功连接,你将看到如下所示的输出:

    StatusCode        : 200
    StatusDescription : OK
    Content           : <!DOCTYPE html>
                        <html>
                        <head>
                        <title>Welcome to nginx!</title>
                        <style>
                            body {
                                width: 35em;
                                margin: 0 auto;
                                font-family: Tahoma, Verdana, Arial, sans-serif;
                            }
                        </style>
                        <...
    
  5. 验证 Pod“pwsh”是否可以访问 Pod“porter”:

    kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5
    

    如果成功,你将看到如下所示的内容:

    StatusCode        : 200
    StatusDescription : OK
    Content           : This is a Calico for Windows demo.
    RawContent        : HTTP/1.1 200 OK
                        Content-Length: 49
                        Content-Type: text/plain; charset=utf-8
                        Date: Fri, 21 Aug 2020 22:45:46 GMT
    
                        This is a Calico for Windows demo.
    Forms             :
    Headers           : {[Content-Length, 49], [Content-Type, text/plain;
                        charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}
    Images            : {}
    InputFields       : {}
    Links             : {}
    ParsedHtml        :
    RawContentLength  : 49
    
    

你已经验证了应用程序中的所有 Pod 之间可以进行通信。

将策略应用到 Windows 客户端 Pod

在实际部署中,你需要确保只有彼此可以通信的 Pod 允许执行此操作。

要实现此目的,请应用基本网络策略,该策略仅允许 Pod“busybox”访问 Pod“porter” 。

创建 network-policy.yaml 文件

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-busybox
  namespace: calico-demo
spec:
  podSelector:
    matchLabels:
      app: porter
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: busybox
    ports:
    - protocol: TCP
      port: 80

应用 network-policy.yaml 文件

  1. 打开 PowerShell 窗口。

  2. 使用 Get-AksHciCredential 命令加载目标群集的凭据。

  3. 使用 kubectl 应用 network-policy.yaml 文件。

    kubectl apply -f network-policy.yaml
    

验证策略是否有效

执行该策略后,Pod“busybox”仍应能够访问 Pod“porter” 。 如本主题前面所述,你可以在命令行中合并这些步骤:

kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80

但是 Pod“pwsh”将无法访问 Pod“porter”:

kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5

如果请求超时,会出现如下所示的消息:

Invoke-WebRequest : The operation has timed out.
At line:1 char:1
+ Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeout ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:Htt
pWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
command terminated with exit code 1

在此演示中,我们在 Linux 和 Windows 节点上配置了 Pod,验证了 Pod 之间的基本连接,并且试用了基本网络策略来隔离 Pod 之间的流量。 最后一步就是清理所有的演示资源:

kubectl delete namespace calico-demo

后续步骤

在本文中,你已了解如何使用网络策略来保护 Pod 之间的流量。 接下来可以: