文章目录
- Docker 网络
- 一、 网络基础
- 二、 Docker网络模式
- 三、 Dockerfile 构建镜像
-
- 3.1、 FROM:指定基础镜像,必须为第一个命令
- 3.2、 MAINTAINER: 维护者信息
- 3.3、 RUN:构建镜像时执行的命令
- 3.4、 ADD:将本地文件添加到容器中
- 3.5、 COPY:功能类似 ADD,但是是不会自动解压文件,也不能访问网络资源
- 3.6、 CMD:构建容器后调用,也就是在容器启动时才进行调用
- 3.7、 LABEL:用于为镜像添加元数据
- 3.8、 ENV:设置环境变量
- 3.9、 EXPOSE:指定于外界交互的端口
- 3.10、 VOLUME:用于指定持久化目录
- 3.11、 WORKDIR:工作目录,类似于 cd 命令
- 3.12、 ARG:用于指定传递给构建运行时的变量
- 3.13、 ONBUILD:用于设置镜像触发器
- 3.14、 Dockerfile 构建镜像案例
- 总结
- 四、 Docker Compose
Docker 网络
Docker 本身的技术依赖于 Linux 内核虚拟化技术的发展。所以 Docker 对 Linux 内核的特性有很强的依赖。 本章主要介绍 Docker 所使用的 Linux 网络技术
一、 网络基础
其中 Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由。
1.1、 网络名称空间
为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace),这些 独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行 网络通信,就好像两个“平行宇宙”。通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环 境,而 Docker 正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。在 Linux 的网络命名空间 内可以有自己独立的 Iptables 来转发、NAT 及 IP 包过滤等功能。
Linux 的网络协议栈是十分复杂的,为了支持独立的协议栈,相关的这些全局变量都必须修改为协议栈私有。 最好的办法就是让这些全局变量成为一个 Net Namespace 变量的成员,然后为了协议栈的函数调用加入一个 Namespace 参数。这就是 Linux 网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。当然, 通常的物理网络设备只能关联到 root 这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空 间中,而且可以在这些名称空间之间移动
1.2、 创建一个命名空间
ip netns add test01(命名空间名)
ip netns add test02(命名空间名)
ip netns list : 查看创建过的命名空间
1.2.1、 Veth 设备
引入 Veth 设备对是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间链接起 来。由于要连接的两个网络命名空间,所以 Veth 设备是成对出现的,很像一对以太网卡,并且中间有一根直连 的网线。既然是一对网卡,那么我们将其中一端称为另一端的 peer。在 Veth 设备的一端发送数据时,它会将数 据直接发送到另一端,并触发另一端的接收操作
1.2.2、 Veth 设备操作
1.2.2.1、 创建 Veth 设备对
ip link add veth(Veth名称) type veth peer name veth001(Veth名称)
生成了两个 veth 设备, 互为对方的 peer ! ! ! !
1.2.2.2、 查看 Veth 设备对
ip link list
ip link show
ip a
1.2.2.3、 将 Veth设备对绑定命名空间
# 绑定命名空间
ip link set veth001 netns test01
# 如何进入命名空间
ip netns exec test01(命名空间) bash
1.2.2.4、 给 Veth 分配 IP
# 设置 IP
ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001
# 为对端 Veth 设备设置 IP
ip addr add 172.16.0.112/20 dev veth
# 重启veth设备对
ip netns exec test01 ip link set dev veth001 up/down
ip link set dev veth down
ip link set dev veth up
# ping
ping 172.16.0.111
注意!!! 设置IP之后重启 veth 设备对,否则会 ping 不通 !!!
1.2.2.5、 查看对端 Veth 设备
ip netns exec test01 ethtool -S veth001
1.2.2.6、 命名空间的 veth 设备对删除 IP
ip addr del 172.16.0.112/20 dev veth1
ip netns exec test01 ip addr del 172.16.0.111/20 dev veth2
二、 Docker网络模式
Docker 使用 Linux 桥接的方式,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会 根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。 因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker 网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外 部网络无法通过直接Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到 宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主 机 IP]:[容器端口]访问容器
2.1、 HOST 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用 host 模式的容器可以直接使用宿主机的 IP 地址与外界通信,容器内部的服务端口也可以使用宿主机的 端口,不需要进行 NAT,host 最大的优势就是网络性能比较好,但是 docker host 上已经使用的端口就不能再 用了,网络的隔离性不好。
使用宿主主机的网卡
docker run --network host [镜像名称|ID]
2.2、 Containe 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。 新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个 容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
共享一个容器的网络,几个容器使用container指向同一个容器的时候,共用一个网卡。
docker run -d --network "container:[共享容器名称]" nginx
2.3、 none 模式
使用 none 模式,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络 配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。
这种网络模式下容器只有 lo 回环网络,没有其他网卡。none 模式可以在容器创建时通过–network=none 来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
不为容器提供任何网络
docker run -d --network none 镜像[名称|ID]
2.4、 bridge 模式
当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机