Docker 网络
Docker 网络
网络接口查看
- ip 命令
# 方式一
$ ip link show
# 方式二
# ip address、ip addr、ip a都是等价的命令
$ ip address
......
ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:33:4d:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.168/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::af3e:9c:1cb4:f12e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
......
- net文件
$ ls /sys/class/net
网络接口详情
- ip命令详情
# ip address、ip addr、ip a都是等价的命令
$ ip address
# ens32: 网卡名称
# 网络状态: up/down/unkonw等
# link/eher: mac地址
# inet: 绑定的ip地址
......
ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:33:4d:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.168/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::af3e:9c:1cb4:f12e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
......
- 网卡配置文件
# 在Linux中网卡对应的其实就是文件,所以找到对应的网卡文件即可
# Centos7一般网卡名称为 ensxxx
$ cat /etc/sysconfig/network-scripts/ifcfg-ensxxx
- 单个网卡配置多个IP地址
# 添加ip地址
$ ip addr add 192.168.188.178/24 dev ens32
$ ip addr
......
ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:33:4d:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.168/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet 192.168.188.178/24 scope global secondary ens32 # 添加上ip地址
valid_lft forever preferred_lft forever
inet6 fe80::af3e:9c:1cb4:f12e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
......
# 删除ip地址
$ ip addr delete 192.168.188.178/24 dev ens32
$ ip addr
......
ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:33:4d:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.168/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::af3e:9c:1cb4:f12e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
......
- 网卡开启&关闭
# 重启网卡
$ service network restart
$ systemctl restart network
# 启动/关闭网卡
#开启网卡
$ ifup ens32
$ ip link set ens32 up
#关闭网卡
$ ifdown ens32
$ ip link set ens32 down
Docker 网络信息
docker不启动时,通过ip addr
查看默认网络情况
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:11:13:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.188/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::400e:cc35:e4ab:8c3f/64 scope link noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::1612:6953:eae9:ffd2/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
docker启动时,通过ip addr
查看默认网络情况
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:11:13:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.188/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::400e:cc35:e4ab:8c3f/64 scope link noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::1612:6953:eae9:ffd2/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:69:43:63:59 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:69ff:fe43:6359/64 scope link
valid_lft forever preferred_lft forever
docker启动容器后,通过 ip addr
查看默认网络情况
$ docker run -itd -P nginx:alpine
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:11:13:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.188/24 brd 192.168.188.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::400e:cc35:e4ab:8c3f/64 scope link noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::1612:6953:eae9:ffd2/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:69:43:63:59 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:69ff:fe43:6359/64 scope link
valid_lft forever preferred_lft forever
4: veth562fa10@if70: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether f6:a8:ee:32:44:12 brd ff:ff:ff:ff:ff:ff link-netnsid 4
inet6 fe80::f4a8:eeff:fe32:4412/64 scope link
valid_lft forever preferred_lft forever
Docker 网络模式
Bridge 模式
Docker 服务启动时, 会自动在宿主机上创建一个 docker0 虚拟网桥 (Linux Bridge, 可以理解为一个软件虚拟出来的交换机); 它会在挂载到它的网口之间进行转发; 同时 Docker 随机分配一个可用的私有 IP 地址给 docker0 接口; 如果容器使用默认网络参数启动, 那么它的网口也会自动分配一个与 docker0 同网段的 IP 地址;
- 获取
docker0
网络信息
# 地址为 172.17.0.1, 子网掩码为 255.255..0.0
$ ip address show dev docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ab:ad:e2:fe brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:abff:fead:e2fe/64 scope link
valid_lft forever preferred_lft forever
- 新建容器测试连通性&查看容器ip地址
# 运行 busybox 容器
$ docker run -d -t --name b0 busybox
$ docker run -d -t --name b1 busybox
# 查看容器 ip 地址
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' b0 # 172.17.0.9
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' b1 # 172.17.0.10
- docker0 网络拓扑图
自定义网桥
除了使用默认 docker0 做网桥,还可以使用 docker network
相关命令自定义网桥;
- 创建网桥 br0
# 将创建一个网桥 br0, 设定网段是 172.71.0.0/24, 网关为 172.71.0.1
$ docker network create -d bridge --subnet '172.71.0.0/24' --gateway '172.71.0.1' br0
# -d 指定管理网络的驱动方式,默认为bridge
# --subnet 指定子网网段
# --gateway 指定默认网关
- 查看 docker 网络列表
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
c9238e72be54 br0 bridge local
......
- 在 br0 网桥中运行容器测试
$ docker run -d -t --network br0 --name b2 busybox
$ docker run -d -t --network br0 --name b3 busybox
- 测试 b2、b3 容器网络连通性
# ping 测试过程中, 输入的并不是 IP, 而是容器名; 在自定义网桥中, 容器名会在需要的时候自动解析到对应的 IP, 也解决了容器重启可能导致 IP 变动的问题;
# 使用 b2 容器 ping b3 容器
$ docker exec b2 ping b3
# 使用 b3 容器 ping b2 容器
$ docker exec b3 ping b2
- 删除容器&网络
# 删除 b2 b3 容器
$ docker rm -f b2 b3
# 删除自定义网络 br0
$ docker network rm br0
端口映射访问容器
将宿主机的本地端口, 与指定容器的服务端口进行映射绑定, 之后访问宿主机端口时, 会将请求自动转发到容器的端口上, 实现外部对容器内网络服务的访问;
- 创建 nginx 容器
# 创建名为 n0 的 nginx 容器, 映射宿主机 8000 端口到它的 80 端口
# Tips: 指定的宿主机端口必须是未被占用的端口, 否则操作会失败, 且生成一个无法正常启动的容器 n0, 需要手动删除;
# 绑定单个端口, 则使用单个 -p
$ docker run -d -t -p 8000:80 --name n0 nginx
# 绑定多个端口, 则使用多个 -p
$ docker run -d -t -p 8001:80 -p 8433:443 --name n1 nginx
# 若不想指定端口, 想随机生成一个端口则使用 -P
$ docker run -d -t -P --name n2 nginx
- 查看 n0 容器端口映射信息
$ docker port n0
80/tcp -> 0.0.0.0:8000
- 访问测试
# 方式一: 打开浏览器, 地址栏输入 http://宿主机ip:8000
# 方式二: 通过 curl 命令
$ curl localhost:8000
- 使用宿主机上特定的网口与容器进行映射
# Tips: 此处 192.168.188.188 指代宿主机映射网口的 IP 地址, 需要根据网口的实际 IP 更改;
$ docker run -d -t -p 192.168.188.188:8002:80 --name n3 nginx
- 查看防火墙
# 这种端口转发方式的本质是通过配置 iptables 规则转发实现的, 效率较低, 如果容器的服务端口数量过多, 需要配置较多的映射, 占用大量宿主机端口, 也不便于管理;
$ iptables -t nat -nL
......
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:172.17.0.6:8000
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8433 to:172.17.0.11:443
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8001 to:172.17.0.11:80
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8002 to:172.17.0.13:80
- 删除 n0、n1、n2、n3 容器
$ docker rm -f n0 n1 n2 n3
Host 模式
host 模式下启动的容器, 网络不再与宿主机隔离, 访问容器服务可以直接使用访问宿主机对应的网络端口, 且不需要端口转发;
- host 网络拓扑图
- 以 host 模式启动 nginx 容器 h0
$ docker run -d -t --network host --name h0 nginx
- 访问测试
# 访问宿主机 80 端口就是访问容器的 80 端口, 它们是一致的;
# 方式一: 打开浏览器, 地址栏输入 http://宿主机ip:80
# 方式二: 通过 curl 命令
$ curl localhost
- 以 host 模式启动 nginx 容器 h1
# 启动 h1 容器
$ docker run -d -t --network host --name h1 nginx
# 查看 h1 状态, 发现 h1 容器没有运行
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d5be60c0ee87 nginx "/docker-entrypoint.…" 43 seconds ago Exited (1) 39 seconds ago h1
- 查看 h1 容器日志信息
# 发现由于宿主机 80 端口已经被 h0 容器的服务占用, 使得 h1 无法获取到 此端口, 导致无法正常启动
$ docker logs h1
......
2023/05/25 18:01:21 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2023/05/25 18:01:21 [emerg] 1#1: bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
2023/05/25 18:01:21 [notice] 1#1: try again to bind() after 500ms
2023/05/25 18:01:21 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2023/05/25 18:01:21 [emerg] 1#1: bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
2023/05/25 18:01:21 [notice] 1#1: try again to bind() after 500ms
2023/05/25 18:01:21 [emerg] 1#1: still could not bind()
nginx: [emerg] still could not bind()
- 删除容器 h0、h1
$ docker rm -f h0 h1
host 模式下的容器与宿主机共享同一个网络环境, 容器可以使用宿主机的网卡和外界的通信, 不需要转发拆包, 性能好;
host 模式也有非常严重的缺点,容器没有隔离的网络, 会与其他服务竞争宿主机的网络, 导致宿主机网络状态不可控, 因此无法用在生产环境;
container 模式
与 host 模式类似, container 模式可以使一个容器共享另一个已存在容器的网络, 此时这两个容器共同使用同一网卡、主机名、IP 地址, 容器间通讯可直接通过本地回环 lo 接口通讯;
- 运行 busybox 容器
# 新运行一个 busybox 的容器 b1, 设定它共享已存在的容器 b0 的网络
# Tips: Tips: 端口转发设定以已存在的容器为准, 出于安全和权限控制的角度, container 模式下运行的容器设定端口转发不生效;
# 运行 b0 容器
$ docker run -d -t --name b0 busybox
# 运行 b1 容器
$ docker run -d -t --network container:b0 --name b1 busybox
- 查看 b0、b1 容器网络配置
# 查看 b0 网络配置
$ docker exec b0 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:09
inet addr:172.17.0.9 Bcast:172.17.255.255 Mask:255.255.0.0
......
# 查看 b1 网络配置
$ docker exec b1 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:09
inet addr:172.17.0.9 Bcast:172.17.255.255 Mask:255.255.0.0
......
- container 网络拓扑图
- 删除 b0、b1 容器
$ docker rm -f b0 b1
- 创建 nginx、busybox 容器,busybox容器共享nginx容器网络信息
# 运行一个名为 n0 的 nginx 容器, 再将n0的网络共享给 busybox 容器 n0-net
$ docker run -d -t --name n0 nginx
$ docker run -d -t --network container:n0 --name n0-net busybox
- 查看 nginx 网络信息
# 使用 n0-net 容器, 执行 docker exec n0-net ip a 进行网络状态查看自身网络信息, 也就是 nginx 的网络信息
$ docker exec n0-net ip a
......
91: eth0@if92: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:0a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.10/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
- 访问测试
# 通过 localhost 访问 n0 的 web 服务, 说明通过 container 模式下, 共享的网络中的容器能够使用 lo 访问其他容器的服务
$ docker exec -it n0-net /bin/sh
......
get # 输入get获取信息
- 删除 n0、n0-net 容器
$ docker rm -f n0 n0-net
在 container 模式下的容器, 会使用其他容器的网络命名空间, 其网络隔离性会处于 bridge 桥接模式与 host 模式之间: 当容器共享其他容器的网络命名空间, 则在容器之间不存在网络隔离; 而它们又与宿主机以及其他不在此共享中的容器存在网络隔离;
none 模式
容器有自己的网络命名空间, 但不做任何配置, 它与宿主机、与其他容器都不连通的;
- 新建一个 none 模式的 busybox 镜像
$ docker run -d -t --network none --name b0 busybox
- 查看 busybox 容器网络信息
# 仅有 lo 接口,不能与容器外通信
$ docker exec b0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
两个容器之间可以直连通信, 但不通过主机网桥进行桥接;解决的办法是创建一对 peer 接口,分别放到两个容器中,配置成点到点链路类型即可;
- 启动 busybox 容器
$ docker run -it -d --net=none --name=none1 busybox
$ docker run -it -d --net=none --name=none2 busybox
- 查看容器进程号
$ docker inspect -f '{{.State.Pid}}' none1 #47657
47657
$ docker inspect -f '{{.State.Pid}}' none2 #47711
47711
- 创建命名空间跟踪文件
# 创建目录
$ sudo mkdir -p /var/run/netns
# 软连接进程网络
$ sudo ln -s /proc/47657/ns/net /var/run/netns/47657
$ sudo ln -s /proc/47711/ns/net /var/run/netns/47711
- 创建一对 peer 接口,配置路由
# 一对创建 peer 接口
$ sudo ip link add A type veth peer name B
# 将 node1 添加到 peer 接口中
$ sudo ip link set A netns 47657
$ sudo ip netns exec 47657 ip addr add 10.1.1.1/32 dev A
$ sudo ip netns exec 47657 ip link set A up
$ sudo ip netns exec 47657 ip route add 10.1.1.2/32 dev A
# 将 node2 添加到 peer 接口中
$ sudo ip link set B netns 47711
$ sudo ip netns exec 47711 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 47711 ip link set B up
$ sudo ip netns exec 47711 ip route add 10.1.1.1/32 dev B
- 测试 none1、none2 容器连通性
# 通过 none1 ping none2
$ docker exec -it none1 ping 10.1.1.2
# 通过 none2 ping none1
$ docker exec -it none2 ping 10.1.1.1
none 模式提供了一种空白的网络配置,方便用户排除其他干扰,用于自定义网络。
Docker 网络命令
docker network命令
$ docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
#参数说明
connect: 连接网络
create: 创建一个docker网络
disconnect: 断开网络
inspect: 显示详细的网络信息
ls: 显示所有docker网络
prune: 移除所有未使用的docker网络
rm: 移除一个或者多个docker网络
Docker network命令使用
# 创建一个名为`network_name`的docker网络
# 默认创建的网络为'bridge'模式
$ docker network create network_name
# 详细显示`network_name`的网络信息
$ docker network inspect network_name
# 显示docker所有网络
$ docker network ls
# 删除名为`network_name`的docker网络
$ docker network rm network_name
Docker 网络的作用:
- 容器间的互联和通信以及端口映射;
- 容器IP变动时候可以通过服务名直接网络通信而不受到影响;
Docker 网络模式总类:
- bridge模式:使用--network bridge指定,默认使用docker0,使用
network create
创建网络时默认为bridge
模式; - host模式:使用--network host指定;
- none模式:使用--network none指定;
- container模式:使用--network container:NAME或者容器ID指定。
查看docker network信息
#1.启动两个centos容器,用于查看网络信息
$ docker run -itd --name centos1 centos:7.6.1810
$ docker run -itd --name centos2 centos:7.6.1810
#2.查看centos1和centos2的网络ip地址
# 查看IPAddress:1
$ docker inspect centos1 | tail -n 20 | grep IPAddress
"IPAddress": "172.17.0.5"
$ docker inspect centos2 | tail -n 20 | grep IPAddress
"IPAddress": "172.17.0.6"
#3.停止centos2,启动centos3
$ docker stop centos2
$ docker run -itd --name centos3 centos:7.6.1810
#4.查看centos1和centos3的网络ip地址
$ docker inspect centos1 | tail -n 20 | grep IPAddress
"IPAddress": "172.17.0.5"
$ docker inspect centos3 | tail -n 20 | grep IPAddress
"IPAddress": "172.17.0.6"
docker容器内部的ip是有可能会发生改变的。
Docker 网络配置&使用
Network Namespace
network namespace(netns)是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息;不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。
veth pair(Virtual Ethernet Pair),是一个成对的端口,可以将相互隔离的network namespace链接起来;
有了不同 network namespace 之后,也就有了网络的隔离,但是如果它们之间没有办法通信,也没有实际用处;要把两个网络ns1、ns2连接起来,linux 提供了 veth pair
;可以把 veth pair
当做是双向的 pipe(管道),从一个方向发送的网络数据,可以直接被另外一端接收到;或者也可以想象成两个 namespace 直接通过一个特殊的虚拟网卡连接起来,可以直接通信。
# ip netns list: 查看当前机器上的network namespace
# network namespace相关命令
#Usage: ip netns list
# ip netns add NAME
# ip netns set NAME NETNSID
# ip [-all] netns delete [NAME]
# ip netns identify [PID]
# ip netns pids NAME
# ip [-all] netns exec [NAME] cmd ...
# ip netns monitor
# ip netns list-id
# 查看namespace
$ ip netns list
# 添加namespace
$ netns add ns1
# 删除namesapce
$ ip netns delete ns1
- 创建ns1
# network namespace(netns)
# 创建 ns1
$ ip netns add ns1
- 查看ns1下的网卡情况
$ ip netns exec ns1 ip a
# state DOWN: 该网卡并未启动
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
- 启动ns1下的网卡
# 以下命令等效
$ ip netns exec ns1 ifup lo
$ ip netns exec ns1 ip link set lo up
# 查看ns1下网卡
$ ip netns exec ns1 ip a
# state UNKNOWN: 状态为 UNKNOWN
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
- 创建ns2
$ ip netns add ns2
- 创建一对veth
# 创建一对veth通过veth pair连接的Link
$ ip link add veth-ns1 type veth peer name veth-ns2
# 查看link
$ ip link
......
5: veth-ns2@veth-ns1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether b2:84:b5:2c:57:25 brd ff:ff:ff:ff:ff:ff
6: veth-ns1@veth-ns2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether c2:60:7a:a3:bf:68 brd ff:ff:ff:ff:ff:ff
- 将veth-ns1加入到ns1中,veth-ns2加入到ns2中
$ ip link set veth-ns1 netns ns1
$ ip link set veth-ns2 netns ns2
- 查看宿主机、ns1、ns2的Link情况
# 宿主机Link
$ ip link
# ns1的Link
$ ip netns exec ns1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: veth-ns1@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether c2:60:7a:a3:bf:68 brd ff:ff:ff:ff:ff:ff link-netnsid 1
# ns2的Link
$ ip netns exec ns2 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: veth-ns2@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether b2:84:b5:2c:57:25 brd ff:ff:ff:ff:ff:ff link-netnsid 0
- veth-ns1、veth-ns2添加ip地址
# veth-ns1 添加 ip 地址
$ ip netns exec ns1 ip addr add 192.168.188.10/24 dev veth-ns1
# veth-ns2 添加 ip 地址
$ ip netns exec ns2 ip addr add 192.168.188.11/24 dev veth-ns2
# 查看ns1、ns2的ink
# 发现ns1、ns2的state是DOWN, 并且还是没有IP地址
$ ip netns exec ns1 ip link
$ ip netns exec ns2 ip link
- 启动veth-ns1、veth-ns2
# 启动veth-ns1、veth-ns2
$ ip netns exec ns1 ip link set veth-ns1 up
$ ip netns exec ns2 ip link set veth-ns2 up
# 查看ns1、ns2
$ ip netns exec ns1 ip a
$ ip netns exec ns2 ip a
- 测试连通性
# 测试ns1
$ ip netns exec ns1 ping 192.168.188.10
$ ip netns exec ns1 ping 192.168.188.11
# 测试ns2
$ ip netns exec ns2 ping 192.168.188.10
$ ip netns exec ns2 ping 192.168.188.11
Container Namespace
- 创建container1、container2
# 创建tomcat1、tomcat2
$ docker run -d --name tomcat01 -p 8081:8080 tomcat
$ docker run -d --name tomcat02 -p 8082:8080 tomcat
# docker 网络模式
$ docker network ls
# 查看容器container1、container2 ip
$ docker network inspect bridge
$ docker inspect bridge
"Containers": {
"47fb5c74c91c89677221edf9f9f048e401b6febfd45671fcd99a15a886d98bf1": {
"Name": "tomcat02",
"EndpointID": "413dca73ee560dfb0e7ef2e7058e56cc6f4271c3a9f56449c7f21fecd2e071bb",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"74b4bc929344547cd8f5958ddf5a2ec0ba47de314f5ddcfb587a60e4c218e460": {
"Name": "tomcat01",
"EndpointID": "61d9c7720d3cbe8f4d7559b112df7b7a5714a8ddab194decddac1ac234c6d917",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
}
# 测试连通性
# 发现是可以 ping 通, 这里未使用veth-pair技术
$ docker exec -it tomcat01 /bin/bash
61d9c7720$ ping 172.17.0.3
$ docker exec -it tomcat02 /bin/bash
413dca73e$ ping 172.17.0.2
- 安装bridge
$ yum install -y bridge-utils