作者:Ms丶娇丶 | 来源:互联网 | 2023-05-17 11:31
我正在尝试在构建期间在docker容器中设置主机名,因为某些软件安装使用发现的随机生成的主机名并将该主机名永久地烘焙到配置中.
虽然可以通过run -h以交互方式运行时设置主机名,但使用Dockerfile构建时无法使用相同的功能.
解决此问题的唯一方法是使用LD_PRELOAD hacks,以便我可以将主机名设置为localhost.LD_PRELOAD黑客有不必要的副作用,我无法解决.使用"docker run -it -h localhost"时,软件安装没有问题.
strace报告安装程序调用uname确定主机名.
uname({sys="Linux", node="12b0c7c7eacb", ...}) = 0
有谁知道如何解决这个限制?
更新1
这不是如何处理Dockerfile中的特定主机名(如-h选项)的问题的副本,因为这是专门讨论由动态生成的文件引起的"/ etc/hosts"问题.这很容易解决,因为它是一个可写文件.
这是关于尝试从系统调用(例如uname和gethostname)解析主机名的软件安装.据我所知,由于无法在正在运行的docker容器中更改主机名,因此无法解决此问题.uname系统调用可能引用/ proc/sys/kernel/hostname,这是只读的,不能更改.通常可以运行hostname命令,但是此命令会生成一个错误,即使您是root用户,也必须是root用户.解决方法是使用-h标志,这在构建中不可用.
更新2
对于任何寻找解决方法的人来说,这只需要在docker构建期间使用,如果需要使用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
#include
#include
#include
#include
#include
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根据into_the_void,因为没有解决这个问题的方法.