docker之dockerFile(解决hosts,hostname问题)

本文介绍了Dockerfile的基本语法及如何使用它来定制Docker镜像,包括关键指令如FROM、RUN、ENV等的使用方法。并通过实例展示了如何通过Dockerfile修改容器内的配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前自己使用docker的方式都是直接使用镜像来进行创建,今天尝试了一下使用dockerfile来进行创建,发现似乎这才更加符合docker的思想-----在原始镜像上面添加改动层,然后更具改动创建自己的镜像文件。(不知道理解是否有错误)。首先我们来了解一些dockerfile的基本语法:

在Dockerfile中用到的命令有
FROM
    FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令。至于image则可以是任何合理存在的image镜像。
    FROM 一定是首个非注释指令 Dockerfile.
    FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。
    如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。
MAINTAINER
    这里是用于指定镜像制作者的信息
RUN
    RUN命令将在当前image中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行Dockerfile中的下一个指令。
    层级 RUN 指令和生成提交是符合Docker核心理念的做法。它允许像版本控制那样,在任意一个点,对image 镜像进行定制化构建。
    RUN 指令缓存不会在下个命令执行时自动失效。比如 RUN apt-get dist-upgrade -y 的缓存就可能被用于下一个指令. --no-cache 标志可以被用于强制取消缓存使用。
ENV
    ENV指令可以用于为docker容器设置环境变量
    ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run --env <key>=<value>来修改环境变量。
USER
    USER 用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险。
WORKDIR
    WORKDIR 用来切换工作目录的。Docker 默认的工作目录是/,只有 RUN 能执行 cd 命令切换目录,而且还只作用在当下下的 RUN,也就是说每一个 RUN 都是独立进行的。如果想让其他指令在指定的目录下执行,就得靠 WORKDIR。WORKDIR 动作的目录改变是持久的,不用每个指令前都使用一次 WORKDIR。
COPY
    COPY 将文件从路径 <src> 复制添加到容器内部路径 <dest>。
    <src> 必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url,<dest> 是目标容器中的绝对路径。
    所有的新文件和文件夹都会创建UID 和 GID 。事实上如果 <src> 是一个远程文件URL,那么目标文件的权限将会是600。
ADD
    ADD 将文件从路径 <src> 复制添加到容器内部路径 <dest>。
    <src> 必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url。<dest> 是目标容器中的绝对路径。
    所有的新文件和文件夹都会创建UID 和 GID。事实上如果 <src> 是一个远程文件URL,那么目标文件的权限将会是600。
VOLUME
    创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
EXPOSE
    EXPOSE 指令指定在docker允许时指定的端口进行转发。

CMD
    Dockerfile.中只能有一个CMD指令。 如果你指定了多个,那么最后个CMD指令是生效的。
    CMD指令的主要作用是提供默认的执行容器。这些默认值可以包括可执行文件,也可以省略可执行文件。
    当你使用shell或exec格式时,  CMD 会自动执行这个命令。
ONBUILD
    ONBUILD 的作用就是让指令延迟執行,延迟到下一个使用 FROM 的 Dockerfile 在建立 image 时执行,只限延迟一次。
    ONBUILD 的使用情景是在建立镜像时取得最新的源码 (搭配 RUN) 与限定系统框架。
ARG
    ARG是Docker1.9 版本才新加入的指令。
    ARG 定义的变量只在建立 image 时有效,建立完成后变量就失效消失
LABEL
    定义一个 image 标签 Owner,并赋值,其值为变量 Name 的值。(LABEL Owner=$Name )

ENTRYPOINT
    是指定 Docker image 运行成 instance (也就是 Docker container) 时,要执行的命令或者文件。

上面就是我们创建的基本语法,必须以FROM开始。但是有一个问题,我们在对docker容器中的hosts,hostname等文件进行修改时只是进行了临时的改变,我们下一次启动同一个容器的时候又恢复为了默认值。这样我们就需要每次启动都需要进行相关的修改。感觉这样做太繁琐了。

想想docker是干什么的?就是在基础镜像上面添加改动层,这种思想其实是很方便的,我们不需要去更改操作系统的源码,或者是显示的更改docker的镜像文件就可以从系统层面上进行修改。那么我们可以直接添加一个改动层,让改动层来支持我们进行这些文件的操作。再stackoverflow上面看到一中改动的方法是这样的:

FROM ubuntu:14.04
RUN cp /etc/hosts /tmp/hosts
RUN mkdir -p -- /lib-override && cp /lib/x86_64-linux-gnu/libnss_files.so.2 /lib-override
RUN sed -i 's:/etc/hosts:/tmp/hosts:g' /lib-override/libnss_files.so.2
ENV LD_LIBRARY_PATH /lib-override
就是把启动时加载的文件给他进行相关的替换,替换成我们所制定的文件,经过测试,此方法可行。

那么hostname的更改呢?那就挺方便了,我们只需要将上面的dockerfile build生成一个新的镜像,然后在启动这个镜像的时候通过-h 指定hostname就可以了。如下:

sudo docker run -h slave -it --name slave ubuntu /bin/bash


### 解决 Docker 容器内无法解析主机名的问题 当遇到容器内部无法解析自定义主机名的情况时,可以采取多种方法来解决问题。 如果希望在构建镜像阶段设置固定的主机名,在 `Dockerfile` 中添加如下指令: ```dockerfile LABEL org.label-schema.name="myapp" LABEL maintainer="admin@example.com" # 设置默认主机名 RUN echo "mycustomhostname" > /etc/hostname \ && ln -sf /dev/stdout /var/log/myapp.log ``` 不过更灵活的方式是在运行容器时动态指定主机名称。这可以通过 `-h` 或者 `--hostname` 参数实现[^1]: ```bash docker run -d --name=mycontainer -h mycustomhostname myimage:latest ``` 另外一种常见情况是需要让多个容器之间能够互相通过自定义域名访问彼此。此时应该考虑使用 Docker 自带的网络功能创建用户定义桥接网络,并确保所有相关服务都在同一个自定义网桥下启动: ```bash # 创建名为 mynetwork 的新网络 docker network create mynetwork # 启动带有特定主机名的服务A并加入到mynetwork中 docker run -d --name=servicea --net=mynetwork --hostname=servicea.example.local servicea_image # 类似地为其他依赖组件配置相同的操作... ``` 对于某些复杂场景下的 DNS 解析需求,则可能需要用到外部DNS服务器或者修改 `/etc/hosts` 文件来进行静态映射。可以在启动命令里增加额外参数完成此操作: ```bash # 修改 hosts 文件内容 docker run -d --name=mywebserver \ --add-host database.server:192.168.0.5 \ webserver_image ``` 以上几种方式可以根据实际应用场景选择合适的方法处理容器内的主机名解析问题
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值