

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 为混合节点配置 Kubernetes 网络策略
<a name="hybrid-nodes-network-policies"></a>

 如果将 Cilium 用作 EKS 混合节点的 CNI，则 AWS 支持通过 Kubernetes 网络策略（第 3 层/第 4 层）来控制容器组（pod）的入口和出口流量。如果运行的 EKS 集群包含 AWS 云中的节点，则 AWS 支持[使用 Amazon VPC CNI 来实现 Kubernetes 网络策略](cni-network-policy.md)。

本主题介绍如何通过 EKS 混合节点配置 Cilium 和 Kubernetes 网络策略。有关 Kubernetes 网络策略的详细信息，请参阅 Kubernetes 文档中的 [Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)。

## 配置网络策略
<a name="hybrid-nodes-configure-network-policies"></a>

### 注意事项
<a name="_considerations"></a>
+  AWS 支持通过上游 Kubernetes 网络策略及其规范，控制容器组（pod）的入口和出口流量，但 AWS 目前不支持 `CiliumNetworkPolicy` 或 `CiliumClusterwideNetworkPolicy`。
+ `policyEnforcementMode` Helm 可用于控制 Cilium 的默认策略执行行为。默认行为允许所有出口和入口流量。如果一个端点被某个网络策略选中，则会转换为默认拒绝状态，仅允许明确允许的流量。有关[默认策略模式](https://docs.cilium.io/en/stable/security/policy/intro/#policy-mode-default)和[策略执行模式](https://docs.cilium.io/en/stable/security/policy/intro/#policy-enforcement-modes)的更多信息，请参阅 Cilium 文档。
+ 如果要为现有的 Cilium 安装更改 `policyEnforcementMode`，则必须重启 Cilium 代理 DaemonSet，这样才能应用新的策略执行模式。
+ 使用 `namespaceSelector` 和 `podSelector` 以允许或拒绝进出带有匹配标签的命名空间和容器组（pod）的流量。`namespaceSelector` 和 `podSelector` 可与 `matchLabels` 或 `matchExpressions` 结合使用，以根据标签选择命名空间和容器组（pod）。
+ 使用 `ingress.ports` 和 `egress.ports` 以允许或拒绝进出端口和协议的流量。
+ `ipBlock` 字段不能用于选择性地允许或拒绝进出容器组（pod）IP 地址的流量（[\$19209](https://github.com/cilium/cilium/issues/9209)）。对节点 IP 使用 `ipBlock` 选择器是 Cilium 中的一项测试功能，不受 AWS 支持。
+ 有关 Kubernetes 网络策略可用字段的信息，请参阅 Kubernetes 文档中的 [NetworkPolicy resource](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)。

### 先决条件
<a name="_prerequisites"></a>
+ 按照[为混合节点配置 CNI](hybrid-nodes-cni.md)中的说明安装 Cilium。
+ 在命令行环境中安装 Helm，请参阅[安装 Helm 说明](helm.md)。

### 过程
<a name="_procedure"></a>

以下过程为示例微服务应用程序设置了网络策略，使得各个组件只能与应用程序正常运行所需的其他组件通信。该过程使用 [Istio Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) 示例微服务应用程序。

Bookinfo 应用程序由四项独立的微服务组成，它们具有以下关系：
+  **productpage**。productpage 微服务会调用 details 和 reviews 微服务来填充页面。
+  **details**。details 微服务包含包含书籍信息。
+  **reviews**。reviews 微服务包含书评，还会调用 ratings 微服务。
+  **ratings**。ratings 微服务包含随书评附带的书籍排名信息。

  1. 创建示例应用程序。

     ```
     kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
     ```

  1. 确认应用程序成功运行，并记下 productpage 微服务的容器组（pod）IP 地址。您将在后续步骤中使用此容器组（pod）IP 地址查询每项微服务。

     ```
     kubectl get pods -o wide
     ```

     ```
     NAME                              READY   STATUS    RESTARTS   AGE   IP            NODE
     details-v1-766844796b-9wff2       1/1     Running   0          7s    10.86.3.7     mi-0daa253999fe92daa
     productpage-v1-54bb874995-lwfgg   1/1     Running   0          7s    10.86.2.193   mi-082f73826a163626e
     ratings-v1-5dc79b6bcd-59njm       1/1     Running   0          7s    10.86.2.232   mi-082f73826a163626e
     reviews-v1-598b896c9d-p2289       1/1     Running   0          7s    10.86.2.47    mi-026d6a261e355fba7
     reviews-v2-556d6457d-djktc        1/1     Running   0          7s    10.86.3.58    mi-0daa253999fe92daa
     reviews-v3-564544b4d6-g8hh4       1/1     Running   0          7s    10.86.2.69    mi-09183e8a3d755abf6
     ```

  1. 创建一个容器组（pod），用于全程测试网络策略。请注意，该容器组（pod）是在 `default` 命名空间中创建，带有 `access: true` 标签。

     ```
     kubectl run curl-pod --image=curlimages/curl -i --tty --labels=access=true --namespace=default --overrides='{"spec": { "nodeSelector": {"eks.amazonaws.com/compute-type": "hybrid"}}}' -- /bin/sh
     ```

  1. 测试对 productpage 微服务的访问权限。在以下示例中，我们使用 productpage 容器组（pod）的容器组（pod）IP 地址 (`10.86.2.193`) 查询该微服务。请将其替换为环境中 productpage 容器组（pod）的容器组（pod）IP 地址。

     ```
     curl -s http://10.86.2.193:9080/productpage | grep -o "<title>.*</title>"
     ```

     ```
     <title>Simple Bookstore App</title>
     ```

  1. 您可以通过输入 `exit` 来退出测试 curl 容器组（pod），也可以通过运行以下命令重新附加到该容器组（pod）。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

  1. 为演示后续步骤中网络策略的效果，我们首先创建了一个拒绝所有流向 BookInfo 微服务之流量的网络策略。创建一个名为 `network-policy-deny-bookinfo.yaml` 的文件，用于定义拒绝网络策略。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: deny-bookinfo
       namespace: default
     spec:
       podSelector:
         matchExpressions:
         - key: app
           operator: In
           values: ["productpage", "details", "reviews", "ratings"]
       policyTypes:
       - Ingress
       - Egress
     ```

  1. 将拒绝网络策略应用于集群。

     ```
     kubectl apply -f network-policy-default-deny-bookinfo.yaml
     ```

  1. 测试对 BookInfo 应用程序的访问权限。在以下示例中，我们使用 productpage 容器组（pod）的容器组（pod）IP 地址 (`10.86.2.193`) 查询该微服务。请将其替换为环境中 productpage 容器组（pod）的容器组（pod）IP 地址。

     ```
     curl http://10.86.2.193:9080/productpage --max-time 10
     ```

     ```
     curl: (28) Connection timed out after 10001 milliseconds
     ```

  1. 创建一个名为 `network-policy-productpage.yaml` 的文件，用于定义 productpage 网络策略。该策略具有以下规则：
     + 允许来自带有 `access: true` 标签的容器组（pod）[即上一步中创建的 curl 容器组（pod）] 的入口流量
     + 允许端口 `9080` 上的出口 TCP 流量流向 details、reviews 和 ratings 微服务
     + 允许端口 `53` 上的出口 TCP/UDP 流量流向在 `kube-system` 命名空间中运行的 CoreDNS

       ```
       apiVersion: networking.k8s.io/v1
       kind: NetworkPolicy
       metadata:
         name: productpage-policy
         namespace: default
       spec:
         podSelector:
           matchLabels:
             app: productpage
         policyTypes:
         - Ingress
         - Egress
         ingress:
         - from:
           - podSelector:
               matchLabels:
                 access: "true"
         egress:
         - to:
           - podSelector:
               matchExpressions:
               - key: app
                 operator: In
                 values: ["details", "reviews", "ratings"]
           ports:
           - port: 9080
             protocol: TCP
         - to:
           - namespaceSelector:
               matchLabels:
                 kubernetes.io/metadata.name: kube-system
             podSelector:
               matchLabels:
                 k8s-app: kube-dns
           ports:
           - port: 53
             protocol: UDP
           - port: 53
             protocol: TCP
       ```

  1. 将 productpage 网络策略应用于集群。

     ```
     kubectl apply -f network-policy-productpage.yaml
     ```

  1. 连接到 curl 容器组（pod）并测试对 Bookinfo 应用程序的访问权限。现在允许访问 productpage 微服务，但其他微服务仍被拒绝，因为它们仍然受到拒绝网络策略的约束。在以下示例中，我们使用 productpage 容器组（pod）的容器组（pod）IP 地址 (`10.86.2.193`) 查询该微服务。请将其替换为环境中 productpage 容器组（pod）的容器组（pod）IP 地址。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

     ```
     curl -s http://10.86.2.193:9080/productpage | grep -o "<title>.*</title>"
     <title>Simple Bookstore App</title>
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1
     {"error": "Sorry, product details are currently unavailable for this book."}
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/reviews
     {"error": "Sorry, product reviews are currently unavailable for this book."}
     ```

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/ratings
     {"error": "Sorry, product ratings are currently unavailable for this book."}
     ```

  1. 创建一个名为 `network-policy-details.yaml` 的文件，用于定义 details 网络策略。该策略仅允许来自 productpage 微服务的入口流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: details-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: details
       policyTypes:
       - Ingress
       ingress:
       - from:
         - podSelector:
             matchLabels:
               app: productpage
     ```

  1. 创建一个名为 `network-policy-reviews.yaml` 的文件，用于定义 reviews 网络策略。该策略仅允许来自 productpage 微服务的入口流量，并且仅允许流向 ratings 微服务和 CoreDNS 的出口流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: reviews-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: reviews
       policyTypes:
       - Ingress
       - Egress
       ingress:
       - from:
         - podSelector:
             matchLabels:
               app: productpage
       egress:
       - to:
         - podSelector:
             matchLabels:
               app: ratings
       - to:
         - namespaceSelector:
             matchLabels:
               kubernetes.io/metadata.name: kube-system
           podSelector:
             matchLabels:
               k8s-app: kube-dns
         ports:
         - port: 53
           protocol: UDP
         - port: 53
           protocol: TCP
     ```

  1. 创建一个名为 `network-policy-ratings.yaml` 的文件，用于定义 ratings 网络策略。该策略仅允许来自 productpage 和 reviews 微服务的入口流量。

     ```
     apiVersion: networking.k8s.io/v1
     kind: NetworkPolicy
     metadata:
       name: ratings-policy
       namespace: default
     spec:
       podSelector:
         matchLabels:
           app: ratings
       policyTypes:
       - Ingress
       ingress:
       - from:
         - podSelector:
             matchExpressions:
             - key: app
               operator: In
               values: ["productpage", "reviews"]
     ```

  1. 将 details、reviews 和 ratings 网络策略应用于集群。

     ```
     kubectl apply -f network-policy-details.yaml
     kubectl apply -f network-policy-reviews.yaml
     kubectl apply -f network-policy-ratings.yaml
     ```

  1. 连接到 curl 容器组（pod）并测试对 Bookinfo 应用程序的访问权限。在以下示例中，我们使用 productpage 容器组（pod）的容器组（pod）IP 地址 (`10.86.2.193`) 查询该微服务。请将其替换为环境中 productpage 容器组（pod）的容器组（pod）IP 地址。

     ```
     kubectl attach curl-pod -c curl-pod -i -t
     ```

     测试 details 微服务。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1
     ```

     ```
     {"id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890"}
     ```

     测试 reviews 微服务。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/reviews
     ```

     ```
     {"id": "1", "podname": "reviews-v1-598b896c9d-p2289", "clustername": "null", "reviews": [{"reviewer": "Reviewer1", "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"}, {"reviewer": "Reviewer2", "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]}
     ```

     测试 ratings 微服务。

     ```
     curl -s http://10.86.2.193:9080/api/v1/products/1/ratings
     ```

     ```
     {"id": 1, "ratings": {"Reviewer1": 5, "Reviewer2": 4}}
     ```

  1. 清理您在此过程中创建的资源。

     ```
     kubectl delete -f network-policy-deny-bookinfo.yaml
     kubectl delete -f network-policy-productpage.yaml
     kubectl delete -f network-policy-details.yaml
     kubectl delete -f network-policy-reviews.yaml
     kubectl delete -f network-policy-ratings.yaml
     kubectl delete -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
     kubectl delete pod curl-pod
     ```