calico: Outgoing packets does not follow configuration on Source IP
I am observing a bad choice of source IP of outgoing traffic on my Kubernetes nodes.
I have a node that have multiple IP adresses on a single interface:
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether fa:da:fa:da:fa:da brd ff:ff:ff:ff:ff:ff
altname enp0s3
inet 1.2.3.4/32 scope global ens3
valid_lft forever preferred_lft forever
inet 1.2.3.5/32 scope global ens3
valid_lft forever preferred_lft forever
inet 1.2.3.6/32 scope global ens3
valid_lft forever preferred_lft forever
inet 1.2.3.7/32 metric 100 scope global dynamic ens3
valid_lft 84172sec preferred_lft 84172sec
If I display the node configuration using calicoctl
I see this:
spec:
addresses:
- address: 10.100.0.253/16
type: CalicoNodeIP
- address: 10.100.0.253
type: InternalIP
- address: 1.2.3.7
type: ExternalIP
bgp:
ipv4Address: 10.100.0.253/16
ipv4VXLANTunnelAddr: 10.42.9.192
orchRefs:
- nodeName: noprod-node-2
orchestrator: k8s
Here is the default route (using ip route
) of the given node:
default via 1.2.3.1 dev ens3 proto dhcp src 1.2.3.7 metric 100
Expected Behavior
I expect all traffic coming out of the node described to be seen as coming from 1.2.3.7
as it is:
- The external ip configured
- The default route out on the system
Current Behavior
Executing a curl ifconfig.me
on the node directly will display the right outgoing ip address (1.2.3.7
on the exemple given at the beginning).
Executing a curl ifconfig.me
on a container will always display the first IP of the interface porting all the addresses (so it will display 1.2.3.4
on this specific case).
Possible Solution
I have the feeling that it shows something at the first index of an array of available address on a given interface when selecting the outgoing interface. Maybe it should check for the default route of the host or the ExternalIP
specifically ?
Steps to Reproduce (for bugs)
- Deploy a node with multiple public IP on a single interface
- Set an ExternalIP that is not the first of the list of the attached IP on this interface
curl
a service displaying the outgoing adress- See that it does not match.
Context
This issue is affecting me because I need to be sure of the outgoing IP of my containers since I have to whitelist my IPs to other providers that will interact with my systems.
Your Environment
- Calico version:
v3.25.0
- Orchestrator version (e.g. kubernetes, mesos, rkt):
v1.26.5+rke2r1
- Operating System and version:
Ubuntu 22.04.2 LTS (jammy)
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 18 (10 by maintainers)
Sure, here is example:
Install
If you want to try it out, you can install the latest version.
Create EgressGateway CR
Choose a node as the Egress Node, this node will implement the Egress IP.
Create an EgressPolicy to match the Pods that require Egress
Create test pod
Create EgressPolicy
Test
You can see that your EgressIP has changed to the set IP.
@MalikaML
part 1 - think
EgressGateway can assign an Egress IP to a specific namespace/pod (or understood as, encapsulating the internet access traffic from a Pod, or all Pods under a namespace, as a specific Source IP).
Let’s take a step-by-step look at whether EgressGateway can solve your actual scenario.
First, let’s look at the principle of converting namespace/pod internet access traffic to an Egress IP: When
EgressPolicy.spec.destSubnet
is not filled in, the default behavior of EgressPolicy is to SNAT all traffic (except for accessing within the cluster) to the Egress IP. EgressGateway will automatically discover the CIDR within the cluster and can easily identify external access traffic. Of course, you can also manually specify that traffic accessing destSubnet is converted to Egress IP.At this point, it seems that EgressGateway can solve the problem in your scenario. However, it’s important to note whether you need EgressGateway to record access requests? EgressGateway currently does not record access requests. If you are managing on a network device (such as a Cisco Switch), it’s easy to see this part of the traffic characteristics.
part 2 - put into effect
part 3 - introspect
You should use EgressGateway when you have the above requirements. If you simply want to restrict internet traffic without identifying it, you should use k8s NetworkPolicy.