虚拟化网络的原理简述

Linux内核支持六种名称空间,只要在用户空间有相应的客户端工具,都可以对对应的名称空间进行操作。

假如物理机有四块网卡,可以创建两个名称空间,此时可灵活将网卡分配到单独的名称空间中。

一般一个设备只能属于一个名称空间,如此每个名称空间都可以配置IP地址,并且和外部通信。

假如名称空间数量超过物理网卡数量,而名称空间中的进程必须通过物理网卡对外通信,如何处理?可以使用虚拟网卡设备,使用纯软件的方式模拟出网卡设备。

在Linux内核级别,支持两种模拟:二层设备和三层设备。

二层设备(链路层)

链路层,实现报文转发的设备。

利用内核对二层设备的模拟,创建虚拟网卡接口,这种网络接口是成对出现的,模拟为一根网线的两头。其中一头插在主机上,另一头插在交换机上。

内核原生支持二层虚拟网桥设备,用软件来构建交换机。比如bridge-utils工具的brctl来实现。

利用软件交换机和软件实现的名称空间,如此就可模拟一个主机连接到交换机中,以实现网络连接的功能。两个名称空间相当于连接到同一台交换机中的两台主机。

以上就是虚拟化网络,是网络虚拟化技术的一种简单实现。

三层设备(软件交换机)

OVS:Open VSwitch 开源的虚拟交换机,能模拟实现高级的三层网络设备如VLAN,VxLAN,GRE等等,它不属于Linux内核本身的模块,因此需要额外安装。它是由思科等众多网络设备生产公司开发的,其功能非常强大。

SDN:软件定义网络/软件驱动网络,需要在硬件层面上支持虚拟化网络,还需要在每个主机上构建复杂的虚拟化网络,来运行多个虚拟机或者容器。

容器间通信

如果在同一个host上的两个namespace需要通信,可以在host上建立虚拟交换机,使用纯软件的方式建立一对网卡,一半在容器上,一半在交换机上。此时只要容器配置同子网的IP地址,即可通信。

如果存在多个交换机,比如两个软件交换机,各自连接不同的容器。比如:

可以创建一对网卡,一半在SW1上,一半在容器中。(docker的默认网络模型就是这个)

如果希望C1仅仅和C3通信,则需要在交换机中间添加路由器,而路由器是三层设备,可以在Linux内核的模块来单独来支持,比如第三个容器(中的内核)来实现报文转发。

如果希望跨主机通信,比如C1和C5通信,如何实现?

方式有:

  • 桥接:

    把host的物理网卡当做交换机使用,各个容器都有自己的虚拟网卡/mac地址,如果需要和本host通信,则将目的mac指向host的虚拟网卡即可。如此可以让C1和C5通信。

    然而这种方式的代价很大,如果都是桥接则所有容器/主机都在同一网络平面上,非常容易产生风暴,隔离性很差。

    因此,在大规模的虚拟化或者容器的场景中,不能选用这种方式。除非使用大二层的网络技术将其隔离,否则,都不应该直接桥接。

  • NAT

    如果希望对外通信,则应该使用nat技术而不是桥接。

    如果C3和C5通信,C3将网关指向了S1,物理机上打开核心转发功能。报文:C3 -> S1 ->(路由表,转发) -> 外部网络。但是报文无法回来,因为C3是私有地址。因此,在C3的报文离开主机前,将IP转换为S1主机上的IP地址,这就是源地址转换。

    如此C5可直接回复给S1。而S1内部的nat表可知道,该报文实际上是属于C3的,因此会自动转发给C3。

    上述通信必须经过nat实现,而且两级的nat代理。因为C5可能也是nat内部。因此S1并看不到C5,除非将C5 DNAT发布出去。

    因此,比如将C5发布到S2的地址和端口,由S2自动将其请求转换到C5中。

    经过SNAT和DNAT转换,效率不高。而且通信的双方并看不到真正的对方。其好处是,网络易于管理。

  • 叠加网络Overlay Network

    这种网络方式不用完全暴露主机,也不用完全隐藏主机。其方式如下:

    • 多个host,创建虚拟桥,让VM连接到虚拟桥上。
    • 在虚拟桥上创建隧道,让C3直接看到C5
    • 物理机可直接通信,C3和C5在同一个地址段内。C3先将报文送给桥,而桥知道C5并不在本地,于是将报文通过物理网卡发出去:在使用隧道转发出去前,报文C3|C5再封装一层IP首部:H1|H2
    • H2拆开第一层封装,看到C3|C5,于是将报文转发给C5.

    上述实现两级的三层封装,使用一个IP承载另一个IP,这就是隧道技术。如此C3和C5就可以直接通信。

