为none网络添加网卡
docker中的网络接口默认都是虚拟接口。虚拟接口最大的优势就是转发效率高。这是因为Linux通过在内核中进行数据复制来实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将被直接复制到接收接口的接收缓存中,而不需要通过外部物理网络设备进行交换。这样,对于本地系统和容器内系统来看,虚拟接口跟一个正常的以太网卡没有啥区别。
思路:
网络创建过程:
1、创建一对虚拟接口,分别放在本地主机上和容器里面
2、本地的虚拟接口接在docker0网桥上,并且具有一个一veth开头的名字
3、另一端的接口将放在新创建的容器的命名空间里面,并修改为eth0
4、从网桥可用地址中获取一个空闲地址分配给容器的eth0,并配置地址默认路由网关为docker0网卡的内部接口docker0的ip地址。
过程:
1、我们先启动一个none网络容器
1 | docker run -it --rm --net=none ubuntu:16.04 /bin/bash |
2、在本机查找它的进程号,然后在本地创建它的一个网络命名空间
1 | docker inspect -f '{{.State.Pid}}' 6d9454 |
注:容器号可通过docker ps获取
然后为了方便我们设置一个变量:
pid=进程号
1 | mkdir -p /var/run/netns |
3、检查桥接网卡的ip和掩码
1 | ip addr show docker0 |
4、创建一对veth pair的虚拟接口,绑定A在docker0上
1 | ip link add A type veth peer name B |
5、将B放在容器里面的网络命名空间里面,命名为eth0,并配置
1 | ip link set B netns $pid |
端口映射
如果想让外部访问docker内的应用,可以通过-P或者-p参数来进行端口的映射,当用-P的时候,此时,系统随机映射一个49000-49900的端口到内部容器的开放端口;而通过-p则是由人员指定映射的端口。
1 | -p hostport:containport,映射多个端口时,多次使用-p参数。 |
点对点通信
通过上面的实验,我们可以拓展一下,将放在docker0的接口放在另一个容器中,去实现一个点对点的通信。这样就不用通过主机网桥进行一个桥接。
大致过程:
1 | 首先启动两个容器: |
注:644,502是进程号
容器互联
通过容器的互联让多个容器中的应用进行快速交互,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名来快速发送源容器而不需要具体的ip地址。
使用–link name:alias参数可以让容器之间安全地进行交互
比如:
先创建一个数据库容器:
1 | docker run -d --name db training/postgres |
然后创建一个web容器连接到数据库容器上:
1 | docker run -d -P --name web --link db:db training/webwebapp python app.py |
可用docker ps来查看连接情况,docker此时相当于在两个互联的容器之间创建了一个虚拟的通道,而且不用映射他们的端口在宿主主机上,在启动db容器的时候没有使用端口映射,这样就避免的数据库暴露在外。