docker 容器连接, dockerfile

文章目录

  • [docker 容器连接](#docker 容器连接)
    • [端口映射 -P/-p](#端口映射 -P/-p)
    • [docker port 容器名:查"容器端口"对应到了"宿主机哪个地址和端口"](#docker port 容器名:查“容器端口”对应到了“宿主机哪个地址和端口”)
      • [docker port 容器名 查看这个容器所有已经发布的端口映射](#docker port 容器名 查看这个容器所有已经发布的端口映射)
      • [docker port 容器名 5000/docker port 容器名 5000/tcp.只看容器内部这个端口映射到了宿主机哪里](#docker port 容器名 5000/docker port 容器名 5000/tcp.只看容器内部这个端口映射到了宿主机哪里)
    • [Docker 容器互联](#Docker 容器互联)
      • [容器命名 --name](#容器命名 --name)
    • 新建网络-d(driver):这个网络用什么网络驱动创建"
    • [配置 DNS.给 Docker daemon 设置默认 DNS 服务器](#配置 DNS.给 Docker daemon 设置默认 DNS 服务器)
      • [把域名翻译成 IP 地址,这个东西就是 DNS。域名解析系统,把人容易记的名字,翻译成机器要用的地址](#把域名翻译成 IP 地址,这个东西就是 DNS。域名解析系统,把人容易记的名字,翻译成机器要用的地址)
      • [为什么要配置 DNS?遇到域名时,该去问谁来翻译?"](#为什么要配置 DNS?遇到域名时,该去问谁来翻译?”)
      • [为什么 Docker 里经常要配 DNS?不配置 DNS容器默认继承系统或 Docker 的默认解析方式。配置 DNS你是在明确告诉 Docker:以后容器解析域名,优先去问这几个 DNS 服务器。](#为什么 Docker 里经常要配 DNS?不配置 DNS容器默认继承系统或 Docker 的默认解析方式。配置 DNS你是在明确告诉 Docker:以后容器解析域名,优先去问这几个 DNS 服务器。)
      • dns服务器是谁配置的?怎么配置?电脑也没配置,仿佛自动可以解析
      • DNS服务器怎么实现
      • [docker run -it --rm ubuntu cat etc/resolv.conf.开一个临时 Ubuntu 容器,看看容器内部正在使用哪个 DNS 配置](#docker run -it --rm ubuntu cat etc/resolv.conf.开一个临时 Ubuntu 容器,看看容器内部正在使用哪个 DNS 配置)
        • [不是在 /etc/docker/daemon.json 文件 配置的吗?为什么看cat etc/resolv.conf?Docker 的容器 DNS 配置最终会映射到容器里的 resolver 配置文件](#不是在 /etc/docker/daemon.json 文件 配置的吗?为什么看cat etc/resolv.conf?Docker 的容器 DNS 配置最终会映射到容器里的 resolver 配置文件)
      • [为什么要给容器配置DNS?给容器配置 DNS,是为了让容器能正确地把域名解析成 IP,从而正常访问软件源、网站、接口和各种网络服务。](#为什么要给容器配置DNS?给容器配置 DNS,是为了让容器能正确地把域名解析成 IP,从而正常访问软件源、网站、接口和各种网络服务。)
      • 手动指定容器的配置
        • [docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu](#docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu)
          • [-h 主机名,给容器起名](#-h 主机名,给容器起名)
          • [--dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。](#--dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。)
            • [etc/hosts = 把"域名或主机名"手动对应到 IP 地址的本地表](#etc/hosts = 把“域名或主机名”手动对应到 IP 地址的本地表)
  • [Docker Dockerfile](#Docker Dockerfile)
    • [什么是 Dockerfile?文本文件,里面写的是:"怎么一步一步制作一个 Docker 镜像。"](#什么是 Dockerfile?文本文件,里面写的是:“怎么一步一步制作一个 Docker 镜像。”)
      • [RUN:用于执行后面跟着的命令行命令。shell 格式是"让 shell 帮你执行命令",exec 格式是"直接执行程序本身"。](#RUN:用于执行后面跟着的命令行命令。shell 格式是“让 shell 帮你执行命令”,exec 格式是“直接执行程序本身”。)
        • [shell格式,RUN <命令行命令>。# <命令行命令> 等同于,在终端操作的 shell 命令。](# <命令行命令> 等同于,在终端操作的 shell 命令。)
        • [exec 格式:RUN ["可执行文件", "参数1", "参数2"]](#exec 格式:RUN ["可执行文件", "参数1", "参数2"])
      • [Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。下载、使用、清理,尽量放在同一个 RUN 里完成](#Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。下载、使用、清理,尽量放在同一个 RUN 里完成)
      • [ docker build -t nginx:v3 . 使用当前目录中的 Dockerfile 和相关文件,构建一个名为 nginx:v3 的镜像](# docker build -t nginx:v3 . 使用当前目录中的 Dockerfile 和相关文件,构建一个名为 nginx:v3 的镜像)
        • [. 是构建上下文是当前目录。](#. 是构建上下文是当前目录。)
      • [上下文路径。Dockerfile 在构建时"能访问哪些本地文件"。只准用哪个目录里的材料做镜像](#上下文路径。Dockerfile 在构建时“能访问哪些本地文件”。只准用哪个目录里的材料做镜像)
    • 指令详解
      • COPY,从上下文目录中复制文件或者目录到容器里指定路径。
        • [如果目标以 / 开头,就是相对于镜像根目录的绝对路径;如果不以 / 开头,它就是相对于当前 WORKDIR 的相对路径。目标不存在时,Docker 会创建缺失的目录](#如果目标以 / 开头,就是相对于镜像根目录的绝对路径;如果不以 / 开头,它就是相对于当前 WORKDIR 的相对路径。目标不存在时,Docker 会创建缺失的目录)
        • [结尾有没有 / 很重要](#结尾有没有 / 很重要)
        • [copy默认从 build context 复制,也可以用 --from 从 build stage、named context 或另一个 image 复制](#copy默认从 build context 复制,也可以用 --from 从 build stage、named context 或另一个 image 复制)
      • ADD
        • [本地 tar 自动解压](#本地 tar 自动解压)
        • [ADD 支持从远程 URL 加文件,也支持把 Git 仓库作为源并克隆到镜像里的目标目录](#ADD 支持从远程 URL 加文件,也支持把 Git 仓库作为源并克隆到镜像里的目标目录)
      • CMD
        • [CMD <shell 命令>](#CMD <shell 命令>)
        • [CMD ["可执行文件", "参数1", "参数2"](exec form)](#CMD ["可执行文件", "参数1", "参数2"](exec form))
        • [CMD ["参数1", "参数2"] 给 ENTRYPOINT 提供默认参数的](#CMD ["参数1", "参数2"] 给 ENTRYPOINT 提供默认参数的)
        • [docker run 能覆盖 CMD](#docker run 能覆盖 CMD)
        • [多个 CMD 只有最后一个生效"](#多个 CMD 只有最后一个生效”)
      • [ENTRYPOINT 规定"容器启动时一定要执行的主程序".-entrypoint 覆盖 Dockerfile 里的 ENTRYPOINT](#ENTRYPOINT 规定“容器启动时一定要执行的主程序”.-entrypoint 覆盖 Dockerfile 里的 ENTRYPOINT)
      • [ENV 用来在镜像里设置环境变量。ENV 会持久保留到最终镜像和容器里](#ENV 用来在镜像里设置环境变量。ENV 会持久保留到最终镜像和容器里)
      • [ARG 只在构建过程中可用,默认不会成为镜像里的环境变量,也不会自动出现在容器里](#ARG 只在构建过程中可用,默认不会成为镜像里的环境变量,也不会自动出现在容器里)
      • [VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去](#VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去)
        • [容器里的文件,默认是跟着容器走的.重启容器:容器还是那个容器,里面原来写进去的文件通常还在. 删除容器:那个容器本身没了,写在它自己里面的数据通常也就没了](#容器里的文件,默认是跟着容器走的.重启容器:容器还是那个容器,里面原来写进去的文件通常还在. 删除容器:那个容器本身没了,写在它自己里面的数据通常也就没了)
        • [VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去](#VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去)
          • [挂到宿主机自己指定的目录。宿主机目录:容器目录 → 你自己指定挂到本机哪里](#挂到宿主机自己指定的目录。宿主机目录:容器目录 → 你自己指定挂到本机哪里)
          • [挂到 Docker 自己管理的一块存储。这叫 volume。你不给宿主机具体目录,只给一个卷名。卷名:容器目录 → 交给 Docker 管,宿主机具体位置你通常不用管。docker volume ls 列出docker 管理的卷](#挂到 Docker 自己管理的一块存储。这叫 volume。你不给宿主机具体目录,只给一个卷名。卷名:容器目录 → 交给 Docker 管,宿主机具体位置你通常不用管。docker volume ls 列出docker 管理的卷)
        • [VOLUME /data,它只是在镜像里声明:容器里的 /data 是个适合挂外部存储的位置。真正"外部存储挂哪里",是在 docker run 时决定的](#VOLUME /data,它只是在镜像里声明:容器里的 /data 是个适合挂外部存储的位置。真正“外部存储挂哪里”,是在 docker run 时决定的)
        • 忘了挂载,也会自动挂匿名卷"
        • [docker run -v 能"修改挂载点](#docker run -v 能“修改挂载点)
        • [镜像运行时,Docker 会为 /myvol 创建新 volume,并把镜像里这个位置原本已有的数据初始化到新 volume 里](#镜像运行时,Docker 会为 /myvol 创建新 volume,并把镜像里这个位置原本已有的数据初始化到新 volume 里)
      • [EXPOSE 仅仅只是声明端口](#EXPOSE 仅仅只是声明端口)
      • [WORKDIR:WORKDIR 会为后续的 RUN、CMD、ENTRYPOINT、COPY、ADD 设置工作目录;如果目录不存在,会自动创建。给后面的命令指定"默认当前目录"](#WORKDIR:WORKDIR 会为后续的 RUN、CMD、ENTRYPOINT、COPY、ADD 设置工作目录;如果目录不存在,会自动创建。给后面的命令指定“默认当前目录”)
        • [RUN 文件系统变化会保留,shell 的"当前状态"不会保留。](#RUN 文件系统变化会保留,shell 的“当前状态”不会保留。)
        • [WORKDIR 可以写多次,而且相对路径会基于前一个 WORKDIR 继续拼。绝对路径,直接重设](#WORKDIR 可以写多次,而且相对路径会基于前一个 WORKDIR 继续拼。绝对路径,直接重设)
      • HEALTHCHECK
      • [ONBUILD 先埋一个触发器,现在不执行,等别人拿这个镜像当基础镜像时再执行](#ONBUILD 先埋一个触发器,现在不执行,等别人拿这个镜像当基础镜像时再执行)
      • [LABEL 给镜像贴"说明标签"](#LABEL 给镜像贴“说明标签”)
      • [STOPSIGNAL:设置"当 Docker 要停止容器时,先发给容器主进程的那个信号"](#STOPSIGNAL:设置“当 Docker 要停止容器时,先发给容器主进程的那个信号”)

docker 容器连接

端口映射 -P/-p

-P:镜像里声明的端口自动映射到宿主机的随机端口

-P:把镜像里通过 EXPOSE 声明的所有端口,自动发布到宿主机的随机高位端口。Docker 官方也区分了 EXPOSE 和发布端口:EXPOSE 只是声明,真正发布到宿主机要靠 -p 或 -P

-p :[宿主机IP:]宿主机端口:容器端口[/协议]

宿主机IP:\]宿主机端口:容器端口\[/协议

如果不写宿主机 IP,Docker 默认会把端口发布到 所有网络接口,也就是通常看到的 0.0.0.0;如果写了 127.0.0.1,那就只有宿主机自己能访问;如果写了 /udp,那发布的就是 UDP 端口,不再是默认的 TCP。
TCP 和 UDP 是两套不同的端口映射。 也就是说,宿主机的 5000/tcp 和 5000/udp 不是同一个东西。




docker port 容器名:查"容器端口"对应到了"宿主机哪个地址和端口"

docker port 容器名 查看这个容器所有已经发布的端口映射

docker port 容器名 5000/docker port 容器名 5000/tcp.只看容器内部这个端口映射到了宿主机哪里

Docker 容器互联

容器命名 --name

新建网络-d(driver):这个网络用什么网络驱动创建"

-d 是 --driver,意思是:创建网络时,指定用哪一种网络驱动(network driver)。这个网络用什么网络驱动创建"。

Docker 官方说明,docker network create 里内置常见驱动有 bridge 和 overlay;如果你不写 --driver,默认会创建 bridge 网络。

bridge:一台机器里的容器网络

overlay:多台机器之间的容器网络


bridge:一台机器内部,给几个容器拉了一个局域网。同一台电脑里的容器互相连网


overlay:跨多台机器,把各台机器上的容器接成一个"虚拟大局域网"。跨多台电脑,把容器接到一个大网里


docker network create -d bridge test-net。在当前这台 Docker 主机上,建一个给容器用的本地桥接网络 test-net

配置 DNS.给 Docker daemon 设置默认 DNS 服务器

把域名翻译成 IP 地址,这个东西就是 DNS。域名解析系统,把人容易记的名字,翻译成机器要用的地址

DNS 就是把域名翻译成 IP 地址的系统;配置 DNS,就是指定"找谁来做这个翻译"。

配置 DNS 里的 IP,不是你要访问的目标地址,而是你拿来"问路"的服务器地址。

输入域名 → 问 DNS → 拿到目标 IP → 再访问网站。


为什么要配置 DNS?遇到域名时,该去问谁来翻译?"

为什么 Docker 里经常要配 DNS?不配置 DNS容器默认继承系统或 Docker 的默认解析方式。配置 DNS你是在明确告诉 Docker:以后容器解析域名,优先去问这几个 DNS 服务器。





dns服务器是谁配置的?怎么配置?电脑也没配置,仿佛自动可以解析

第一层:路由器/运营商在配
路由器,"网络总管"



电脑 → 路由器 → 运营商网络 → 互联网 → 网站服务器




第二层:公司网络管理员在配
第三层:自己手动配

DNS服务器怎么实现

DNS 服务器的实现,本质上就是一个维护"域名记录"的网络服务:它要么自己保存答案,要么按分层规则替你继续询问,最后把域名对应的结果返回给客户端。











docker run -it --rm ubuntu cat etc/resolv.conf.开一个临时 Ubuntu 容器,看看容器内部正在使用哪个 DNS 配置

-it

给你一个交互终端环境。

不过这条命令里其实不是必须,因为 cat 不是交互程序,不加通常也能跑。

--rm

容器运行结束后自动删除。

所以这是一个"一次性临时容器"。
启动一个临时 Ubuntu 容器

在容器里执行 cat etc/resolv.conf

把文件内容输出到终端

命令结束,容器自动删除

不是在 /etc/docker/daemon.json 文件 配置的吗?为什么看cat etc/resolv.conf?Docker 的容器 DNS 配置最终会映射到容器里的 resolver 配置文件

"因为 daemon.json 是配置来源,resolv.conf 是容器里的实际结果,所以要看结果文件来验证配置是否生效。"



为什么要给容器配置DNS?给容器配置 DNS,是为了让容器能正确地把域名解析成 IP,从而正常访问软件源、网站、接口和各种网络服务。



手动指定容器的配置

docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu

临时开一个 Ubuntu 容器,主机名叫 host_ubuntu,查域名优先问 114.114.114.114,短主机名默认补 .test.com
--dns 解决的是:问谁查地址

--dns-search 解决的是:遇到短名字时,自动补什么后缀。自动补域名后缀

-h 主机名,给容器起名


--dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
etc/hosts = 把"域名或主机名"手动对应到 IP 地址的本地表




Docker Dockerfile

什么是 Dockerfile?文本文件,里面写的是:"怎么一步一步制作一个 Docker 镜像。"

它是干什么的

它告诉 Docker:

以哪个基础镜像开始

要装哪些软件

要复制哪些文件进去

工作目录设在哪

容器启动时执行什么命令




RUN:用于执行后面跟着的命令行命令。shell 格式是"让 shell 帮你执行命令",exec 格式是"直接执行程序本身"。

shell格式,RUN <命令行命令>。# <命令行命令> 等同于,在终端操作的 shell 命令。


exec 格式:RUN ["可执行文件", "参数1", "参数2"]

exec 格式里第一个元素,一般就是要直接运行的"可执行文件"或命令。

exec 格式里,第一个元素就是要直接启动的程序,后面的元素都是传给它的参数。




Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。下载、使用、清理,尽量放在同一个 RUN 里完成






$ docker build -t nginx:v3 . 使用当前目录中的 Dockerfile 和相关文件,构建一个名为 nginx:v3 的镜像

-t nginx:v3

给构建出来的镜像打标签。

这里:

nginx 是镜像名

v3 是标签 tag

. 是构建上下文是当前目录。


上下文路径。Dockerfile 在构建时"能访问哪些本地文件"。只准用哪个目录里的材料做镜像


为什么要有这个概念?





指令详解

COPY,从上下文目录中复制文件或者目录到容器里指定路径。

COPY = 从构建可访问的来源里拿文件,复制到当前镜像阶段里;源路径看 context,目标路径看 / 和 WORKDIR,目标不存在会自动建,结尾 / 会影响它被当成文件还是目录。

如果目标以 / 开头,就是相对于镜像根目录的绝对路径;如果不以 / 开头,它就是相对于当前 WORKDIR 的相对路径。目标不存在时,Docker 会创建缺失的目录




结尾有没有 / 很重要
copy默认从 build context 复制,也可以用 --from 从 build stage、named context 或另一个 image 复制




ADD

ADD 比 COPY 多了一些"额外能力",但正因为它会偷偷多做事,所以平时更推荐用 COPY。 Docker 官方现在的定义是:ADD 除了能从 build context 复制本地文件/目录,还能直接处理 远程 URL 和 Git 仓库;而 COPY 更"单纯",主要就是复制文件

本地 tar 自动解压



ADD 支持从远程 URL 加文件,也支持把 Git 仓库作为源并克隆到镜像里的目标目录


CMD

CMD 是给容器设置"默认启动命令"。

如果你运行容器时没有额外指定命令,就执行它;如果你在 docker run 后面又写了别的命令,通常会把它覆盖掉。Docker 官方对 CMD 的定义就是:为执行中的容器提供默认命令,且一个 Dockerfile 里只有最后一个 CMD 生效。

CMD <shell 命令>
CMD ["可执行文件", "参数1", "参数2"](exec form)
CMD ["参数1", "参数2"] 给 ENTRYPOINT 提供默认参数的
docker run 能覆盖 CMD


多个 CMD 只有最后一个生效"

ENTRYPOINT 规定"容器启动时一定要执行的主程序".-entrypoint 覆盖 Dockerfile 里的 ENTRYPOINT

ENTRYPOINT 用来规定"容器启动时一定要执行的主程序",而 CMD 更像是给这个主程序提供"默认参数"。 Docker 官方也是这么描述两者配合关系的:ENTRYPOINT 更适合把容器当成一个可执行程序来用,CMD 则适合给 ENTRYPOINT 提供默认参数;docker run 镜像 参数... 会覆盖 CMD,并把这些参数追加到 exec 形式的 ENTRYPOINT 后面




菜鸟应该是写错了

ENV 用来在镜像里设置环境变量。ENV 会持久保留到最终镜像和容器里

ENV 用来在镜像里设置环境变量。

设置以后,这个变量不仅能在后续的 RUN、CMD、ENTRYPOINT 等指令里用到,而且将来用这个镜像启动出来的容器里也会保留下来。




ARG 只在构建过程中可用,默认不会成为镜像里的环境变量,也不会自动出现在容器里

ARG 就是 构建时参数:它主要给 Dockerfile 的构建过程用,可以让你在 docker build 时传不同的值;但它不会像

ENV 那样自动变成运行中容器里的环境变量



VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去

"挂外部存储"就是把容器里的某个目录,接到容器外面去。外面可以是你电脑上的一个真实目录,也可以是 Docker 帮你管理的一块数据区

容器里的文件,默认是跟着容器走的.重启容器:容器还是那个容器,里面原来写进去的文件通常还在. 删除容器:那个容器本身没了,写在它自己里面的数据通常也就没了




VOLUME 这个目录里的数据,不要只放在容器自己身上,最好单独存出去



"挂外部存储"就是把容器里的某个目录,接到容器外面去。外面可以是你电脑上的一个真实目录,也可以是 Docker 帮你管理的一块数据区

挂到宿主机自己指定的目录。宿主机目录:容器目录 → 你自己指定挂到本机哪里
挂到 Docker 自己管理的一块存储。这叫 volume。你不给宿主机具体目录,只给一个卷名。卷名:容器目录 → 交给 Docker 管,宿主机具体位置你通常不用管。docker volume ls 列出docker 管理的卷
VOLUME /data,它只是在镜像里声明:容器里的 /data 是个适合挂外部存储的位置。真正"外部存储挂哪里",是在 docker run 时决定的


忘了挂载,也会自动挂匿名卷"
docker run -v 能"修改挂载点
镜像运行时,Docker 会为 /myvol 创建新 volume,并把镜像里这个位置原本已有的数据初始化到新 volume 里

EXPOSE 仅仅只是声明端口


WORKDIR:WORKDIR 会为后续的 RUN、CMD、ENTRYPOINT、COPY、ADD 设置工作目录;如果目录不存在,会自动创建。给后面的命令指定"默认当前目录"

RUN 文件系统变化会保留,shell 的"当前状态"不会保留。

RUN 的文件改动会保留到下一层,所以你 RUN mkdir /app 创建的目录,后面通常也还在。

但是你在某个 RUN 里临时 cd 到别的目录,这个"当前目录状态"不会自动延续到下一个 RUN





WORKDIR 可以写多次,而且相对路径会基于前一个 WORKDIR 继续拼。绝对路径,直接重设


HEALTHCHECK




ONBUILD 先埋一个触发器,现在不执行,等别人拿这个镜像当基础镜像时再执行

ONBUILD 是在当前 Dockerfile 构建完成之后,当该镜像被别的 Dockerfile FROM 时才执行






LABEL 给镜像贴"说明标签"



STOPSIGNAL:设置"当 Docker 要停止容器时,先发给容器主进程的那个信号"


信号(signal)就是操作系统发给进程的一种"通知"






相关推荐
同元软控2 小时前
同元软控“电力能源系统数智运维解决方案”入选2025年江苏省信息技术应用创新典型解决方案
运维·数据库·能源
xiaokangzhe2 小时前
Keepalived 高可用与负载均衡
运维·负载均衡
Harvy_没救了2 小时前
Ansible 学习指南
linux·运维·服务器·ansible
小连~2 小时前
Docker
docker·容器
学Linux的语莫2 小时前
Linux环境中anaconda 的安装与环境配置
linux·运维·服务器
Elastic 中国社区官方博客2 小时前
多大才算太大?Elasticsearch 容量规划最佳实践
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索
中海德--陈顺真2 小时前
西门子直流调速器维修时,需注意点
运维·维修
rockmelodies3 小时前
用 Python 实现 Docker 镜像批量推送(带进度条)
python·docker·eureka
ITKEY_3 小时前
linux edge 强制使用x11运行
linux·运维·edge