模拟容器间通信

使用ip命令,可以在一台主机中构建出一个网络名称空间,并且可模拟容器间通信。

root@eto:~# ip netns help
Usage: ip netns listip netns add NAMEip netns set NAME NETNSIDip [-all] netns delete [NAME]ip netns identify [PID]ip netns pids NAMEip [-all] netns exec [NAME] cmd ...ip netns monitorip netns list-id

通过这种方式只有网络名称空间是隔离的,而其他名称空间都是共享的。和容器略有不同。

  • 创建名称空间

    root@eto:~# ip netns add r1
    root@eto:~# ip netns add r2
    root@eto:~# ip netns list
    r2
    r1
    
  • 创建对应的虚拟网卡对,然后分配到名称空间中

    root@eto:~# ip link add name veth1.1 type veth peer name veth1.2
    root@eto:~# ip link show
    ...
    9: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether 6a:f0:ef:a0:76:80 brd ff:ff:ff:ff:ff:ff
    10: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    
    # 把veth1.2分配到r1中去
    root@eto:~# ip link set dev veth1.2 netns r1
    root@eto:~# ip a s
    ...
    10: veth1.1@if9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether 0e:33:73:c9:73:fc brd ff:ff:ff:ff:ff:ff link-netnsid 0root@eto:~# ip netns exec r1 ifconfig -a
    lo: flags=8<LOOPBACK>  mtu 65536loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0veth1.2: flags=4098<BROADCAST,MULTICAST>  mtu 1500ether 6a:f0:ef:a0:76:80  txqueuelen 1000  (Ethernet)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
  • 修改网卡名称,设置IP地址并激活

    root@eto:~# ip netns exec r1 ip link set dev veth1.2 name eth0
    root@eto:~# ip netns exec r1 ifconfig eth0 10.1.0.2/24 up
    root@eto:~# ifconfig veth1.1 10.1.0.1/24 up
    root@eto:~# ping 10.1.0.2
    PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
    64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.054 ms
    64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.036 ms
    

    此时两张网卡可通信,有宿主机 -> r1

  • 将另一半网卡挪到r2,并激活

    root@eto:~# ip link set dev veth1.1 netns r2
    root@eto:~# ip netns exec r2 ifconfig veth1.1 10.1.0.3/24 up
    root@eto:~# ip netns exec r2 ping 10.1.0.2
    PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
    64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.037 ms
    64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.034 ms
    

    使用这种方式来测试网络通信模型,和虚拟机几乎无区别。可以模拟物理桥,仅主机和nat桥。

Docker的网络

Docker安装完成后,自动提供三种网络:

  • bridge
  • host
  • none
root@eto:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fd3713beb21e        bridge              bridge              local
509f1fdd50fb        host                host                local
83fea3e78ba1        none                null                local

Bridge:本机上创建的软交换机,也可以当做网卡使用。当启动容器时,可自动让容器自动分配一对网卡,一半在容器上,一半在交换机上。比如:

# 启动容器
root@eto:~# docker run --name t1 -it jaywin/httpd:v0.1-1
/ # # 宿主机上,关联到docker0上的网卡设备,其中
root@eto:~# ip a s
...
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:72:ff:55:a2 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
...
6: veth2fadfaf@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default veth2fadfaf@if5 中的if5在容器中,另一端veth2fadfaf在宿主机中。它们连接到了docker0桥上。root@eto:~# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.024272ff55a2       no              veth2fadfaf(宿主机的接口)

Docker0桥默认是一个nat桥,创建容器后会自动分配iptables规则:

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0

只要从docker0桥的网段发出的报文,自动选择一个合适的源地址做SNAT(MASQUERADE)。如此同一个宿主机下的容器,都可以相互通信(属于docker0的二层网络),并且容器可以和外部通信(实现了SNAT)。

如果有一个nginx容器,提供服务。另外一个容器也是连接到桥上来的,则可以直接当客户端来访问nginx。通过如下方式:

  • 物理机上也能直接访问(可以看成是仅主机的桥)
  • 如果是外部的物理机访问nginx,它是无法看到nginx容器,因为nat将容器隐藏在背后。此时需要使用dnat将nginx发布

