Kubernetes选择性出口:能否为集群外域名设置出口策略?
Great question! The short answer is yes, but it depends on which CNI plugin you're using with your Kubernetes cluster. Let me break this down clearly for you:
Native Kubernetes NetworkPolicy Limitation
Out of the box, Kubernetes' built-in NetworkPolicy resource doesn't support directly specifying domain names in egress rules—it only works with IP blocks, pod selectors, or namespace selectors. So the configuration example you proposed won't work with vanilla Kubernetes.
Solution: Use a CNI Plugin with Domain-Based Egress Control
Most popular CNI plugins (like Calico, Cilium, or Istio) extend Kubernetes network policies to support domain name filtering. Here's how you can achieve your goal with two common options:
Example 1: Calico NetworkPolicy
Calico lets you define egress rules with domainNames in both namespace-scoped NetworkPolicy and cluster-scoped GlobalNetworkPolicy resources.
First, set a default deny egress policy for your namespace:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress namespace: your-namespace spec: podSelector: {} policyTypes: - Egress
Then, create a policy to allow your app to access the external domains:
apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-app-egress-external namespace: your-namespace spec: selector: app == "your-app" egress: - action: Allow protocol: TCP destination: ports: - 443 domainNames: - "mydependency1.example.com" - "mydependency2.example.com" - action: Allow protocol: TCP destination: ports: - 80 domainNames: - "*.example.org" types: - Egress
Example 2: Cilium NetworkPolicy
Cilium supports domain-based egress rules using FQDN selectors. Here's a similar setup:
Default deny policy (same as native Kubernetes):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress namespace: your-namespace spec: podSelector: {} policyTypes: - Egress
Allow egress to specific domains:
apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: allow-app-egress-fqdn namespace: your-namespace spec: endpointSelector: matchLabels: app: your-app egress: - toFQDNs: - matchName: "mydependency1.example.com" - matchName: "mydependency2.example.com" toPorts: - ports: - port: "443" protocol: TCP - toFQDNs: - matchPattern: "*.example.org" toPorts: - ports: - port: "80" protocol: TCP
Key Notes
- Ensure your cluster uses a CNI plugin that supports domain-based egress (Calico, Cilium, Istio, etc.—vanilla kube-proxy/bridge won't work).
- Wildcard domains (
*.example.org) are supported by most of these plugins, but syntax might vary slightly—always check your plugin's official docs for exact pattern requirements. - Test your policies thoroughly to confirm they only allow the traffic you intend, while blocking all other outbound requests as expected.
内容的提问来源于stack exchange,提问作者user_mda

