You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过iptables限制Kubernetes Pod访问外部MySQL服务的源IP

Answers to Your Kubernetes & iptables Questions

Hey there, let's tackle your two questions step by step, considering your specific cluster setup (Kubernetes 1.13.4, Calico overlay network, ipvs-mode kube-proxy, only ClusterIP services):

1. Restricting Source IP for Pods Accessing External Services

When pods in your Calico-overlay cluster access external services, traffic typically gets SNAT'ed to the node's IP by default. To control/limit the source IP, you have two reliable approaches:

Calico lets you configure custom SNAT rules for outgoing traffic, which avoids conflicts with its own network management:

  • Fixed single source IP: If you want all external-bound pod traffic to use a single IP (like a dedicated egress gateway), create a GlobalNetworkPolicy that enforces SNAT to that IP. Example:
    apiVersion: projectcalico.org/v3
    kind: GlobalNetworkPolicy
    metadata:
      name: egress-snat-fixed-ip
    spec:
      selector: all()
      egress:
      - action: Allow
        destination:
          nets: ["0.0.0.0/0"] # All external destinations
        nat:
          outboundIP: "192.168.1.100" # Your fixed egress IP
    
  • Per-node SNAT with controlled IP pool: If you want to restrict to a pool of node IPs, configure Calico's felix settings to only use specific node IPs for SNAT. You can set this via the Calico ConfigMap:
    # Update calico-config ConfigMap
    data:
      felix-config: |
        {
          "snatOutgoing": true,
          "outgoingIPs": ["192.168.1.20", "192.168.1.21"] # Allowed node SNAT IPs
        }
    

Option 2: Node-level iptables Rules (Use with Caution)

Since Calico manages node iptables rules, you'll need to add your rules to a chain that Calico won't overwrite (like INPUT or FORWARD with higher priority):

  • For example, to SNAT all pod traffic from a specific namespace to a fixed IP:
    # Get the pod CIDR for your target namespace (or use pod IPs directly)
    POD_CIDR=$(kubectl get namespace my-app -o jsonpath='{.metadata.annotations.cni.projectcalico.org/ipv4pools}')
    # Add SNAT rule
    iptables -t nat -A POSTROUTING -s $POD_CIDR -d 0.0.0.0/0 -j SNAT --to-source 192.168.1.100
    
    Note: This needs to be applied to all nodes, and you'll need to maintain it if Calico resets iptables rules.

2. Restricting VM-hosted MySQL Access to Specific Pods via iptables

Your DBA's requirement is achievable, but you first need to fix a key routing issue: by default, pods accessing the external VM will have their source IP replaced with the node's IP (due to SNAT). To target individual pods, you need to make the pod's overlay IP visible to the VM. Here's how:

Step 1: Enable Direct Pod IP Routing to the VM

Calico uses BGP for network routing—you can add the VM (or its upstream router) as a BGP peer to your Calico cluster. This lets the VM directly route traffic to pod IPs, so pod traffic to the VM will retain its original pod IP as the source.

  • Edit your Calico BGP configuration to add the VM's IP as a peer:
    apiVersion: projectcalico.org/v3
    kind: BGPPeer
    metadata:
      name: vm-peer
    spec:
      peerIP: "10.0.0.50" # VM's IP address
      asNumber: 64512 # Use the same AS number as your Calico cluster (default is 64512)
    
  • Verify the VM can ping a pod IP to confirm routing works.

Step 2: Configure iptables Rules on the VM

Once the VM can see pod IPs, you can create strict iptables rules to allow only specific pods:

  1. First, set a default deny rule for MySQL's port (3306):
    iptables -A INPUT -p tcp --dport 3306 -j DROP
    
  2. Then add allow rules for your target pod IPs:
    # Allow pod 10.233.64.10
    iptables -I INPUT -p tcp --dport 3306 -s 10.233.64.10 -j ACCEPT
    # Allow pod 10.233.64.11
    iptables -I INPUT -p tcp --dport 3306 -s 10.233.64.11 -j ACCEPT
    
  3. Save the rules to persist across VM reboots:
    # On Debian/Ubuntu
    iptables-save > /etc/iptables/rules.v4
    # On RHEL/CentOS
    service iptables save
    

Workaround If BGP Routing Isn't Possible

If you can't add the VM as a BGP peer, you can use node-level SNAT to assign a unique source IP to traffic from your target pods, then allow that IP on the VM:

  1. On every cluster node, add an iptables rule to SNAT traffic from your target pods to a dedicated IP:
    # Replace with your pod IP range or specific pod IPs
    iptables -t nat -A POSTROUTING -s 10.233.64.0/24 -d 10.0.0.50/32 --dport 3306 -j SNAT --to-source 192.168.1.200
    
  2. On the VM, allow only this dedicated IP:
    iptables -I INPUT -p tcp --dport 3306 -s 192.168.1.200 -j ACCEPT
    iptables -A INPUT -p tcp --dport 3306 -j DROP
    
    Note: You'll need to update these rules if pods are recreated and their IPs change—using Calico's static IP assignment for critical pods avoids this hassle.

内容的提问来源于stack exchange,提问作者Alex.Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:54:37