Docker:主机名与容器名称

时间:2018-02-15 08:32:20

标签: perl docker

我正在使用泊坞窗覆盖网络

我正在一个容器中启动服务器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守护程序)上的另一个容器连接到此服务器:ie 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' s socket.gethostname()或其他什么获取主机名的方法会认为并且不使用ebcf3c65c3e1等容器ID作为主机名吗?

[编辑] 我看到了docker run的选项--hostname但是我真的需要同时提供--name和--hostname吗?是否有其他方法可以自动继承容器名称作为主机名?

1 个答案:

答案 0 :(得分:0)

个人意见:您应该保留主机名。如果您需要使用scale: <n>生成多个类似的容器,则任何设置主机名的尝试都将无效。

但是您可以通过docker:socket从容器内部获取容器名称,并将其用于其他许多目的,例如用于标识自身或其他容器的代码。

请参阅我的示例here