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:
- What arguments do I have to pass to
socat
in order to obtain the setup working?
- 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?
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