本教程演示了如何使用集群网络政策来控制哪些 Pod 可接收传入的网络流量,以及哪些 Pod 可发送传出流量。如需了解详情,请参阅创建集群网络政策。
您可使用网络政策来限制 Pod 之间的连接。因此,使用网络政策可缩小入侵范围,提供更好的安全性。
请注意,网络政策决定是否允许连接,但不提供授权或安全传输(如 SSL/TLS)等更高级别的功能。
创建已启用网络政策实施功能的 GKE 集群
如需创建强制执行网络政策的容器集群,请运行以下命令:
gcloud container clusters create test --enable-network-policy
限制传入 Pod 的流量
通过 Kubernetes NetworkPolicy
资源,您可以为 Pod 配置网络访问政策。NetworkPolicy
对象包含以下信息:
应用网络政策的 Pod,通常由标签选择器指定
受网络政策影响的流量类型:表示传入流量的 Ingress 和/或表示传出流量的 Egress
哪些 Pod 可以连接指定的 Pod(对于入站流量政策)
出站流量政策规定指定的 Pod 可以连接哪些 Pod
首先,运行带有标签 app=hello
的 Web 服务器应用,并在集群内部将其公开:
kubectl run hello-web --labels app=hello \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
接下来,配置 NetworkPolicy
以仅允许来自 app=foo
Pod 的流量传入 hello-web
Pod。来自未带此标签的 Pod 的其他传入流量、外部流量和来自其他命名空间中的 Pod 的流量均会被阻止。
以下清单选择带有标签 app=hello
的 Pod,并指定入站流量政策,以仅允许来自带有标签 app=foo
的 Pod 的流量:
要将此政策应用于集群,请运行以下命令:
kubectl apply -f hello-allow-from-foo.yaml
验证入站流量政策
首先,运行带有标签 app=foo
的临时 Pod,并获取 Pod 中的 shell:
kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t test-1
向 hello-web:8080
端点发出请求,验证是否允许该传入流量:
/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world! Version: 1.0.0 Hostname: hello-web-2258067535-vbx6z / # exit
从 Pod app=foo
到 app=hello
Pod 的流量传输已启用。
接下来,运行带有不同标签 (app=other
) 的临时 Pod,并在 Pod 中获取 shell:
kubectl run -l app=other --image=alpine --restart=Never --rm -i -t test-1
发出相同的请求,观察到流量不被允许,因此请求超时;然后退出 Pod shell:
/ # wget -qO- --timeout=2 http://hello-web:8080
wget: download timed out / # exit
限制传出 Pod 的流量
您可以像限制传入流量一样限制传出流量。
但是,为了能够查询内部主机名(如 hello-web
)或外部主机名(如 www.example.com
),您必须在出站流量网络政策中允许 DNS(域名系统)解析。DNS 流量使用 TCP 和 UDP 协议在端口 53 上产生。
若要启用出站网络政策,请部署 NetworkPolicy
以控制从带有标签 app=foo
的 Pod 传出的流量,同时仅允许该流量传入带有标签 app=hello
的 Pod 并允许 DNS 流量。
以下清单指定了一个网络政策,对从带有标签 app=foo
的 Pod 传出的出站流量进行控制,仅允许该流量传入下面两个目标位置:
- 同一命名空间中带有
app=hello
标签的 Pod。 - 端口 53 上的集群 Pod 或外部端点(UDP 和 TCP)。
要将此政策应用于集群,请运行以下命令:
kubectl apply -f foo-allow-to-hello.yaml
验证出站流量政策
首先,部署名为 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
接下来,运行带有标签 app=foo
的临时 Pod,并在容器中打开 shell:
kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never test-3
验证 Pod 可以与 hello-web:8080
建立连接:
/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world!
Version: 1.0.0
Hostname: hello-web-2258067535-vbx6z
验证 Pod 无法与 hello-web-2:8080
建立连接:
/ # wget -qO- --timeout=2 http://hello-web-2:8080
wget: download timed out
验证 Pod 无法与外部网站(如 www.example.com
)建立连接,并退出 Pod shell。
/ # wget -qO- --timeout=2 http://www.example.com
wget: download timed out
/ # exit