因此,当使用默认的桥接网络时,只能通过dnat规则以便让外部的客户端访问该容器。

如果同一台主机拥有两个web容器,如何对外做dnat?毕竟只有一个80端口,如何能正常提供访问?如果使用默认的网络模型,并没有很好的解决方法。

如果使用overlay网络,则无需有上述的困扰,直接访问对应的web服务即可。关于overlay网络,暂不表述。

除了上述描述的方式,还有什么方法可以使得容器可以对外服务?比如:

让每个容器仅拥有user,mount,pid是隔离的,两个容器共享UTS,Net,IPC。如此,容器的文件系统,pid和用户是隔离的,而网络是同一组,同一个网络协议栈,同一个域名主机名。容器间的通信可直接通过lo实现。

共享的一般是和网络通信相关的资源。

也可以让容器直接使用物理名称空间。

如果容器仅使用none网络,则容器仅有lo,没有网卡,无网络通信功能

Docker网络模型

Docker创建容器时,使用选项–network来指定使用哪种网络模型。默认default为bridge (docker0)

查看网络的详细信息:

root@eto:~# docker network inspect bridge

Docker的网络名称空间和UTS,IPC是可以让容器共享的,因此可构建出隔离,桥接,nat等网络模型。

docker网络模型

四种网络模型:

  • 封闭式容器
  • 桥接式容器:容器包含虚拟网络设备,一半在docker0上,一半在名称空间中。默认情况下,容器是启动为桥接式的网络模型。
  • 联盟式容器:容器a有自己的名称空间,容器b共享容器a的名称空间。可以让a和b的容器应用在本地通信
  • 容器共享宿主机的名称空间

可以指定为封闭式容器:

root@eto:~# docker run --name t4 -it --network none --rm busybox:latest
/ # ifconfig -a
lo        Link encap:Local Loopback  inet addr:127.0.0.1  Mask:255.0.0.0UP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Bridge可以实现不同容器间通信,而主机名默认为容器id,可使用hostname设置或者run的时候指定hostname,从容器外注入主机名。

# 查看默认主机名
root@eto:~# docker run --name t4 -it --network bridge --rm busybox:latest hostname
3ccdfa0745a3# 注入主机名
root@eto:~# docker run --name t4 -it --network bridge -h t2.jaywin.com --rm busybox:latest
/ # hostname
t2.jaywin.com

也可以注入解析,默认情况下容器使用宿主机的DNS配置。

/ # cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      t2.jaywin.com t2

可自定义DNS服务器

root@eto:~# docker run --name t4 -it --network bridge -h t2.jaywin.com --dns 114.114.114.114 --rm busybox:latest cat /etc/resolv.conf
search midea.com.cn
nameserver 114.114.114.114

定义搜索域

root@eto:~# docker run --name t4 -it --network bridge -h t2.jaywin.com --dns 114.114.114.114 --dns-search ilinux.io --rm busybox:latest cat /etc/resolv.conf
search ilinux.io
nameserver 114.114.114.114

添加hosts记录

root@eto:~# docker run --name t4 -it --network bridge -h t2.jaywin.com --dns 114.114.114.114 --dns-search ilinux.io --add-host www.jaywin.com:1.1.1.1 --rm busybox:latest cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
1.1.1.1 www.jaywin.com
172.17.0.2      t2.jaywin.com t2

服务的暴露方式

使用-p选项进行服务暴露

动态端口暴露

root@eto:~# docker run --name w1 --rm -p 80 jaywin/httpd:v0.2root@eto:~# docker port w1
80/tcp -> 0.0.0.0:32768
# 暴露随机端口

实际上,通过DNAT规则将服务发布出去。

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:32768 to:172.17.0.2:80
# 只要访问本机的32768端口,将DNAT到172.17.0.2:80
# 当删除容器时,nat规则也会一并移除

固定地址的动态端口暴露

root@eto:~# docker run --name w1 --rm -p 192.168.2.10::80 jaywin/httpd:v0.2root@eto:~# docker port w1
80/tcp -> 192.168.2.10:32768

固定端口暴露

# 将端口暴露在宿主机的指定端口:
root@eto:~# docker run --name w1 --rm -p 80:80 jaywin/httpd:v0.2root@eto:~# docker port w1
80/tcp -> 0.0.0.0:80

