文章目录
之前咱们写过docker的基础:
docker的介绍、安装、基础命令、数据卷、DockerFile等方面的知识。
👉最全docker-初级篇
现在咱们开始docker的高级篇!
二、高级篇
1、Network
首先记牢Docker网络官网:https://docs.docker.com/network/
1.1、网络介绍
当前咱们搭建了docker的容器之后,容器和容器之间是需要通讯的,如果不能通讯,容器作用和价值就不大了。
比如:咱们启动了两个容器,一个项目的容器,一个Redis的容器,项目是需要链接redis的,这就构成了两个容器的网络通讯。甚至容器在不同的宿主机上,无法通讯的话,docker基本上没啥用了。
关于Docker容器的构成
Docker是基于Linux Kernel的namespace,CGroups,UnionFileSystem等技术封装成的一种自定义容器格式,从而提供了一套虚拟运行环境。
Linux Kernel:linux的内核
namespace:命名空间。他的作用是用来过隔离的,他可以隔离很多东西,比如 pid[进程]、net【网络】、mnt【挂载点】等。
CGroups:即Controller Groups,他是用来做资源限制,比如内存和CPU等。
Union File Systems:联合文件系统(也就是卷,基础篇中讲过),用来做Image和Container分层
1.2、计算机网络模型
关于docker中的分层思想,其实在计算机中很多地方,都能体现到这一思想。例如:网络模型
1.2.1、网络模型和概念模型

1.2.2、数据的分层封装
1.2.2.1 客户端发送请求
解释
-
客户端发起请求首先在应用层,生成
HTTP报文的请求行,请求头,请求体。并将HTTP协议报文发送到传输层。

