1.使用veth pair连接两个network namespace
1.1 基本使用
# 查看linux上的network namespace
sudo ip netns list
# 删除network namespace
sudo ip netns delete [name]
# 创建network namespace
sudo ip netns add test1
# 查看namespace里的ip(可以看到只有环回口,并且是down的状态)
sudo ip netns exec test1 ip a
# 将状态设置为up(结果是UNKNOW,单个端口是没法up的,必须是一对)
# sudo ip netns exec test1 ip link(这条也是查看)
sudo ip netns exec test1 ip link set dev lo up
1.2 目标
# 将test1和test2连接起来(连接两个namespace)
1.3 实现
1.查看本机link
ip link
2.添加veth pair
sudo ip link add veth-test1 type veth peer name veth-test2
# 再ip link发现出现了一对link,分别是veth-test1@veth-test2和veth-test2@veth-test1,均有mac地址,但没有ip,状态为down
3.将veth pair添加到namespace
sudo ip link set veth-test1 netns test1
sudo ip link set veth-test2 netns test2
4.查看namespace和本地的变化
#namespace
sudo ip netns exec test1 ip link
sudo ip netns exec test2 ip link
# 本地
# 发现本地ip link创建的一对veth pair已经消失了,不再有veth-test1@veth-test2和veth-test2@veth-test1了
5.给veth-test1和veth-test2分配ip地址
# 分配
sudo ip netns exec test1 ip addr add 192.168.118.1/24 dev veth-test1
sudo ip netns exec test2 ip addr add 192.168.118.2/24 dev veth-test2
# 启动
sudo ip netns exec test1 ip link set dev veth-test1 up
sudo ip netns exec test2 ip link set dev veth-test2 up
# 查看(发现已经正确有了ip地址)
sudo ip netns test1 ip a
sudo ip netns test2 ip a
6.两个namespace互ping(发现已经能够正确ping通)
sudo ip netns exec test1 ping 192.168.118.2
sudo ip netns exec test2 ping 192.168.118.1
2.docker网络
# 上面的示例是通过veth pair来实现的连接,那么docker呢
# docker创建一个容器,同时也会创建一个network namespace,怎么互通呢?
# 查看网络
docker network ls(bridge,host,none)
# 查看bridge网络上连接了哪些容器
docker network inspect [bridge的ID]
# 容器网络的连接
1.启动容器
docker run -d --name test1 busybox /bin/sh -c "while true; do sleep 3600; done"
2.查看veth pair对
# 运行ip -a发现多了一个15: vethxxxxxx@if14
# 运行docker exec test1 ip a发现多了一个14: eth0@if15
# 这两个其实就是一个veth pair对,他们将容器与docker0进行了连接,我们验证一下
sudo yum install bridge-utils
brctl show
bridge name bridge id STP enabled intefaces
docker0 8000.0242301b1d5e no vethxxxxx
# 其中这个vethxxxx就是本机ip -a时的那个虚拟eth
# 访问外网
3.容器间的link
# 我们已经有了一个容器busybox test1
# 现在创建test2,连接到test1
docker run -d --name test2 --link test1 busybox /bin/sh -c "while true; do sleep 3600; done"
# 这时候进入test2,ping test1的ip和test1这个名字均可以正常通
# 进入test1,ping test2的ip肯定是通的,但Ping test2的名字是不通的
# 但有一种例外,跟下面的创建network有关,如果两个容器都连接到了用户自定义的网络上.比如下面的my-bridge,而不是系统默认的docker0这个bridge,则默认情况下互相link好了,通过名字可以ping通
# 实际中--link这个参数很少使用
4.network的种类
1.bridge
sudo docker network create -d bridge my-bridge
# 新建容器指定网络为my-bridge
sudo docker run -d --name test3 --network my-bridge busybox /bin/sh -c "while true; do sleep 3600; done"
# 指定已经存在的容器到新的网络(原网络也还在,即test2即在my-bridge上,也在bridge上)
sudo docker network connect my-bridge test2
2.none
容器是孤立的(没有ip地址,mac地址,ip a里面除了回环地址也没别的,除了exec的方式可以进入容器,没有其他任何办法,用得非常少
3.host
也没有ip地址,mac地址,容器没有独立的namespace,与主机共享一套,ip a看到的信息与宿主机一致,容易造成端口冲突
5.docker多机通信
# 了解VXLAN
# 了解LVS(Linux Virtual Server)
# Overlay多机通信,依赖于etcd分布式kv存储,etcd能够保证ip地址不会冲突
6.routing mesh
Internal:
Container和Container之间的访问通过overlay网络(通过VIP虚拟IP)
Ingress:
如果服务有绑定接口,则此服务可以通过任意swarm节点的相应接口访问
# 查看本地创建的network namespcae
sudo ls /var/run/docker/netns
10de222a0ebc 1-heweupwlcu 1-obe9f2751s ingress_sbox
# 进入ingress_sbox
sudo nsenter --net=/var/run/docker/netns/ingress_sbox