Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
docker构建类docker run-h的docker文件主机名指令_Docker_Dockerfile - Fatal编程技术网

docker构建类docker run-h的docker文件主机名指令

docker构建类docker run-h的docker文件主机名指令,docker,dockerfile,Docker,Dockerfile,我试图在构建期间在docker容器中设置主机名,因为某些软件安装使用发现的随机生成的主机名,并将该主机名永久地烘焙到配置中 虽然可以在通过run-h交互运行时设置主机名,但通过Dockerfile使用build无法使用相同的功能 解决这个问题的唯一方法是使用LD_PRELOAD hacks,这样我就可以将主机名设置为localhost。LD_预加载黑客有一些不必要的副作用,我在处理这些副作用时遇到了麻烦。使用“docker run-it-h localhost”时,软件安装不会出现问题 stra

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

虽然可以在通过run-h交互运行时设置主机名,但通过Dockerfile使用build无法使用相同的功能

解决这个问题的唯一方法是使用LD_PRELOAD hacks,这样我就可以将主机名设置为localhost。LD_预加载黑客有一些不必要的副作用,我在处理这些副作用时遇到了麻烦。使用“docker run-it-h localhost”时,软件安装不会出现问题

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

uname({sys="Linux", node="12b0c7c7eacb", ...}) = 0
有人知道如何绕过这个限制吗

更新1

这不是问题的重复,因为它专门讨论动态生成的文件所产生的“/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 <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);
}
定义GNU源
#包括
#包括
#包括
#包括
#包括
#包括
静态int(*real_gethostname)(字符*名称、大小长度);
int uname(结构utsname*buf)
{
int ret;
ret=syscall(SYS_uname,buf);
strcpy(buf->nodename,“localhost”);
返回ret;
}
int gethostname(字符*名称,大小\u t len)
{
常量字符*val;
/*覆盖主机名*/
val=“localhost”;
如果(val!=NULL)
{
strncpy(名称、val、len);
返回0;
}
/*调用实gethostname()*/
返回真实的主机名(名称,len);
}

根据进入\u void,因为这个问题没有解决方案。

让我看看我是否理解您的问题,您希望构建一个映像,当作为容器运行时,它具有运行时主机名,即使用于构建的主机名不同。对的如果是这样,我的问题是:在安装软件后,您是否能够重新配置软件,使其具有新的主机名

如果这是可能的,我建议编写一个能够修改主机名的脚本,并将此脚本用作
入口点
。通过这种方式,您可以保证在容器运行时(使用任何命令)已更正主机名,并且不会在构建时花费时间强制支持特定主机名,这一点您自己也承认很难做到。

您可以使用来构建映像并分配主机名,例如

version: '3'
services:
  all:
    image: testimage
    container_name: myname
    hostname: myhost
    build:
      context: .

运行方式:
docker compose--build-up
我最近遇到了类似的问题

对我有效的解决方案是在容器名称空间中设置主机名。 为了自动执行此操作,我将以下docker构建脚本放在一起:

docker build . | tee >((grep --line-buffered -Po '(?<=^change-hostname ).*' || true) | while IFS= read -r id; do nsenter --target "$(docker inspect -f '{{ .State.Pid }}' "$id")" --uts hostname 'new-hostname'; done)
打印出
change hostname$(hostname)
(其中hostname应打印出当前容器id)的第一行向构建脚本发送信号,以更改该容器的主机名。然后,构建脚本查询容器的pid,并在其uts命名空间中执行
hostname'newhostname'
sleep 1
只给构建脚本一些时间来正确调整主机名。然后修改
/etc/hostname
/etc/hosts
以包含新设置的主机名


这甚至改变了uname-n的输出,因此我很确定它可以作为原始问题的解决方案。

我的回答对您有帮助吗?谢谢你的回复,纳撒尼尔;我想你的答案是我在网上唯一能找到的关于这个话题的答案。我正在安装的软件查看/etc/hosts,但使用uname系统调用派生主机名。我将在将来记住您的解决方案。这可能是一个伟大的建议,入口点脚本是我们为所有docker图像所做的。不幸的是,该软件在大约60个位置配置主机名,包括文本文件、xml文件和内部二进制文件。建议的主机名更改方法意味着重新安装软件以及一些附加步骤。这意味着入口点启动时间将从2分钟增加到大约40分钟,这是不可行的。好吧,也许是时候尝试问题跟踪器()了,因为我认为这个功能不存在,或者至少没有遇到过它55分钟前进入\u void谢谢您提供的信息,我认为这是正确的答案。docker compose是在构建步骤中使用指定的主机名,还是仅在运行步骤中使用指定的主机名?我希望看到一个简单构建文件的演示,它在构建时和运行时输出主机名。这只在运行时设置主机名。不是在构建期间。至少在Mac上使用“docker compose version 1.23.2,build 1110ad01”。
RUN echo "change-hostname $(hostname)"; \
    sleep 1; \
    printf '%s\n' "$(hostname)" > /etc/hostname; \
    printf '%s\t%s\t%s\n' "$(perl -C -0pe 's/([\s\S]*)\t.*$/$1/m' /etc/hosts)" "$(hostname)" > /etc/hosts; \
    echo 'Installing more stuff...'