0

Given:

  • I have a containerized service that sends UDP packets to a list of network elements (3rd party syslog sink servers).
  • Each target network element is specified by IP address, its port number is constant, the same for each node.

I need to create a simple test environment - like in the graph below. The main service emits syslog messages, on the graph it's named PRODUCER CONTAINER.

TEST CONTAINER can easily spawn docker containers, so I picked spawning alpine/socat:latest.

The question is:

  1. What arguments do I have to pass to socat in order to obtain the setup working?
  2. What else do I need to care about?

I tried many combinations of socat args so far, but with no luck. With socat UDP-RECV:514 UDP-SENDTO:172.25.0.2:65354,bind=:1234 I receive messages in the proxy containers, but nothing is received in the test container.

Seems that I lack of overall knowledge. Could anyone explain how it is supposed to be done?

test_environment

The code I use in the test container looks more-less like that:

import os
import platform
import threading
from socket import socket

import docker
from docker import DockerClient
from docker.models.containers import Container
from docker.models.networks import Network


def create_proxy():
    docker_client: DockerClient = docker.from_env()
    test_network: Network = docker_client.networks.create(f'test_network_{os.environ.get("HOSTNAME")}')
    testrunner_container: Container = docker_client.containers.get(platform.node())

    testrunner_container.reload()
    test_container_ip = testrunner_container.attrs['NetworkSettings']['Networks'][test_network.name]['IPAddress']

    socket_ = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    socket_.bind(('', 0))  # bind to random local port
    _, test_container_port = socket_.getsockname()
    proxy_port = 1234
    socat_args = [
        '-d', '-d', f'UDP-RECV:514', f'UDP-SENDTO:{test_container_ip}:{test_container_port},bind=:{proxy_port}',
    ]

    proxy_container: Container = docker_client.containers.run(
        'alpine/socat:latest',
        socat_args,
        name='udp_proxy_container',
        network=test_network.name,
        detach=True,
        remove=True,
    )
    proxy_container.reload()
    proxy_ip = proxy_container.attrs['NetworkSettings']['Networks'][test_network.name]['IPAddress']

    socket_ = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    socket_.bind(('', 0))  # bind to random local port

    socket_.connect((proxy_ip, proxy_port))
    socket_.settimeout(1)

    def receive_loop(queue):
        while True:
            try:
                message = socket_.recv(1024)
                if b'STOP IT' in message:
                    break
                queue.append(message)
            except socket.timeout as e:
                log.error(f"{type(e).__name__} in Syslog stub's receive loop: {e}")

    msg_queue = []
    receive_thread = threading.Thread(target=receive_loop, args=(msg_queue,))
    receive_thread.daemon = True
    receive_thread.start()

    # ... some other code

0 Answers0