Dockerfile HOSTNAME docker build的指令,如docker run -h

我正在尝试在构build期间设置docker容器内的主机名,因为某些软件安装使用发现的随机生成的主机名,并永久性地将该主机名烘焙到configuration中。

虽然可以在通过运行-h交互式运行时设置主机名,但通过使用Dockerfile生成相同的function是不可用的。

解决此问题的唯一方法是使用LD_PRELOAD黑客,以便我可以将主机名设置为localhost。 LD_PRELOAD黑客有不必要的副作用,我有麻烦解决。 在使用“docker run -it -h localhost”时,软件安装没有问题。

strace报告安装程序调用uname来确定主机名。

uname({sys="Linux", node="12b0c7c7eacb", ...}) = 0 

有谁知道如何解决这个限制吗?

更新1

这不是问题的重复如何处理特定的主机名像Dockerfile中的-h选项,因为这是特别谈论由dynamic生成该文件引起的“/ etc / hosts”问题。 这很容易解决,因为它是一个可写的文件。

这是关于尝试从系统调用(如uname和gethostname)parsing主机名的软件安装。 从我可以告诉这不能解决,因为主机名不能在运行的docker容器内更改。 uname系统调用可能引用/ proc / sys / kernel / hostname,这是只读的,不能改变。 通常可以运行hostname命令,但是这个命令会产生一个错误,即使你是root用户,你也必须是root用户。 解决方法是使用-h标志,这在构build中不可用。

更新2

对于任何寻找解决方法的人来说,这只是在Docker构build期间才需要使用,如果需要使用docker run自定义主机名,请使用-h标志。 这是基于别人的工作。

Dockerfile:

 RUN gcc -o fakehostname.o -c -fPIC -Wall fakehostname.c RUN gcc -o libfakehostname.so -shared -W1,export-dynamic fakehostname.o -ldl RUN .. export LD_PRELOAD=/u01/app/oracle/libfakehostname.so;\ installer section .. 

C来源:

 #define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/utsname.h> #include <stdio.h> #include <string.h> static int (*real_gethostname)(char *name, size_t len); int uname(struct utsname *buf) { int ret; ret = syscall(SYS_uname, buf); strcpy(buf->nodename, "localhost"); return ret; } int gethostname(char *name, size_t len) { const char *val; /* Override hostname */ val = "localhost"; if (val != NULL) { strncpy(name, val, len); return 0; } /* Call real gethostname() */ return real_gethostname(name, len); } 

http://github.com/docker/docker/issues根据in_the_void,因为没有解决这个问题。

让我看看,如果我理解你的问题,你想build立一个图像,当作为一个容器运行的运行时主机名,即使用于build设的主机名是不一样的。 正确? 如果是这样,我的问题是你是否能够重新configuration软件安装后有一个新的主机名?

如果这是可能的,我会build议编写一个能够修改主机名的脚本,并使用这个脚本作为ENTRYPOINT 。 通过这种方式,您可以保证在任何时候您的容器运行时(通过任何命令)您已经更正了主机名,而且您不需要花费时间在构build时强制对特定主机名的支持,而这在您自己的承认中是困难的去做。