-p选项可以使用多次,以暴露多个端口。

暴露所有端口

-P选项或者–publish-all,将容器所有计划要暴露的端口全部映射至主机端口。

计划 要暴露的端口需要使用–expose选项指定

# docker run -d -P --expose 2222 --expose 3333 --name web busybox:latest /bin/httpd -p 2222 -f

联盟式容器Joined containers

联盟式容器是指使用某个已存在容器的网络接口的容器,接口被联盟内各容器共享使用。因此,联盟式容器彼此间完全无隔离。

联盟式容器彼此间虽然共享同一个网络名词空间,但其他名称空间如User、Mount等还是隔离的

联盟式容器彼此间存在端口冲突的可能。因此,通常只会在多个容器上的程序需要程序loopback接口相互通信,或者对某个已存在的容器的网络属性进行监控时,才使用这种模式的网络模型

创建联盟式容器

root@eto:~# docker run --name b2 --rm --network container:w1 -it busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:16 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1256 (1.2 KiB)  TX bytes:0 (0.0 B)lo        Link encap:Local Loopback  inet addr:127.0.0.1  Mask:255.0.0.0UP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)# 此时b2和W1共享网络名称空间,而其他资源是隔离的。此时,b2可通过lo口访问w1的httpd服务。
# 如此相当于同一主机上的两个进程。/ # wget -O - -q 127.0.0.1
busybox http server
# 容器和宿主机的联盟式网络
root@eto:~# docker run --name b2 --rm --network host -it busybox:latest
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:72:FF:55:A2  inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0inet6 addr: fe80::42:72ff:feff:55a2/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:19 errors:0 dropped:0 overruns:0 frame:0TX packets:38 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1289 (1.2 KiB)  TX bytes:3578 (3.4 KiB)

如此一来,将十分简便地部署应用,并利用宿主机的网络。

修改docker0上的网络信息

自定义docker0桥的网络属性信息:

root@eto:~# cat /etc/docker/daemon.json
{"exec-opts": ["native.cgrounpdriver=systemd"],"registry-mirrors": ["https://e2615hzs.mirror.aliyuncs.com"],"bip": "192.168.1.0/24"}# 核心选项bip,即bridge ip之意,用于指定docker0桥自身的IP地址
# 修改docker0的地址后,启动容器的地址也会随之改变。

dockerd默认监听在Unix Socket格式的地址:/var/run/docker.sock。如果使用TCP套接字,则修改配置文件选项为:

"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]

也可以向dockerd直接传递"-H | --host"选项。在ubuntu上,如果docker.service指定了-H fd,此处再设置hosts时会无法启动。此时可以将docker.service中的-H选项去掉即可。

此时客户端就可以通过-H,指定要连接的服务器地址:

root@eto:~# docker -H 192.168.2.10:2375 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

创建自定义桥设备

root@eto:~# docker network create -d bridge --subnet "192.168.100.0/24" --gateway "192.168.100.1" mybr0
eb582031756ecb64541e6c95dd23caf1ece1c5b87378438cf6661b250b887052
root@eto:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f3f514b6596c        bridge              bridge              local
509f1fdd50fb        host                host                local
eb582031756e        mybr0               bridge              local
83fea3e78ba1        none                null                local

将容器和mybr0桥接

root@eto:~# docker run --name t4 -it --net mybr0 busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:64:02  inet addr:192.168.100.2  Bcast:192.168.100.255  Mask:255.255.255.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:12 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1032 (1.0 KiB)  TX bytes:0 (0.0 B)

再创建一个容器,桥接到docker0

root@eto:~# docker run --name b2 -it --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:8 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:696 (696.0 B)  TX bytes:0 (0.0 B)

这两个容器可以相互通信,默认做nat地址转换,只需要宿主机打开forward转发,并清空此规则:

root@eto:~# iptables -F  DOCKER-ISOLATION-STAGE-1

此规则包含限制不同容器网络之间的访问的规则:

target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

如此就可以通信了:

/ # ping 192.168.100.2
PING 192.168.100.2 (192.168.100.2): 56 data bytes
ip64 bytes from 192.168.100.2: seq=125 ttl=63 time=0.133 ms
64 bytes from 192.168.100.2: seq=126 ttl=63 time=0.074 ms
64 bytes from 192.168.100.2: seq=127 ttl=63 time=0.168 ms