-
传输层在此报文的基础上封装上
TCP头信息,即客户端的端口,服务端的端口,并将封装过后的报文发送到网络层。 -
网络层在此基础上继续封装上
IP头信息,封装上客户端IP以及服务端IP,并将报文发送到网络接口层。 -
网络接口层,会再封装,添加上
MAC头信息,即客户端的MAC地址以及网关MAC,然后将封装好的报文转成二进制码,发到客户端
1.2.2.2 服务端接受请求
解释:
- 请求经过物理层的传输到达服务器后。首先需要经过网络接口层,他会将二进制的数据转成客户端封装后的报文。
- 然后,网络接口层会从报文中先解析出
MAC头信息,验证MAC是否正确。正确,则继续下一层,并将报文发送到网络层。 - 网络层接收到报文后,进行第二层的解析,将
IP头信息解析出来,并验证是否正确。正确,则将信息发送到传输层。 - 传输层再次解析出报文中的
TCP头信息,并验证服务端端口是正确,并且端口已经开放。都没问题,则将信息发送到应用层。 - 应用层则将最后的
HTTP协议报文转成HttpServletRequest对象发送给服务。
1.3、Linux中的网卡
1.3.1、查看网卡及其作用
在知道docker是如何通信的之前,先来看一下Linux的中的网卡是如何通信。毕竟原理是相通的,弄懂一个,其他的就都懂了。
[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:22:7c:7a brd ff:ff:ff:ff:ff:ff
inet 10.19.6.104/16 brd 10.19.255.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::420c:3702:e936:a686/64 scope link noprefixroute
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:9a:99:34:1b 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 ~]#
通过命令ip a 查看系统中的所有网卡信息。
| 网卡名称 | 干嘛用的 |
|---|---|
| lo | 回环网卡,也就是本地网卡,他主要是模拟网络接口层,解析报文发送给自己(解析网络地址)。 **举个例子:**计算机上有两个服务,服务1访问服务2,没有回环网卡,发送的数据报文就会走完传输层和网络层所有过程,再发给自己;但是有了回环网卡,就不用走这个路径,通过回环网卡解析报文,就可以发送自己。 |
| ens33 | 网络网卡,他的作用是,与外面网络进行链接 |
| docker0 | docker的网卡。docker安装后,会生成一个docker的网卡 |
网卡配置信息解释如下:
UP: 网卡处于活动状态
BROADCAST: 支持广播
RUNNING: 网线已接入
MULTICAST: 支持组播
MTU: 最大传输单元(字节),即此接口一次所能传输的最大封包
inet: 显示IPv4地址行
inet6: 显示IPv6地址行
link/enther: 指设备硬件(MAC)地址
txqueuelen: 传输缓存区长度大小
RX packets: 接收的数据包
TX packets: 发送的数据包
errors: 总的收包的错误数量
dropped: 由于各种原因, 导致拷贝在内存过程中被丢弃
collisions: 网络信号冲突情况, 值不为0则可能存在网络故障
关于网卡的这信息的详细解释,请看👉网络基础管理
查看网卡的其他命令
[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:22:7c:7a 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:9a:99:34:1b brd ff:ff:ff:ff:ff:ff
# 以文件的形式查看网卡
[root@localhost ~]# ls /sys/class/net/
docker0 ens33 lo

1.3.2、网卡的配置文件
这个文件主要是给网卡配置固定IP
[root@localhost ~]# cd /etc/sysconfig/network-scripts/
# 这个目录下面有好多文件,咱们就加条件筛选一下
[root@localhost network-scripts]# ls | grep ifcfg
ifcfg-lo
ifcfg-ens33
----------------------------
# 自己 建的文件 dhcp的
ifcfg-ens33.dhcp.bak
# 自己建的文件 配置静态Ip
ifcfg-ens33.static.bak
根据你的网卡个数,就会有几个配置文件。lo对应ifcfg-lo、ens33对应ifcfg-ens33 、docker0是虚拟网卡没有配置文件。
对于固定Ip的设定,这里不讲。

1.3.3、网卡操作
# 给网卡增加ip
ip addr add 192.168.100.120/24 dev ens33
# 删除网卡的ip
ip addr delete 192.168.100.120/24 dev ens33


1.4、NameSpace
接下来看,第二个知识点NameSpace。
Network Namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。
这也就是docker的容器在运行中是如何和其他网络隔离的。
拓展知识 关于windows的网络操作👉:Windows网络命令汇总
1.4.1、NameSpace操作
1.4.1.1、namespace基本操作
#查看当前所有的namespace
ip netns list
#增加一个 名为【ns1】的namespace
ip netns add ns1
#删除【ns1】这个namespace
ip netns delete ns1
#查看namespace【ns1】的网卡情况。exec跟docker的exec命令差不多,都可以理解为进入/登录的意思。
#通过 exec登录名为【ns1】的namespace,执行【ip a】命令
ip netns exec ns1 ip a
最后形成这样的图才对。

1.4.1.2、namespace内网卡的启动与关闭
#----------ip命令--------------
# 打开(ns1的lo)网卡
ip nets exec ns1 ifup lo
# 关闭(ns1的lo)网卡
ip nets exec ns1 ifdown lo
#----------link命令--------------
#通过link命令来启动网卡
ip netns exec ns1 ip link set lo up
#通过link命令来关闭网卡
ip netns exec ns1 ip link set lo down


1.4.2、不同namespace网卡的通讯
要想实现不同namespace下的网卡通讯,需要用到的技术就是:
veth pair:Virtual Ethernet Pair,是一个成对的端口,可以实现上述功能。示意图图下:

接下来命令实操
#首先创建两个namespace【ns1】【ns2】
#创建成对的 veth pair网卡 veth1 以及 veth2
ip link add veth1 type veth peer name veth2
# 将网卡 veth1 交给 ns1
ip link set veth1 netns ns1
# 将网卡 veth2 交给 ns2
ip link set veth2 netns ns2

#分别查询两个namespace就会发现之前新增的两个网卡
ip netns exec ns1 ip link
ip netns exec ns2 ip link

#想要通讯,需要增加ip地址。给两个网卡增加新的ip地址。注意:网卡和namespace一定要对应好
ip netns exec ns1 ip addr add 192.168.0.11/24 dev eth1
ip netns exec ns2 ip addr add 192.168.0.11/24 dev eth2

#分别启动两个网卡
ip netns exec ns1 ip link set veth1 up
ip netns exec ns2 ip link set veth2 up
# 然后需要互相ping
ip netns exec ns1 ping 192.168.0.12
ip netns exec ns2 ping 192.168.0.11

1.4.3、【docker】Container的NameSpace
Docker使用了Linux的Namespaces技术来进行资源隔离,如PTD Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
按照上面的描述,docker的每个container,都会有自己的network namespace,并且是独立的。接下验证咱们的猜想。
-
使用
docker pull centos:7命令,下载centos镜像(之所以使用centos,不直接使用tomcat镜像,是因为tomcat镜像里没有ip命令) -
创建tomcatDockerFile文件,并进行编写
FROM centos MAINTAINER bugaosuni ADD apache-tomcat-8.5.93.tar.gz /usr/local/ ENV MYPATH /usr/local WORKDIR $MYPATH #配置tomcat环境变量 ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.93 ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.93 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat CMD ["/usr/local/apache-tomcat-8.5.93/bin/catalina.sh","run"] -
构建自定义tomcat镜像
docker build -f tomcatDockerFile -t tomcat_custom:1.0.0 . -
运行tomcat镜像
docker run -d --name tomcat01 -p 8081:8080 tomcat_custom:1.0.0 docker run -d --name tomcat02 -p 8082:8080 tomcat_custom:1.0.0 -
进入容器查看ip
docker exec -it tomcat01 ip a docker exec -it tomcat02 ip a

通过上面的图片,咱们就可以看到,每个容器都有自己一套网卡,容器和容器是相互隔离的。
仔细看就会发现他们的网卡eth0绑定的不是同一个MAC,网卡名字也是不相同的。
他们能够相互PING的通,原理是相同的,但是他们的网卡通信却不是veth-pair技术,而是Bridge技术。
1.5、docker的Container网络模式
执行命令docker network ls就会发现docker中存在三种网络模式。
[root@localhost tomcat]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b6147ac32cc8 bridge bridge local
8673ae77bb8a host host local
5f2ed6e8566d none null local
也就是 bridge、host、none。
注意:docker的网络模式其实是4种,还有一种container模式,类似于host模式。
1.5.1、VMware虚拟机的网络模式
了解docker的网络模式之前,先来了解一下虚拟机的网络模式,毕竟一法通百法明。
打开VMware Workstation Pro -->虚拟机–>设置–>网络适配器。就会弹出下图。

-
桥接模式:在这种模式下,VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。
在桥接模式下,你需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信。
同时,由于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。即此虚拟机可以和局域网中的其他主机互相通信。
-
使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟系统里访问互联网。
NAT模式下的虚拟系统的TCP/IP配置信息是由
VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机器能访问互联网即可。
-
仅主机模式:在此模式下所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的。
此模式下,虚拟系统和宿主机器系统是可以相互通信的,相当于这两台机器通过双绞线互连。
此模式下,虚拟系统的TCP/IP配置信息(如
IP地址、网关地址、DNS服务器等),都是由VMnet1(host-only)虚拟网络的DHCP服务器来动态分配的。
1.5.2、Bridge模式
咱们容器的网卡不是veth-pair技术生成的成对的网卡,那他们是如何PING的呢?
他们用的是Bridge,也就是咱们平常经常说的桥接模式!
通过命令查询宿主机IP,就会发现宿主机又多了两个网卡。
对比容器内的网卡就会发现网卡的规律
其最后的网卡示意图,是如下所示的。
容器的网卡都在各自的容器内,和容器通讯的网卡则在宿主机上,eth0@if11和vethb598148@if10则构成了成对的网卡。而宿主机上的两个网卡vethb598148@if10和veth7736952@if14则都在docker0网桥中。
咱们使用 ip netns list 发现不了docker0网桥的,那如何验证宿主机上的两个网卡都在docker0中呢?
开始验证
#安装 网桥工具 bridge-utils
yum install bridge-utils
#执行命令
brctl show
#创建名为<网桥名>的网桥
brctl addbr <网桥名>
#卸载网桥上的端口
brctl delif <网桥名> <端口名>
#查看是否有网桥网卡名
ifconfig
#关闭此网卡
ifconfig <网桥名> down
#删除网桥
brctl delbr <网桥名>
这个时候,咱么就会发现这网桥docker0存在连个interfaces分别对应咱们宿主机上的两个网卡。那现在这张图,证明咱们上面画的那张图是正确的。
这种网络连接方式,咱们叫Bridge,也就是网桥技术。
容器默认的网络是桥接模式(自己搭建的网络默认使用桥接模式,启动容器默认也是使用桥接模式)。
此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。

查看docker的网络模式
通过执行docker network inspect bridge 就会发现,咱们的两个容器tomcat01、tomcat02 都是桥接的。
[root@localhost tomcat]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "b6147ac32cc846ab99901aa99d7ec2f820d36e5733acf4bbacee874f07e1205e",
"Created": "2023-10-08T09:09:09.869331457+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,
"ConfigFro

最低0.47元/天 解锁文章

7254

被折叠的 条评论
为什么被折叠?



