网络基础知识
网络相关命令
查看Linux中的网卡
- [root@localhost ~]# ip link show
- [root@localhost ~]# ls /sys/class/net
- [root@localhost ~]# ip a
状态: UP、DOWN、UNKNOW
link/ether:MAC地址
inet:该网卡绑定的IPv4地址
[root@localhost ~]# ip link show
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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:43:ed:74 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:60:35:29:a1 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# ls /sys/class/net
docker0 ens33 lo
[root@localhost ~]# ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:43:ed:74 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.104/24 brd 192.168.1.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 2409:8a70:1062:aa70:20c:29ff:fe43:ed74/64 scope global mngtmpaddr dynamic
valid_lft 247096sec preferred_lft 160696sec
inet6 fe80::20c:29ff:fe43:ed74/64 scope link
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:60:35:29:a1 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
[root@localhost ~]#
网卡对应的配置文件
网卡对应配置文件目录:/etc/sysconfig/network-scripts/
以ifcfg-ens33为例
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet" # 表示接口类型:Ethernet-以太网,Bridge-桥接接口
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static" # 网卡类型:dhcp-动态 static-静态 none-固定
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="46d7dee9-2fae-4f9d-b695-22e96afc984c"
DEVICE="ens33" # 网卡名称
ONBOOT="yes" # 开机或重启网卡时,是否启用该网卡
IPADDR="192.168.1.104"
NETMASK="255.255.255.0" # 子网掩码
DNS1="192.168.1.1" # DNS 地址
GATEWAY="192.168.1.1" # 网关
Network Namespace
在linux中,网络的隔离是通过network namespace来管理,不同的network namespace是相互隔离的。
ip netns list 查看network namespace
ip netns add ns2 添加network namespace ns2
ip netns delete ns3 删除ns3
ip netns exec ns1 ip a 查看namesapce ns1下的网卡情况
ip netns exec ns1 ifup lo 启动namespace ns1
ip netns exec ns1 ip link set lo up 启动namespace ns1
veth pair
不同Namespace下的网络是不互通的
veth pair: virtual ethernet pair, 这是一个成对的端口,可以实现不同命名空间下的网络互通功能。
第一步:首先创建一个成对的veth pair
[root@localhost ~]# ip link add veth-ns1 type veth peer name veth-ns2
第二步:将这对veth pair放到对应的网络空间
[root@localhost ~]# ip link set veth-ns1 netns ns1
[root@localhost ~]# ip link set veth-ns2 netns ns2
设置后可以发现原来的网络下已经没有这两个网卡了
发现网络空间ns1和ns2下分别多了一个网卡
第三步:给网络空间下的veth添加 ip 地址
[root@localhost ~]# ip netns exec ns1 ip addr add 192.168.1.11/24 dev veth-ns1
[root@localhost ~]# ip netns exec ns2 ip addr add 192.168.1.12/24 dev veth-ns2
第四步:启动网络空间
[root@localhost ~]# ip netns exec ns1 ip link set veth-ns1 up
[root@localhost ~]# ip netns exec ns2 ip link set veth-ns2 up
[root@localhost ~]# ip netns exec ns1 ip a
第五步:ping测试,发现可以彼此互通
[root@localhost ~]# ip netns exec ns1 ping 192.168.1.12
[root@localhost ~]# ip netns exec ns2 ping 192.168.1.11
Docker 网络—bridge
通过mysql镜像创建两个容器并启动,可以发现在任意一个容器内部可以ping通另一个容器,说明docker容器之间的网络空间也是使用了类似veth pair的技术。
通过ip link查看,可以发现centos机器上除了有docker0网卡之外,还有两个veth网卡:veth40fa112@if4, vethc5f1cda@if6;而每个mysql容器中也都有一个veth网卡:eth0@if5, eth0@if7;实际上,centos机器上的veth40fa112@if4和容器中的eth0@if5是一对网卡,而vethc5f1cda@if6和eth0@if7是一对网卡,所以centos和容器之间可以进行互通;每个docker容器和centos上的docker0可以互通,所以最终docker容器之间也可以互通。
可以通过 docker network inspect bridge 命令查看发现 docker0 下面有mysql-test和mysql两个容器:
[root@localhost ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "8e853a3216179ad241fffddd05c34d4bd074dbda0dcd94a8f51f610f0b6bd7da",
"Created": "2022-12-25T21:20:34.941851548+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"224f6a2434e6a5a56829656be0460c9835d0cd3dc78e07d8e4354a7a31f9e14b": {
"Name": "mysql-test",
"EndpointID": "ddfe5e9d4ce0ecf05aeb88bcac65f35805ad478b92730556fe6531b97854345b",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"4320e95e85b4837c943555c1f0842eae8b9226d397c43402b8696e823ac49117": {
"Name": "mysql",
"EndpointID": "404c03e20c7afeeecab35d93c12afa6f25752eb110787966e2d0244c873c8937",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/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": {}
}
]
[root@localhost ~]#
总结:centos 能够ping通 docker容器mysql-test 和 容器mysql,因为用了veth技术;两个容器之间也可以ping通,是因为都用了docker0作为一个中间桥梁。
不同网卡之间网络空间如何互通?
如果自定义一个网络,基于这个自定义网络来创建容器:
[root@localhost ~]# docker network create –subnet=172.18.0.0/24 mysql-net
[root@localhost ~]# docker run -d –name mysql2 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root –network mysql-net mysql:5.7
这时可以发现容器mysql-test和容器mysql2是无法互通的,因为他们处于不同的网卡,不同的网段。可以通过下面命令将其他网卡中的容器加入到需要连接的网卡中:
[root@localhost ~]# docker network connect mysql-net mysql-test
[root@localhost ~]# docker network inspect mysql-net
可以发现容器mysql-test也出现在mysql-net网卡的容器列表中,这时不同网段的容器就可以互通了: