Docker网络

目录

Docker网络

外部访问容器

映射所有接口地址

映射到指定地址的指定端口

映射到指定地址的任意端口

查看映射端口配置

容器互联

新建网络

连接容器

配置DNS

Docker的网络模式

Bridge 模式

Host 模式

None 模式

Container 模式

Docker高级网络配置

快速配置

容器访问控制

容器访问外部网络

容器之间访问

访问所有端口

访问指定端口

端口映射实现

容器访问外部实现

外部访问容器实现

配置docker0网桥

自定义网桥

编辑网络配置文件


Docker网络

外部访问容器

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过-P或-p参数来指定端口映射。

当使用-P标记时,Docker会随机映射一个端口到内部容器开放的网络端口。 使用docker container ls可以看到,本地主机的 32768 被映射到了容器的 80 端口。此时访问本机的 32768 端口即可访问容器内 NGINX 默认页面。

映射所有接口地址

使用hostPort:containerPort格式本地的 80 端口映射到容器的 80 端口,此时默认会绑定本地所有接口上的所有地址。

docker run -d -p 80:80 nginx:alpine

映射到指定地址的指定端口

使用ip:hostPort:containerPort格式指定映射使用一个特定地址,例如:

docker run -d -p 127.0.0.1:80:80 nginx:alpine

映射到指定地址的任意端口

使用ip::containerPort绑定localhost的任意端口到容器的80端口,本地主机会自动分配一个端口,例如:

docker run -d -p 127.0.0.1::80 nginx:alpine

使用udp标记来指定udp端口

docker run -d -p 127.0.0.1:80:80/udp nginx:alpine

查看映射端口配置

使用docker port来查看当前映射的端口配置,也可以查看到绑定的地址

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

-p标记可以多次使用来绑定多个端口

docker run -d \
    -p 80:80 \
    -p 443:443 \
    nginx:alpine

容器互联

新建网络

docker network create -d bridge [net_name]

-d参数指定Docker网络类型,有bridge overlay,其中overlay网络类型用于Swarm mode

连接容器

运行一个容器并连接到新建的my_net网络

docker run -it --rm --name busybox1 --network my_net busybox sh

打开新的终端,再运行一个容器并加入到 my_net网络

再打开一个新的终端查看容器信息

通过 ping来证明busybox1容器和busybox2容器建立了互联关系

如果有多个容器之间需要互相连接,推荐使用DockerCompose

配置DNS

Docker容器的 DNS 配置通过 /etc/resolv.conf文件立刻得到更新

配置全部容器的 DNS ,也可以在 /etc/docker/daemon.json 文件中增加以下内容来设置,每次启动的容器 DNS 自动配置为 114.114.114.114 和8.8.8.8。

