ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

docker网络

2022-04-13 16:35:23  阅读:117  来源: 互联网

标签:容器 network 自定义 -- 网络 docker


Docker网络概念

网络驱动

Docker 网络子系统使用可插拔的驱动,默认情况下有多个驱动程序,并提供核心联网功能。

  1. bridge:桥接网络,这是默认的网络驱动程序(不指定驱动程序创建的容器默认是bridge驱动)。
  2. host:主机网络。消除容器和主机的网络隔离,直接使用主机的网络。
  3. overlay:覆盖网络。可以将多个Docker守护进程连接,实现跨主机容器通讯(swarm集群)。
  4. macvlan:将MAC地址分配给容器,使容器作为网络上的物理设备。不通过Docker主机网络栈进行路由,直接通过MAC地址路由到容器。
  5. none:表示关闭容器的所有网络连接。常与自定义网络驱动一起使用,不适用于swarm。
  6. 网络插件:可以通过Docker安装和使用第三方网络插件。

Docker网络驱动选用原则

  1. bridge桥接网络:最适合用于同一个Docker主机上运行的多个容器之间需要通信的场景。(单主机)
  2. host主机网络:最适用于当网络栈不能与Docker主机隔离,而容器的其他方面需要被隔离的场景。(解除容器和主机隔离)
  3. overlay网络:适用于不同Docker主机上运行的容器需要通信的场景,或者多个应用程序通过Swarm集群服务一起工作的场景。(多主机、集群)
  4. macvlan网络:适用于从虚拟机迁移过来的场景,或者容器需要像网络上的物理机一样,拥有独立MAC地址的场景。(容器需要mac)
  5. 第三方网络插件适用于将Docker与专用网络栈进行集成的场景。(订制化)

容器的网络模式

bridge模式

桥接网络分为默认桥接网络用户自定义桥接网络两种类型。

桥接网络用于同(单)主机运行的容器间通信。

实现原理:桥接网络使用软件网桥,让连接到同一桥接网络的容器可以通信,没连接该网桥的容器被隔离。

工作流程:Docker守护进程启动,会在主机上创建一个名为 docker0 的虚拟网桥,启动容器时如果没有特别指定,自动连接到这个虚拟网桥。

