Docker网络和通信

docker网络模式

安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络,也就是在不使用–network参数时)、 none 、host。还有以后一种自定义模式,自定义模式有三种:bridge、overlay、macvlan。

  • host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
  • none:该模式关闭了容器的网络功能。
  • bridge:此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。

通过如下命令可以查看docker网络


docker network ls

NETWORK ID          NAME                         DRIVER              SCOPE
2e3e4dcbd3d7        bridge                       bridge              local
f3055283e718        docker-mac-network_default   bridge              local
fdbd9040885e        host                         host                local
9c38974a6323        mybridge                     bridge              local
1c8d0ddedbbe        none                         null                local

自定义bridge模式

docker启动的容器通常使用默认的bridge网络,有个弊端就是不能指定IP,如果停止容器再一次启动IP会发生变化,如果需要指定IP需要使用自定义网络。

创建network命令如下


docker network create -d bridge --ip-range=192.168.2.0/24 --gateway=192.168.2.1 --subnet=192.168.2.0/24 bridge2

在使用docker run命令启动容器的时候,可以通过–net参数来指定容器的网络配置。

  • –net=bridge:默认值,在Docker网桥docker0上为容器创建新的网络栈。
  • –net=none:让Docker将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自行进行配置。
  • –net=container:NAME_or_ID:让Docker将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享IP地址和端口等网络资源,两者进程可以直接通过lo环回接口通信。
  • –net=host:告诉Docker不要将容器网络放到隔离的命名空间中,即不要容器化容器内的网络。此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。容器进程可以跟主机其他root进程一样打开低范围的端口,可以访问本地网络服务,比如D-bus,还可以让容器做一些影响整个主机系统的事情,比如重启主机。因此使用这个选项的时候要非常小心。如果进一步的使用–privileged=true参数,容器甚至会被允许直接配置主机的网络栈。
  • –net=user_defined_network:用户自行用network相关命令创建一个网络,通过这种方式将容器连接到指定的已创建网络上去。

创建两个容器指定ip并指定network

#指定容器IP为192.168.1.3,使用网络bridge2
docker run -it --network=bridge2 --ip=192.168.1.3 busybox
#指定容器IP为192.168.1.4,使用网络bridge2
docker run -it --network=bridge2 --ip=192.168.1.4 busybox

容器之间的通信方式

IP 通信

两个容器要能通信,必须要有属于同一个网络的网卡。满足这个条件后,容器就可以通过IP交互了。具体做法是在容器创建时通过 –network 指定相应的网络,或者通过docker network connect将现有容器加入到指定网络。

Docker DNS Server

通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署应用之前可能无法确定IP,部署之后再指定要访问的IP会比较麻烦。对于这个问题,可以通过docker自带的DNS服务解决。

从Docker1.10版本开始,docker daemon实现了一个内嵌的DNS server,使容器可以直接通过"容器名"通信。方法很简单,只要在启动时用 –name 为容器命名就可以了。

使用 docker DNS 有个限制:只能在用户自定义网络中使用。也就是说,默认的bridge网络是无法使用DNS的。

joined容器

joined容器是另一种实现容器间通信的方式。它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信。

joined容器使用方式如下:

#先创建一个http容器,名字为 box1
docker run -it --name box1 http

#然后创建 busybox 容器并通过 --network=container:box1 指定 jointed 容器为 box1
docker run -it --network=container:box1 busybox

容器访问控制

容器访问外部网络

我们知道容器默认指定了网关为docker0网桥上的docker0内部接口。docker0内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访问到宿主机本地的。更进一步,容器要想通过宿主机访问到外部网络,需要宿主机进行转发。

#查看转发是否打开
sysctl  net.ipv4.ip_forward
#如果为0,则没有开启转发,则需要手动打开:
sysctl -w net.ipv4.ip_forward=1

更简单的,在启动Docker服务的时候设定–ip-forward=true,Docker服务会自动打开宿主机系统的转发服务。

外部访问容器实现

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

不管用那种办法,其实也是在本地的iptable的nat表中添加相应的规则,将访问外部IP地址的网包进行目标地址DNAT,将目标地址修改为容器的IP地址

参考资料

分类

开发
    --go (9)
    --java (5)
    --php (11)
    --mysql (9)
    --javascript (3)
    --html (1)
    --算法 (6)
架构
    --理论 (9)
    --网络 (3)
    --服务器 (2)
    --消息队列 (3)
    --容器 (5)
    --监控 (1)
    --搜索引擎 (3)
    --大数据 (0)
    --测试 (1)
系统
    --linux (10)
    --mac (2)
    --windows (1)
足球
    --世界杯 (60)
    --欧洲杯 (28)
    --文迷 (3)
大学时光
    --校园生活 (96)
    --假期生活 (17)
    --广院杯那些事 (14)
    --北京奥运 (6)
    --胡思乱写 (17)


最近发布

零拷贝技术介绍

服务网格技术简介

C语言标准和标准库简介

Kubernetes简介及环境搭建

Go语言开发的顶级项目


归档

2006 (109)
2007 (40)
2008 (47)
2009 (10)
2010 (6)
2012 (10)
2013 (14)
2014 (27)
2015 (15)
2016 (6)
2017 (8)
2018 (11)
2019 (17)
2020 (5)