{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

使用以下命令来证明其已经生效

docker run -it --rm ubuntu:18.04  cat etc/resolv.conf

如果想要手动指定容器的配置,可以在使用docker run命令启动容器时加入如下参数:

  • -h HOSTNAME或者--hostname=HOSTNAME设定容器的主机名,它会被写到容器内的/etc/hostname 和 /etc/hosts。但它在容器外部看不到,既不会在docker container ls中显示,也不会在其他的容器的/etc/hosts看到
  • --dns=IP_ADDRESS添加 DNS 服务器到容器的/etc/resolv.conf中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名
  • --dns-search=DOMAIN设定容器的搜索域,当设定搜索域为.example.com时,在搜索一个名为host的主机时,DNS 不仅搜索 host,还会搜索host.example.com
  • 如果在容器启动时没有指定最后两个参数,Docker会默认用主机上的/etc/resolv.conf来配置容器

Docker的网络模式

查看网络

docker network ls

网络模式简介
Bridge为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,默认为该模式。
Host容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
None容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP 等。
Container新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。

Bridge 模式

在创建容器时通过参数 --net bridge 或者 --network bridge 指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上,附加在其上的任何网卡之间都能自动转发数据包。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从docker0子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过brctl show命令查看

守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名

同时,守护进程还会从网桥 docker0 的私有地址空间中分配一个 IP 地址和子网给该容器,并设置 docker0 的 IP 地址为容器的默认网关

查看所有 bridge 网络模式下的容器

docker network inspect bridge

Host 模式

host 网络模式需要在创建容器时通过参数--net host或者--network host指定;

采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;

host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

img

None 模式

  • none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数--net none或者--network none指定;
  • none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。

Container 模式

  • Container 网络模式是 Docker 中一种较为特别的网络的模式。在创建容器时通过参数 --net container:已运行的容器名称|ID 或者 --network container:已运行的容器名称|ID 指定
  • 处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信

Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。

Docker高级网络配置

快速配置

Docker 网络相关的命令列表,其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效。

  • -b BRIDGE 或 --bridge=BRIDGE 指定容器挂载的网桥
  • --bip=CIDR定制 docker0 的掩码
  • -H SOCKET... 或 --host=SOCKET... Docker 服务端接收命令的通道
  • --icc=true|false 是否支持容器之间进行通信
  • --ip-forward=true|false 请看下文容器之间的通信
  • --iptables=true|false 是否允许 Docker 添加 iptables 规则
  • --mtu=BYTES 容器网络中的 MTU

下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在 Docker服务启动的时候指定则会成为默认值,后面执行 docker run 时可以覆盖设置的默认值。

  • --dns=IP_ADDRESS... 使用指定的DNS服务器
  • --dns-search=DOMAIN... 指定DNS搜索域

这些选项只有在 docker run 执行时使用,因为它是针对容器的特性内容。

  • -h HOSTNAME 或 --hostname=HOSTNAME 配置容器主机名
  • --link=CONTAINER_NAME:ALIAS 添加到另一个容器的连接
  • --net=bridge|none|container:NAME_or_ID|host 配置容器的桥接模式
  • -p SPEC 或 --publish=SPEC` 映射容器端口到宿主主机
  • -P or --publish-all=true|false 映射容器所有端口到宿主主机

容器访问控制

通过 Linux 上的 iptables 防火墙来进行管理和实现。iptables 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。

容器访问外部网络

容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。

sysctl net.ipv4.ip_forward

如果为 0,说明没有开启转发,则需要手动打开。

sysctl -w net.ipv4.ip_forward=1

如果在启动 Docker 服务的时候设定 --ip-forward=true, Docker 就会自动设定系统的 ip_forward 参数为 1。

容器之间访问

容器之间相互访问,需要两方面的支持。

  • 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 docker0 网桥上。
  • 本地系统的防火墙软件 -- iptables 是否允许通过。

访问所有端口

  • 当启动 Docker 服务(即 dockerd)的时候,默认会添加一条转发策略到本地主机 iptables 的 FORWARD 链上。策略为通过(ACCEPT)还是禁止(DROP)取决于配置--icc=true(缺省值)还是 --icc=false。当然,如果手动指定 --iptables=false 则不会添加 iptables 规则。
  • 默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在 /etc/docker/daemon.json 文件中配置 {"icc": false} 来禁止它。

访问指定端口

在通过 -icc=false 关闭网络访问后,还可以通过 --link=CONTAINER_NAME:ALIAS 选项来访问容器的开放端口。

启动容器(docker run)时使用 --link=CONTAINER_NAME:ALIAS 选项。Docker 会在 iptable 中为 两个容器分别添加一条 ACCEPT 规则,允许相互访问开放的端口(取决于 Dockerfile 中的 EXPOSE 指令)。 当添加了 --link=CONTAINER_NAME:ALIAS 选项后,添加了 iptables 规则。

端口映射实现

默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。

容器访问外部实现

容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址。这是使用 iptables 的源地址伪装操作实现的。

查看主机的 NAT 规则。

sudo iptables -t nat -nL

上述规则将所有源地址在 172.17.0.0/16 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。

外部访问容器实现

容器允许外部访问,可以在 docker run 时候通过 -p 或 -P 参数来启用。

可以通过 -p IP:host_port:container_port 或 -p IP::port 来指定允许访问容器的主机上的 IP、接口等

如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容

{
  "ip": "0.0.0.0"
}

配置docker0网桥

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。

  • --bip=CIDR IP 地址加掩码格式,例如 192.168.1.5/24
  • --mtu=BYTES 覆盖默认的 Docker mtu 配置

也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。

由于目前 Docker 网桥是 Linux 网桥,用户可以使用 brctl show 来查看网桥和端口连接信息。

sudo apt-get install bridge-utils
sudo brctl show

每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 docker0 接口的 IP 作为所有容器的默认网关。

自定义网桥

在启动 Docker 服务的时候,使用 -b BRIDGE--bridge=BRIDGE 来指定使用的网桥。

如果服务已经运行,那需要先停止服务,并删除旧的网桥。

sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0

创建一个网桥 bridge0

sudo brctl addbr bridge0
sudo ip addr add 192.168.5.1/24 dev bridge0
sudo ip link set dev bridge0 up

确认网桥创建并启动

ip addr show bridge0

在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。

{
  "bridge": "bridge0",
}

编辑网络配置文件

Docker 1.2.0 开始支持在运行中的容器里编辑 /etc/hosts, /etc/hostname 和 /etc/resolv.conf 文件。 但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被 docker commit 提交。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值