<p>I need to use UDP broadcast for peer discovery. </p>

<p>Environment:</p>

<ul>
<li><code>docker-desktop</code> with a single node Kubernetes cluster</li>
</ul>

<p>My code looks as follows:</p>

<pre class="lang-java prettyprint-override"><code>import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainApp {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int inPort = Integer.parseInt(System.getenv("IN_PORT"));
        int outPort = Integer.parseInt(System.getenv("OUT_PORT"));
        String name = System.getenv("NAME");
        Client client = new Client(name, outPort);
        Server server = new Server(name, inPort);

        ExecutorService service = Executors.newFixedThreadPool(2);
        service.submit(client);
        service.submit(server).get();
    }


    static class Client implements Runnable {
        final String name;
        final int port;

        Client(String name, int port) {
            this.name = name;
            this.port = port;
        }

        @Override
        public void run() {
            System.out.println(name + " client started, port = " + port);
            try (DatagramSocket socket = new DatagramSocket()) {
                socket.setBroadcast(true);
                while (!Thread.currentThread().isInterrupted()) {
                    byte[] buffer = (name + ": hi").getBytes();

                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
                            InetAddress.getByName("255.255.255.255"), port);
                    socket.send(packet);
                    Thread.sleep(1000);
                    System.out.println("packet sent");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }


    static class Server implements Runnable {
        final String name;
        final int port;

        Server(String name, int port) {
            this.name = name;
            this.port = port;
        }

        @Override
        public void run() {

            System.out.println(name + " server started, port = " + port);

            try (DatagramSocket socket = new DatagramSocket(port)) {

                byte[] buf = new byte[256];
                while (!Thread.currentThread().isInterrupted()) {
                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
                    socket.receive(packet);
                    String received = new String(packet.getData(), 0, packet.getLength());

                    System.out.println(String.format(name + " received '%s' from %s:%d", received,
                            packet.getAddress().toString(),
                            packet.getPort()));
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }

}
</code></pre>

<p>Kubernetes pod settings:</p>

<p>For <code>peer-1</code>:</p>

<pre><code>    spec:
      containers:
        - name: p2p
          image: p2p:1.0-SNAPSHOT
          env:
          - name: NAME
            value: "peer-1"
          - name: IN_PORT
            value: "9996"
          - name: OUT_PORT
            value: "9997"
</code></pre>

<p>For <code>peer-2</code> :</p>

<pre><code>    spec:
      containers:
        - name: p2p-2
          image: p2p:1.0-SNAPSHOT
          env:
          - name: NAME
            value: "peer-2"
          - name: IN_PORT
            value: "9997"
          - name: OUT_PORT
            value: "9996"
</code></pre>

<p>I used a different in/out ports for simplicity's sake. In reality, it should be the same port, e.g.: 9999</p>

<p>I see that each pod has a unique IP address</p>

<pre><code>kubectl get pods -o wide

NAME                                READY   STATUS    RESTARTS   AGE     IP          NODE             NOMINATED NODE   READINESS GATES
p2p-deployment-2-59bb89f9d6-ghclv   1/1     Running   0          2m26s   10.1.0.38   docker-desktop   &lt;none&gt;           &lt;none&gt;
p2p-deployment-567bb5bd77-5cnsl     1/1     Running   0          2m29s   10.1.0.37   docker-desktop   &lt;none&gt;           &lt;none&gt;
</code></pre>

<p>Logs from <code>peer-1</code>:</p>

<pre><code>peer-1 received 'peer-2: hi' from /10.1.0.1:57565
</code></pre>

<p>Logs from <code>peer-2</code>:</p>

<pre><code>peer-2 received 'peer-1: hi' from /10.1.0.1:44777
</code></pre>

<p>Question: why <code>peer-1</code> receives UDP packets from <code>10.1.0.1</code> instead of <code>10.1.0.37</code> ?</p>

<p>If I log into <code>peer-2</code> container: <code>kubectl exec -it p2p-deployment-2-59bb89f9d6-ghclv -- /bin/bash</code></p>

<p>Then </p>

<pre><code>socat - UDP-DATAGRAM:255.255.255.255:9996,broadcast
test
test
...
</code></pre>

<p>in <code>peer-1</code> logs I see <code>peer-1 received 'test' from /10.1.0.1:43144</code>. 
Again why network address is <code>10.1.0.1</code> instead of <code>10.1.0.37</code>.</p>

<p>Could you please tell me what I'm doing wrong?</p>

<p>Note: when using the same port to send/receive UDP packets, some peer can receive a packet from its own IP address. In other words, a peer can only discover its own IP address but always gets <code>10.1.0.1</code> for packets received from other peers/pods</p>

dmgcodevil
<p>For some reason, UDP <strong>broadcast</strong> doesn't work as expected in Kubernetes infrastructure, however <strong>multicast</strong> works fine.</p>

<p>Thanks <a href="https://stackoverflow.com/users/3745413/ron-maupin">Ron Maupin</a> for suggesting multicast.</p>

<p><a href="https://gist.github.com/dmgcodevil/22e50eb8f415602bb8d128fe28cdb209" rel="nofollow noreferrer">Here</a> you can find java code + kube config</p>
