我正在使用docker overlay网络
我在一个容器中启动一个服务器myserver.pl
use strict;
use warnings;
use POSIX qw(:sys_wait_h :errno_h :fcntl_h strftime);
use Getopt::Long;
use File::Basename;
use IO::Socket;
use IO::Select;
STDOUT->autoflush(1);
use Fcntl;
use Socket;
use Carp;
use FileHandle;
use Cwd qw{abs_path cwd};
use Sys::Hostname;
our $HOST = hostname();
our $PUBQDIR = '/x/eng/site/build/altload';
our $PWD = cwd();
our $EMPTY = q{};
our $NL = "\n";
our $SPACE = q{ };
our $ANY_RE = qr{.*};
our $REDIS_OS_RE = qr{^br-redis$};
our $HOST_SPLIT_RE = qr{[.][^:]*};
our $bash_and_list_op = '&&';
my $Request_File = $EMPTY;
# options from command line
my $Opt_Class = 'L';
my $Redis = $EMPTY;
my %Published_Requests = (); # Track published queue requests for cleanup
chomp $HOST;
$HOST =~ s/[.].*//g;
chomp $PWD;
my $Pool = $EMPTY;
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();
# Determine and log the dispatcher queue id
#my $ip = inet_ntoa( scalar gethostbyname( $HOST ));
my $ip = "";
my $uid = (getpwuid( $> ))[2];
my $queue = join(":", $ip, $port, $$, $uid);
# Include in the published queue name:
# - job class, which must be the same for all jobs we submit
# - Our Hostname and Port
# Can't lower hostname to IP yet, it might give 127.0.0.1
print sprintf("Connect me at $HOST 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 $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;
作者:docker run -v /home/:/home/ --name myhost01 --network test-net perl perl /home/myserver.pl
它输出:
Connect me at ebcf3c65c3e1 on port 39580 (1), SOMAXCONN=128
我可以从连接到相同覆盖网络的不同主机(docker守护进程)上的另一个容器通过以下方式连接到此服务器:即myhost01:39580
my $host = "myhost01";
my $port = 39850;
my $s = IO::Socket::INET->new (PeerAddr => $host,
PeerPort => $port,
Type => SOCK_STREAM,
Proto => 'tcp',
Timeout => 1);
所以,这很好,但是我事先知道容器的名称,所以我知道要连接到它,我希望myserver.pl将其主机名公布为myhost01
,而不是ebcf3c65c3e1
Connect me at myhost01 on port 39580 (1), SOMAXCONN=128
有没有办法在容器中设置主机名,使其认为主机名与容器名相同,并且perl的Sys::Hostname:hostname()
或python的socket.gethostname()
或任何获取主机名的方法都会这样认为,并且不使用容器id (如ebcf3c65c3e1
)作为主机名?
编辑我看到选项--hostname用于docker run,但我真的需要同时提供--name和--hostname吗?有没有其他方法可以自动继承容器名作为它的主机名?
发布于 2018-08-17 22:24:56
个人意见:您应该不使用主机名。如果您需要使用scale: <n>
生成多个类似的容器,则任何设置主机名的尝试都不会起作用。
但是您可以通过docker:socket
从容器内部获取容器名称,并将其用于许多其他用途,例如用于代码标识自身或其他容器。
请参阅我的示例here
https://stackoverflow.com/questions/48802901
复制相似问题