本页面演示了如何使用集群网络政策来控制 Pod 能否接收传入(或 Ingress)网络流量,以及是否可以发送传出(或 Egress)流量。
您可使用网络政策来限制 pod 对象之间的连接,从而降低遭到攻击的风险。
网络政策充当 OSI 模型第 3 层或第 4 层的防火墙。它们不提供授权或加密等其他功能。
限制传入 Pod 对象的流量
借助 NetworkPolicy
对象,您可以为 Pod 配置网络访问政策。NetworkPolicy
对象包含以下信息:
政策适用的 pod 对象。您可以使用标签和选择器定义 pod 对象和工作负载。
受网络政策影响的流量类型:表示传入流量的 Ingress 和/或表示传出流量的 Egress。
Ingress 政策规定哪些 Pod 对象可以连接指定的 Pod 对象。
Egress 政策规定指定的 Pod 对象可以连接哪些 Pod 对象。
传入流量限制示例
本部分演示如何在示例应用中创建传入流量限制。您可以根据自己的应用环境修改此示例。
运行带有标签
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
配置
NetworkPolicy
以仅允许来自app=foo
pod 对象的流量传入hello-web
pod。GKE on AWS 会阻止来自没有此标签的 Pod 对象的流量,以及外部流量和来自其他命名空间中的 Pod 对象的流量。以下清单选择带有标签
app=hello
的 Pod 对象,并指定 Ingress 政策,以仅允许来自带有标签app=foo
的 Pod 对象的流量:将此政策应用于集群:
kubectl apply -f hello-allow-from-foo.yaml
验证 Ingress 政策
运行带有标签
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=foo
到app=hello
pod 对象的流量,则会看到类似于下面这样的输出内容:Hello, world! Version: 1.0.0 Hostname: hello-web-2258067535-vbx6z
运行带有不同标签 (
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 流量:
- 带有标签
app=hello
的同一命名空间中的 pod 对象。 - 端口 53 上的内部或外部端点(UDP 和 TCP)
将此政策应用于集群:
kubectl apply -f foo-allow-to-hello.yaml
验证 Egress 政策
部署名为
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,并验证 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
验证 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
验证 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
后续步骤
- Kubernetes 网络政策文档
- 使用网络政策日志记录功能记录集群网络政策允许或拒绝与 Pod 对象连接的时间。