` docker(四) | 听云轩

docker(四)

为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
2
docker inspect -f '{{.State.Pid}}' 6d9454
`

注:容器号可通过docker ps获取

然后为了方便我们设置一个变量:

pid=进程号

1
2
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid

3、检查桥接网卡的ip和掩码

1
ip addr show docker0

ZyJvf1.png

4、创建一对veth pair的虚拟接口,绑定A在docker0上

1
2
3
ip link add A type veth peer name B
brctl addif docker0 A
ip link set A up

5、将B放在容器里面的网络命名空间里面,命名为eth0,并配置

1
2
3
4
5
ip link set B netns $pid
ip netns exec $pid ip link set dev B name eth0
ip netns exec $pid ip link set dev eth0 up
ip netns exec $pid ip addr add 172.17.0.20/16 dev eth0
ip netns exec $pid ip route add default via 172.17.0.1

端口映射

    如果想让外部访问docker内的应用,可以通过-P或者-p参数来进行端口的映射,当用-P的时候,此时,系统随机映射一个49000-49900的端口到内部容器的开放端口;而通过-p则是由人员指定映射的端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
-p hostport:containport,映射多个端口时,多次使用-p参数。

映射指定地址的指定端口时:
-p ip:hostport:containport

映射到指定地址的任意端口:
-p ip::containport

还可以在后面使用协议标记来指定什么协议端口的映射(tcp\udp)
-p hostport:containport/udp

查看端口映射的配置:
docker port命令或者是docker logs命令

点对点通信

    通过上面的实验,我们可以拓展一下,将放在docker0的接口放在另一个容器中,去实现一个点对点的通信。这样就不用通过主机网桥进行一个桥接。

大致过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
首先启动两个容器:
docker run -i -t --rm --net=none debian /bin/bash

docker run -it --rm --net=none debian /bin/bash

查找进程号,创建网络命名空间的跟踪文件:
docker inspect -f '{{\.State\.Pid}}' 440

docker inspect -f '{{\.State\.Pid}}' 94d

mkdir -p /var/run/netns

ln -s /proc/644/ns/net /var/run/netns/644

ln -s /proc/502/ns/net /var/run/netns/502

创建一对虚拟网卡:
ip link add A type veth peer name B

配置:
ip link set A netns 644
ip netns exec 644 ifconfig A 10.1.1.1/24 up


ip link set dev B netns 502
ip netns exec 502 ifconfig B 10.1.1.2/24 up

此时测试ping,如果ping不通,可配置静态路由:
ip netns exec 644 ip route add 10.1.1.2/32 dev A

ip netns exec 502 ip route add 10.1.1.1/32 dev B

注: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容器的时候没有使用端口映射,这样就避免的数据库暴露在外。

------ 本文结束 ------
您的支持将鼓励我继续创作