容器的网络方案分为三大部分:
- 单机的容器间通信;
- 跨主机的容器间通信;
- 容器与主机间通信。
docker的四种网络通信模式:
- bridge模式,通过--network=bridge指定;
- host模式,通过--network=host指定;
- container模式,通过--network=container:NAME_or_ID指定,即joiner容器;
- none模式,通过--network=none指定。
bridge模式
docker在安装时会创建一个名为docker0的Linux网桥。bridge模式是Docker默认的网络模式,在不指定--network的情况下,Docker会为每一个容器分配network、namespace、设置ip等,并将Docker容器连接到docekr0上。可通过brctl show命令查看。
host模式
连接到host网络的容器共享Docker host的网络栈,容器的网络配置与host完全一样。host模式下容器将不会获得独立的network namespace,而是和宿主机公用一个network namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
缺点:容器没有隔离、独立的网络栈;端口资源冲突。
container模式
创建容器时使用--network=container:NAME_or_ID模式,在创建新的容器时指定容器的网络和一个已经存在的容器共享一个network namespace,但是并不为Docker容器进行任何网络配置,这个Docker容器没有网卡、IP、路由等信息,需要手动为Docker容器添加网卡、配置IP等。
kubernetes的pod网络采用的就是Docker的container模式网络。
none模式
none模式下的容器只有lo回环网络,没有其他网卡。网卡、ip、路由等信息需要手动配置。
Docker网络技巧
查看容器IP
docker inspect -f "{{ .
}}" <containerNameOrId>
等价于:
docker inspect <containerNameOrId> | grep '"IPAddress"' | head -n 1
端口映射
在使用docker run的时候可以使用-P或者-p命令进行容器和主机之间的端口映射。使用-P不需要指定任何映射关系,默认情况下,Docker会随机将一个49000的端口映射到内部容器开放的网络端口。使用-p则需要指定主机的端口应该映射到容器的哪个端口。例:
# docker run -p 1234:80 -d nginx
注:-p的格式是hostport:containerport
可以通过iptables命令看底层映射关系:
# iptables -t nat -nL
访问外网
容器访问外网需要两个因素:ip_forward和SNAT/MASQUERADE。
确认系统的ip_forward是否已打开:
# sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
DNS和主机名
容器中的DNS和主机名一般通过三个系统配置文件维护,分别是/etc/resolv.conf、/etc/hosts和/etc/hostname。