配置网络政策

本页面演示了如何使用集群网络政策来控制 Pod 能否接收传入(或 Ingress)网络流量,以及是否可以发送传出(或 Egress)流量。

您可使用网络政策来限制 pod 对象之间的连接,从而降低遭到攻击的风险。

网络政策充当 OSI 模型第 3 层或第 4 层的防火墙。它们不提供授权或加密等其他功能。

限制传入 Pod 对象的流量

借助 NetworkPolicy 对象,您可以为 Pod 配置网络访问政策。NetworkPolicy 对象包含以下信息:

  • 政策适用的 pod 对象。您可以使用标签和选择器定义 pod 对象和工作负载。

  • 受网络政策影响的流量类型:表示传入流量的 Ingress 和/或表示传出流量的 Egress。

  • Ingress 政策规定哪些 Pod 对象可以连接指定的 Pod 对象。

  • Egress 政策规定指定的 Pod 对象可以连接哪些 Pod 对象。

传入流量限制示例

本部分演示如何在示例应用中创建传入流量限制。您可以根据自己的应用环境修改此示例。

  1. 运行带有标签 app=hello 的网络服务器应用,并在集群内部将其公开:

    kubectl run hello-web --labels app=hello \
        --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 \
        --port 8080 --expose
    
  2. 配置 NetworkPolicy 以仅允许来自 app=foo pod 对象的流量传入 hello-web pod。GKE on AWS 会阻止来自没有此标签的 Pod 对象的流量,以及外部流量和来自其他命名空间中的 Pod 对象的流量。

    以下清单选择带有标签 app=hello 的 Pod 对象,并指定 Ingress 政策,以仅允许来自带有标签 app=foo 的 Pod 对象的流量:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: hello-allow-from-foo
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: hello
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: foo
  3. 将此政策应用于集群:

    kubectl apply -f hello-allow-from-foo.yaml
    

验证 Ingress 政策

  1. 运行带有标签 app=foo 的临时 Pod。如需验证是否允许传入流量,请向 hello-web:8080 端点发出请求:

    kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t foo-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    如果启用从 pod app=fooapp=hello pod 对象的流量,则会看到类似于下面这样的输出内容:

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  2. 运行带有不同标签 (app=other) 的临时 Pod,并发出相同请求,以观察流量是否不被允许:

    kubectl run -l app=other --image=alpine --restart=Never --rm -i -t other-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    输出会确认连接未收到响应:

    wget: download timed out
    

限制从 Pod 对象传出的流量

您可以像限制传入流量一样限制传出流量。

但是,要查询内部主机名(如 hello-web)或外部主机名(如 www.example.com),您必须创建 Egress 政策,以允许端口 53 上使用 TCP 和 UDP 协议的 DNS 流量。

要启用 Egress 网络政策,请部署 NetworkPolicy 以控制从带有标签 app=foo 的 Pod 对象传出的流量,同时允许仅传入带有标签 app=hello 的 Pod 对象的流量,以及 DNS 流量。

以下清单指定 NetworkPolicy 控制来自带有标签 app=foo 并且具有两个允许的目标位置的 Pod 对象的 Egress 流量:

  1. 带有标签 app=hello 的同一命名空间中的 pod 对象。
  2. 端口 53 上的内部或外部端点(UDP 和 TCP)
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: foo-allow-to-hello
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: foo
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: hello
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP

将此政策应用于集群:

kubectl apply -f foo-allow-to-hello.yaml

验证 Egress 政策

  1. 部署名为 hello-web-2 的全新 Web 应用,并在集群内部公开该应用:

    kubectl run hello-web-2 --labels app=hello-2 \
      --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
    
  2. 运行带有标签 app=foo 的临时 pod,并验证 pod 是否可以与 hello-web:8080 建立连接:

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
      -- wget -qO- --timeout=2 http://hello-web:8080
    

    pod 会响应请求:

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  3. 验证 Pod 是否无法与 hello-web-2:8080 建立连接:

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://hello-web-2:8080
    

    输出会确认连接未收到响应:

    wget: download timed out
    
  4. 验证 Pod 是否无法与外部网站(如 www.example.com)建立连接。

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://www.example.com
    

    输出会确认连接未收到响应:

    wget: download timed out
    

清理

如需移除您在本教程中创建的资源,请运行以下命令:

kubectl delete pods --labels app=hello-2
kubectl delete pods --labels app=hello
kubectl delete -f foo-allow-to-hello.yaml
kubectl delete -f hello-allow-from-foo.yaml

后续步骤