Docker学习之四:容器虚拟化网络与docker网络相关推荐

  1. Docker学习:容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,重点介绍容器网络模式, 属于了解范畴,充分了容器的网络模式,更有助于更好的理解Docker的容器之间的访问逻辑. 疑问:为什么要了解容器 ...

  2. docker学习(容器虚拟化技术---华子需要)

    文章目录 Docker是什么 docker安装 step1: 卸载旧的docker容器 step2: 需要的安装包环境 step3: 设置镜像的仓库 step4: 安装社区版的docker step5 ...

  3. docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]

    docker学习大纲 docker概述 docker安装 docker命令 镜像命令 容器命令 操作命令 - docker镜像 容器数据卷 dockerfile docker网络原理 IDEA整合do ...

  4. [转]Docker学习之四:使用docker安装mysql

    本文转自:https://blog.csdn.net/qq_19348391/article/details/82998391 Docker学习之一:注册Docker Hub账号 Docker学习之二 ...

  5. nas4free 安装mysql_[转]Docker学习之四:使用docker安装mysql

    Docker学习之一:注册Docker Hub账号 Docker学习之二:Docker基本简单操作命令 Docker学习之三:Docker在linux下简单安装使用 Docker学习之四:使用dock ...

  6. docker学习笔记(四)使用docker搭建环境

    参考:汤小洋老师的教学视频 docker学习笔记(一)[docker 介绍.卸载.安装.配置加速] docker学习笔记(二)docker常用命令 docker学习笔记(三)镜像 docker学习笔记 ...

  7. Docker 学习1 容器技术基础入门

    一.容器是什么 二.虚拟化 1.主机级别虚拟化(两种):虚拟化整个完整的物理硬件平台,比如vmware,可以让我们拿到的虚拟机就像一个裸的物理设备一样.让我们自由的安装操作系统和使用操作系统,安装的操 ...

  8. Docker学习:容器间数据挂载与共享 | 远程共享挂载数据卷 | sshfs挂载远程volume | 容器内部通过sshfs访问远程主机 | -v |--volumes-from(实战篇)

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,主要介绍宿主.容器间数据共享,它的好处自然不言而喻,Tomcat集群就是这么玩儿的(多个tomcat服务,对应一套web应用). 核心原 ...

  9. docker swarm MySQL_容器与云|在 Docker 中运行 MySQL:多主机网络下 Docker Swarm 模式的容器管理...

    本文将以多主机网络环境为基础,探讨如何利用内置编排工具 Docker Swarm 模式对各主机上的容器加以管理. Docker Engine – Swarm 模式 在多台主机之上运行 MySQL 容器 ...

最新文章

  1. 演示:标准ACL的配置、及使用技巧、和相关局限
  2. 深入理解分布式技术 - ServiceMesh 服务网格
  3. Hadoop RPC客户端调用服务代码示例
  4. python去除特殊字符_python去除BOM头\ufeff等特殊字符
  5. codeforces gym-101741 Elevator 动态规划、单调队列
  6. 和redis_Redis 缓存
  7. 将整个表单设置为只读_如何将独立网站设置为制作中,阻止搜索引擎收录网站页面?...
  8. linux 删除sysadm用户,linux 用户和组命令整理及详细介绍
  9. Java集合类学习总结
  10. Java层Binder使用(ServiceManager)
  11. 如何下载spring源码?
  12. xp 计算机配置,怎么查看WindowsXP系统电脑配置?
  13. python的pth打开方式_python .pth 文件 和 site 模块
  14. 病毒茶几 U盘里的恶魔——Autorun病毒
  15. “毒液” 高危漏洞背后的技术较量
  16. Android加载web页时有的手机会弹出手机自带的浏览器解决方法
  17. cv2.warpAffine
  18. 服务器返回的常见http状态码
  19. latex论文排版初级应用
  20. Spring入门基础

热门文章

  1. Speedoffice(Word)怎样设置页眉页脚高度
  2. 批量图片重命名(excel、代码实现)
  3. 表格的属性、表格的合并及表单
  4. Android开发之摇一摇
  5. 同居mm_倾向于同居
  6. 【python】文件读取写 open的方式with的方式 异常报错处理
  7. matlab/simulink中自定义m-s函数作为simulink模块使用实例
  8. 别套模板了 这款宝藏AE插件一键解决画面排版
  9. 微信开放平台创建应用时应用官网的问题
  10. 如何将音乐添加到PowerPoint演示文稿