gpt4 book ai didi

perl - Docker:暴露应用程序在容器内使用的多个端口(未预先确定)

转载 作者:行者123 更新时间:2023-12-02 18:53:50 25 4
gpt4 key购买 nike

server.pl

sub sock_initialize {
my $sock = q{};
my $port = q{};

# Get a port for our server.
$sock = IO::Socket::INET->new(
Listen => SOMAXCONN, # listen queue depth
LocalPort => 0,
Reuse => 1
);

die "Unable to bind a port: $!" if !$sock;

$port = $sock->sockport();
my $ip = "";
my $uid = (getpwuid( $> ))[2];
my $queue = join(":", $ip, $port, $$, $uid);

print sprintf("put started on port $port ($$), SOMAXCONN=%d\n", SOMAXCONN);
return $sock;
} ## end sub sock_initialize

my $listen_sock = sock_initialize();
while (1) {
#my $xsock = Accept();
my $xsock;
while (1) {
$! = 0;
# Accept can block. Need to use nonblocking poll (Stevens)
$xsock = $listen_sock->accept; # ACCEPT
last if defined $xsock;
next if $! == EINTR;
die "accept error: $!";
if ( defined $xsock ) {
$xsock->blocking(0); # mark executor socket nonblocking
$xsock->sockopt( SO_KEEPALIVE() => 1 ) or die "sockopt: $!";
}


#my $rbufp = $conn->readbufref;
#my $rdstatus = Read( $sock, $rbufp );
my $buff = "";

while (1) {
$! = 0;
# Accept can block. Need to use nonblocking poll (Stevens)
$xsock = $listen_sock->accept; # ACCEPT
last if defined $xsock;
next if $! == EINTR;
die "accept error: $!";
if ( defined $xsock ) {
$xsock->blocking(0); # mark executor socket nonblocking
$xsock->sockopt( SO_KEEPALIVE() => 1 ) or die "sockopt: $!";
}
}

#my $rbufp = $conn->readbufref;
#my $rdstatus = Read( $sock, $rbufp );
my $buff = "";
while (1) {
my $nbytes = sysread $xsock, $buff, 32768, length($buff); # SYSCALL

if ( !defined $nbytes ) { # read error
next if $! == EINTR;
last if $! == EWOULDBLOCK; # normal
return;
}
last if $nbytes == 0; # EOF
}
print "received $buff\n";
last;
}

client.pl
my $host = "localhost";
my $port = 37402; # get port number from server.pl


my $s = IO::Socket::INET->new (PeerAddr => $host,
PeerPort => $port,
Type => SOCK_STREAM,
Proto => 'tcp',
Timeout => 1);
if ($s) {
$s->blocking (0) ;
}

my $nbytes = syswrite $s, "hi from X"; # SYSCALL

首先,我将启动server.pl
$perl test_socket_server.pl 
$put started on port 37402 (16974), SOMAXCONN=128

然后我将端口号放在client.pl上
perl test_socket_client.pl

然后,在server.pl shell 上,我看到了
received hi from X

因此,它按预期工作。
现在,当我通过以下方式将server.pl放入容器中时
docker run ubuntu perl server.pl
put started on port 38170 (1), SOMAXCONN=128

然后,我将端口号写入client.pl并运行,但是server.pl没有收到消息

我的理解是容器端口不会通过EXPOSE暴露给主机

现在,即使使用EXPOSE可以解决问题,server.pl也会在未分配的端口上连接,即每次运行 LocalPort => 0, server.pl在容器内运行时,pornumber都可以更改。我的理解是,您必须在容器运行时公开端口,但是此时,您不知道将在哪个端口运行server.pl。我希望这样,没有指定的端口,因为server.pl的多个实例可以在容器中运行(因此需要能够使用不同的端口)。有解决这个问题的策略吗?

启动容器时,您可以公开端口范围,例如30000以上吗? [我已经阅读了其他一些关于暴露端口范围的堆栈溢出问题,但似乎存在一些性能问题,因为实际过程是按端口(?)派生的?在运行时在容器中。也许是由协调员完成的?

最佳答案

选项1-Docker群集和覆盖网络

Docker群的overlay network中的容器(更确切地说是服务)默认情况下公开所有端口。在这种情况下,覆盖网络或多或少地充当专用网络。因此,如果客户端应用程序也是群集的一部分,则它只能连接到服务器容器/服务。
但是,如果不是这种情况,您仍然可以使用 service update --publish-add API解决此情况。此命令使您可以在运行时更改端口暴露(或多或少是您所要求的),有关更多信息,请参见Publish ports on an overlay network部分:

Swarm services connected to the same overlay network effectively expose all ports to each other. For a port to be accessible outside of the service, that port must be published using the -p or --publish flag on docker service create or docker service update. Both the legacy colon-separated syntax and the newer comma-separated value syntax are supported. The longer syntax is preferred because it is somewhat self-documenting.



如果您想使用Docker API解决您的问题,这将是最佳选择,并且它还将完美地处理多主机方案。但是对于高级部分(您的客户端不是群集的一部分,并且您想使用 service update),您将不得不将容器包装到服务中。

注意: --publish-add并没有真正考虑透彻,因为 docker service update通过重新启动容器来工作,因此您的应用程序很可能会切换到另一个端口,这可能是稍微不同的用例的一种选择。

选项2---net = host

如果所有服务器容器无论如何都应在一台主机上运行,​​则可以轻松使用Docker的 --net=host 功能,而不必显式公开任何端口。

例:
docker run --net=host ubuntu perl server.pl

选项3-端口代理

您还可以使用 socatssh之类的应用程序将服务器应用程序的端口手动映射到每个容器的预定义端口。例如,参见 this answer中的 Exposing a port on a live Docker container

关于perl - Docker:暴露应用程序在容器内使用的多个端口(未预先确定),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48772393/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com