[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:b2:81:22:9d  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Docker 守护进程为每个启动的容器创建一个 VETH对设备(总是成对出现,组成数据通道)。

VETH对是直接连接的一对虚拟网络接口,一个接口设置为新创建容器的接口(位于容器的网络名称空间中);另一个接口连接到虚拟网桥docker0(位于Docker的网络名称空间中)。

host模式

host模式的容器使用host驱动,直接连接Docker主机网络栈。实质:关闭 Docker 网络,让容器直接使用主机操作系统的网络。

host模式没有为容器创建一个隔离的网络环境,容器没有隔离的网络名称空间,也不会获得一个独立的网络名称空间,而是和Docker主机共用一个网络名称空间

容器和主机在同一个网络中,使用主机的物理网络接口,没有独立的IP地址,直接使用主机的IP地址和端口。

由于主机名、地址都一样,因此同一主机上的容器要做好协调。各容器通过端口来进行区分。

container模式

Docker中一种较为特别的网络模式,主要用于容器和容器直接频繁交流的情况。

特点:

  1. 该模式指定新建的容器和现有的一个容器共享网络名称空间。
  2. 新创建的容器和一个现有的指定容器共享IP地址、端口范围,不创建自己的网络接口、IP地址。
  3. 两个容器间网络不隔离,进程可通过回环网络进行通信。
  4. 这两个容器和主机和其他容器存在网络隔离。

none模式

none模式将容器放置在它自己的网络栈中,但是并不进行任何配置,实际上关闭了容器的网络功能

特性:none模式,容器有自己的网络名称空间,但未进行任何网络配置,未构建任何网络环境,容器内部只能使用回环网络接口(127.0.0.1)。

可用场景:

  1. 有些容器并不需要网络,例如只需要写入磁盘卷的批处理任务。
  2. 安全性要求高并且不需要联网的应用可以使用none模式。
  3. 要创建自定义网络

自定义模式

管理员可以使用Docker网络驱动(bridge、overlay、macvlan)或第三方网络驱动插件创建一个自定义的网络,然后将多个容器连接到同一个自定义网络。

特点:

  1. 连接到用户自定义网络的容器,可以使用IP地址或名称相互通信。
  2. 可以根据需要创建任意数量的自定义网络。
  3. 可以在任何时间将容器连接到这些网络。
  4. 对运行中的容器,可连接、断开自定义网络,无须重启容器。

用户自定义桥接网络(自定义网络使用bridge网络驱动):单机环境常用。生产环境推荐使用。

生产环境不推荐使用默认桥接网络,推荐使用用户自定义桥接网络,原因在以下区别:

  1. 用户自定义桥接网络能提供容器化应用程序之间更好的隔离和互操作性。如果在默认桥接网络上运行应用栈,则Docker主机需要通过其他方式来限制对端口的访问。
  2. 用户自定义桥接网络提供容器之间自动DNS解析功能,可以通过名称或别名互相访问。而默认桥接网络上的容器只能通过IP地址互相访问。
  3. 容器可以在运行时与用户自定义网络连接和断开。要断开与默认桥接网络的连接,需要停止容器并使用不同的网络选项重新创建该容器。
  4. 每个用户可通过自定义网络创建一个可配置的网桥。而默认桥接网络会自动穿件一个名为docker0的虚拟网桥。
  5. 用户自定义网络中所连接容器不能共享环境变量,不过有更好的方式实现共享环境变量(docker卷挂载、compose文件定义、集群)。默认桥接网络中所连接的容器共享环境变量。

传统容器连接

创建容器时使用--link选项可以在容器之间建立连接,这是Docker传统的容器互联解决方案。

特性:

  1. 这种连接方式用来将多个容器连接在一起,并在容器之间发送连接信息。
  2. 当容器被连接时,在源容器接收容器 之间建立一个安全通道,关于源容器的信息能够被发送到接收容器,让接收容器可以访问源容器所指定的数据。

为容器设置自定义名称的好处:

  • 表示特定用途的名称更易记忆,如将一个Web应用的容器命名为web。
  • 便于Docker通过该名称引用其他容器,弥补默认桥接网络不支持容器名称解析的不足
# 语法
[root@localhost ~]# docker create --help
Usage:  docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
Create a new container
Options:
  --link list                      Add link to another container       # 添加连接到另一个容器

# 案例
docker run -dit --name alpine2 --link alpine1:alp alpine ash

容器访问外部网络

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

使用bridge模式(默认桥接网络)的容器通过NAT方式实现外部访问,具体通过iptables(Linux的包过滤防火墙)的源地址伪装操作实现。

iptables源地址伪装:容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址(即docker0地址)。

查看主机的 NAT 规则:

[root@localhost ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 142 packets, 31842 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    1    52 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 140 packets, 31384 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 4 packets, 288 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 4 packets, 288 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0             《————这一条规则将所有源地址在 172.17.0.0/16 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。
	                                                                                                MASQUERADE 相比传统 SNAT 的好处是它能动态从网卡获取地址。

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0 

容器网络配置

设置容器网络连接

容器启动时,可以使用 --network 选项设置容器要连接的网络,即网络模式。

none:容器为none模式,容器不使用任何网络连接,能完全禁用网络连接。

bridge:容器为bridge模式,连接到默认桥接网络,也是默认设置。

host:容器为host模式,使用主机网络栈。

container:容器为container模式,容器使用某一个容器(通过id或name来标识)的网络栈。

网络名or网络id:容器连接自定义网络,可使用自定义网络的名称或id。

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
      --network network                Connect a container to a network        # 连接容器到网络中

# 案例
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9b3f5f5076b9   bridge    bridge    local
76d9e06a3606   host      host      local
9f44873071f4   none      null      local
[root@localhost ~]# docker run --network none -dit --name centos-test centos /bin/bash
24110a1ca4da0f6d7659d7d2e8a1f57a8d980031ab54ac4730a3b89e44679e46
[root@localhost ~]# docker inspect --format='{{json .HostConfig.NetworkMode}}'  24110a1ca4da 
"none"

容器添加网络作用域别名

容器在网络作用域中允许有别名,别名在所在网络中可以直接访问。使用 --network-alias 选项指定容器在网络中的别名。

注意:网络作用域别名只支持用户自定义的网络。

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
      --network-alias list             Add network-scoped alias for the container   # 给容器添加网络作用域别名

# 失败案例
[root@localhost ~]# docker run -d -p 80:80 --name testweb --network host --network-alias websrv centos
docker: network-scoped aliases are only supported for user-defined networks.       # 网络作用域别名只支持用户自定义的网络

# 案例
[root@localhost ~]# docker network create --driver bridge mynet
a7b402ee062eaf27c50fb303ae6e764f384cd7b2ebd0acf61fdeeba68bddb5f6
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9b3f5f5076b9   bridge    bridge    local
76d9e06a3606   host      host      local
a7b402ee062e   mynet     bridge    local
9f44873071f4   none      null      local
[root@localhost ~]# docker run -d -p 80:80 --name testweb --network mynet --network-alias websrv centos
0630c88e381c805fb9176bf682dfdca5f541d3104364a238a5b4045ca5a7a014

设置容器ip

使用--network 选项启动容器连接自定义网络时,可以使用 --ip--ip6选项明确指定分配给该网络容器的ip地址。

使用前面创建的mynet,创建新容器指定ip时报错:Error response from daemon: user specified IP address is supported only when connecting to networks with user configured subnets.
注意:仅当连接到具有用户配置的子网的网络时,才支持用户指定的IP地址。

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
      --ip string                      IPv4 address (e.g., 172.30.100.104)
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)

# 案例
[root@localhost ~]# docker network create --driver bridge --subnet 172.19.1.0/24 --gateway 172.19.1.1   mynet02
97f9b61b3a30228b714781bfca5c0b6fe2bb140bdb6520eb87f706016707f2d9
[root@localhost ~]# docker network inspect mynet02
[
    {
        "Name": "mynet02",
        "Id": "97f9b61b3a30228b714781bfca5c0b6fe2bb140bdb6520eb87f706016707f2d9",
        "Created": "2022-04-13T17:15:12.435135856+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.1.0/24",
                    "Gateway": "172.19.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@localhost ~]# docker run -d -p 8000:80 --name testweb02 --network mynet02 --network-alias web02 --ip 172.19.1.101 centos
dd8d96ea1e680e010c7a1041dc311fd6eee7194fa8b26a134ccb3053aafee17d

设置容器网络接口MAC地址

默认情况下,容器mac地址是基于其IP地址生成。
可以通过 --mac-address 选项为容器指定一个MAC地址。

注意:手动指定mac地址,docker不会检查地址的唯一性。

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
      --mac-address string             Container MAC address (e.g., 92:d0:c6:0a:29:33)

# 案例
[root@localhost ~]# docker run -d -p 8080:80 --name testweb03 --network mynet --network-alias web03 --mac-address 12:34:56:78:9a:bc  centos
4bc34a65f48f46b95c021194dec216f640d8974f98c6c297dcc37c64f924436b
[root@localhost ~]# docker inspect --format='{{json .Config.MacAddress}}'  4bc34a65
"12:34:56:78:9a:bc"

设置容器的DNS配置和主机名

默认情况下,容器继承Docker守护进程的DNS配置,包括 /etc/hosts/etc/resolv.conf 配置文件。

可以使用以下选项配置DNS,覆盖默认配置。

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
      --dns list                       Set custom DNS servers            # 为容器设置DNS服务器的IP地址
	  可以使用多个--dns为容器指定多个DNS服务器。
	  容器连不上指定DNS服务器,会自动使用google的公共dns:8.8.8.8。
      --dns-option list                Set DNS options                   # 为容器设置表示DNS选项及值的键值对
	  
      --dns-search list                Set custom DNS search domains     # 为容器指定一个DNS搜索域
	  
  -h, --hostname string                Container host name               # 为容器指定自定义的主机名
  

# --dns案例
[root@localhost ~]# docker run -d -p 8081:80 --name testdns --network mynet --dns 202.103.24.68  centos
101cf268006a5780c9e69e147d302933aa91bace5922c5527d41f5dcec4a23f9
[root@localhost ~]# docker inspect --format='{{json .HostConfig.Dns}}'  101cf268
["202.103.24.68"]

标签:容器,network,自定义,--,网络,docker
来源: https://www.cnblogs.com/kongshuo/p/16140845.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有