您的位置:首页 > 运维架构 > Docker

Docker中的网络

2019-12-19 20:37 826 查看

3 月,跳不动了?>>>

从Linux中的网络说起
  • namespace 之间的连通性

namespace 是 Linux 2.6.x 内核版本之后支持的特性,主要用于资源的隔离。有了 namespace,一个 Linux 系统就可以抽象出多个网络子系统,各子系统间都有自己的网络设备,协议栈等,彼此之间互不影响。

  • 如果各个 namespace 之间需要通信,怎么办呢
# 查看网卡信息
ip link show
# 或者
ip a
# 网卡配置目录
cd /etc/sysconfig/network-scripts/

#给网卡添加临时ip
ip addr add 192.168.xxx.xxx/24 dev eth0
#删除ip
ip addr delete 192.168.xxx.xxx/24 dev eth0
将网卡进行隔离
# 创建 network namespace
ip netns add ns1
# 查看
ip netns list
# 查看当前namespace的网卡信息
ip netns exec ns1 ip a
# 启动网卡
ip netns exec ns1 ifup  lo
veth pair技术(virtual Ethernet Pair)

eth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。正因为有这个特性,它常常充当着一个桥梁,连接着各种虚拟网络设备,典型的例子像“两个 namespace 之间的连接”,“Bridge、OVS 之间的连接”,“Docker 容器之间的连接” 等等,以此构建出非常复杂的虚拟网络结构。

ip link add veth-ns1 type veth peer name veth-ns2
#绑定network namespace
ip link set veth-ns1 netns ns1
# 给网卡添加ip
ip netns exec ns1 ip addr add 192.xxx.xxx.10/24 dev veth-ns1
# 启动网卡
ip netns exec ns1 ip link set veth-ns1 up
# ns2同理可得,略
# ns1 ping ns2
ip netns exec ns1 ping 192.168.xxx.xxx
# 两个命名空间中对应的网卡部分信息
veth-ns1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
inet 192.xxx.xxx.10/24 scope global veth-ns1
valid_lft forever preferred_lft forever
----
veth-ns2@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
inet 192.xxx.xxx.11/24 scope global veth-ns2
valid_lft forever preferred_lft forever

veth-ns1@if4  <--->veth-ns2@if5 成对
再看docker

通过上面一些理论我们可以论证docker是否也使用了veth-pair这样一个技术。

启动2个docker容器
docker run -d mytomcat01 -p 8001:8080 tomcat
docker run -d mytomcat02 -p 8002:8080 tomcat
# 物理主机信息
8: veth131fbae@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
inet6 aaaa::aaaa:aaaa:aaaa:aaaa/64 scope link
valid_lft forever preferred_lft forever
10: veth61cf0b5@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
inet6 aaaa::aaaa:aaaa:aaa:aaa/64 scope link
valid_lft forever preferred_lft forever

# 分别进入到docker 容器中
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 172.xxx.xxx.2/16 brd 172.xxx.255.255 scope global eth0
valid_lft forever preferred_lft forever

9: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.xxx.xxx.3/16 brd 172.xxx.255.255 scope global eth0
valid_lft forever preferred_lft forever

可以看出docker中的container和物理主机中也是成对出现了这样的网卡信息。 veth131fbae@if7 <--> eth0@if8 、veth61cf0b5@if9 <---> eth0@if10

Docker 中的网络模式
docker network ls

NETWORK ID          NAME                DRIVER               SCOPE
15ea9d89d616        bridge              bridge               local
1c62b0fd4212        host                host                 local
375f1ab17a8b        none                null                 local

1. bridge
- 默认使用的方式
2.host
- 访问容器不需要进行映射直接可以访问
3. none
- 只有一个本地网卡信息

#创建,默认为bridge
docker network create  net01
# 查看详细信息
docker network inspect net01
[
{
"Name": "net01",
"Id": "b9fee626fdee",
"Created": "2019-12-19T10:50:59.641869093Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "x.0.0.0/16",
"Gateway": "x.x.x.x" #网关信息
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": { # 容器信息
"c0f8db51792b9b394b": {
"Name": "tomcat03",
"EndpointID": "9a966183a87",
"MacAddress": "",
"IPv4Address": "x.x.x.x/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]

# 给容器使用自定义的网络
docker run -d --name tomcat03 --network net01 -p 8082:8080 tomcat
#可以对比容器使用与未使用的ip变化

#但是此刻却无法ping通使用默认docker0的network创建的容器,
因为自定义的网络跟docker0不在同一个网段所以无法ping通,tomcat03在自定义网络,
tomcat01使用的则是默认的网络,那么tomcat03和tomcat01当然无法ping通。
# 查看当前docker默认的bridge
docker inspect bridge

[
{
"Name": "bridge",
"Id": "15ea9d89d6165304b561b",
"Created": "2019-12-19T10:43:46.750789678Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "x.x.0.0/16",
"Gateway": "x.x.x.x"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": { #可以看到默认网络的容器信息
"44371744ca1a": {
"Name": "tomcat01",
"EndpointID": "7005e8d9f9aab442",
"MacAddress": "",
"IPv4Address": "x.x.x.x/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
# 将tomcat01也加入到自定义网络中
docker network connect net01 tomcat01
#再次查看net01发现tomcat01也在当中了
# docker inspect tomcat01 查看tomcat01中的网络此时也多了一个ip地址
#此时tomcat01和tomcat03可以互通

结论: 为什么容器之间能够相互连通,是因为docker会创建这种桥接模式,而桥接模式实际上是使用了veth-pair技术,所以容器之间可以进行通信。

container之间是否可以通过别名互通

如果真的可以那么就不需要担心ip地址的变化了,就像微服务一样,服务与服务之间的调用通过注册咋注册中心上的服务名字即可调用。遗憾的是我们在使用默认的docker网络是无法用名字的方式ping通

  • 增加link的方式进行指定 docker run -d --name tomcat05 --link tomcat01 -p 8085:8080 tomcat
  • 自定义网络的方式是可以互通的
多机通信overlay网络

Swarm中实现

docker network create -d overlay o-net

创建service
docker service create --name mysql -v v1:/var/lib/mysql  -e MYSQL_ROOT_PASSWORD=123 -e MYSQL_DATABASE=db_wordpress --network o-net mysql:5.6

docker service create --name wordpress -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=123 -e WORDPRESS_DB_HOST=mysql:3306 -e WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network o-net wordpress

docker network inspect o-net
[
{
"Name": "o-net",
"Id": "45x28fm6",
"Scope": "swarm",
"Driver": "overlay",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet":
"Gateway":
}
]
},
"Containers": {
"64cf17fd1f0": {
"Name": "mysql.1.s1hfbsju",
"EndpointID":
"MacAddress":
"IPv4Address":
},
"lb-overlay-net": {
"Name": "overlay-net-endpoint",
"EndpointID": ,
"MacAddress":,
"IPv4Address": ,
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": {},
"Peers": [
{
"Name":
"IP":
},
{
"Name":
"IP":
}
]
}
]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息