容器编排、集群部署

Docker0

清空所有镜像

  1. #查看运行的容器
  2. docker ps
  3. #停掉所有正在运行的容器(否则删除不掉)
  4. docker stop [containerID] # docker stop $(docker container ls -q)
  5. #执行删除
  6. docker rmi -f $(docker images -aq)
  7. #查看镜像
  8. docker images

查看网卡信息

  1. #获取当前网卡ip地址和mac地址
  2. ip addr
  3. lo 本机回环地址 127.0.0.1
  4. eth0 阿里云内网地址 172.31.81.32
  5. docker0 docker生成的网卡 172.17.0.1
  6. [root@--- ~]# ip addr
  7. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  8. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  9. inet 127.0.0.1/8 scope host lo
  10. valid_lft forever preferred_lft forever
  11. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  12. link/ether 00:16:3e:0a:00:34 brd ff:ff:ff:ff:ff:ff
  13. inet 172.31.81.32/20 brd 172.31.95.255 scope global dynamic eth0
  14. valid_lft 291944112sec preferred_lft 291944112sec
  15. 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
  16. link/ether 02:42:a4:2f:c5:62 brd ff:ff:ff:ff:ff:ff
  17. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  18. valid_lft forever preferred_lft forever
  19. [root@--- ~]#

运行容器之后,再次查看网卡信息

安装Docker时,它会自动创建三个网络,默认bridge网桥(创建容器默认连接到此网络)、 none 、host

  1. # 运行mysql01,centos01,centos02容器
  2. # 启动时,docker默认的bridge网桥,docker0给容器服务自动分配ip
  3. docker run -it --name mysql01 -e MYSQL_ROOT_PASSWORD=123 mysql:5.7
  4. docker run -it --name centos01 centos /bin/bash
  5. docker run -it --name centos02 centos /bin/bash
  6. # 查看ip、mac地址信息
  7. # 可以看到上面启动的三个容器服务的mac信息
  8. ip addr
  9. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  10. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  11. inet 127.0.0.1/8 scope host lo
  12. valid_lft forever preferred_lft forever
  13. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  14. link/ether 00:16:3e:0a:00:34 brd ff:ff:ff:ff:ff:ff
  15. inet 172.31.81.32/20 brd 172.31.95.255 scope global dynamic eth0
  16. valid_lft 291916543sec preferred_lft 291916543sec
  17. 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  18. link/ether 02:42:a4:2f:c5:62 brd ff:ff:ff:ff:ff:ff
  19. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  20. valid_lft forever preferred_lft forever
  21. 140: br-799426d70aa2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
  22. link/ether 02:42:7f:01:1d:00 brd ff:ff:ff:ff:ff:ff
  23. inet 172.18.0.1/16 brd 172.18.255.255 scope global br-799426d70aa2
  24. valid_lft forever preferred_lft forever
  25. 154: vethe3da564@if153: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
  26. link/ether ea:84:fb:14:47:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  27. 156: veth6477da5@if155: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
  28. link/ether 86:35:30:8d:14:85 brd ff:ff:ff:ff:ff:ff link-netnsid 1
  29. 158: veth17b2712@if157: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
  30. link/ether 72:76:f0:3c:17:e8 brd ff:ff:ff:ff:ff:ff link-netnsid 2
  31. # 查看docker网络
  32. [root@--- ~]# docker network ls
  33. NETWORK ID NAME DRIVER SCOPE
  34. feafa30d4051 bridge bridge local
  35. e8bf4fced9e2 host host local
  36. 6263db0933b9 none null local
  37. [root@--- ~]#
  38. # 查看默认bridge网桥(docker0)
  39. [root@--- ~]# docker network inspect feafa30d4051
  40. [
  41. {
  42. "Name": "bridge",
  43. "Id": "feafa30d4051f24353508959bd420fd163ad0c98d6b30ec8ff13b59a59552bb1",
  44. "Created": "2021-09-26T15:10:27.167774553+08:00",
  45. "Scope": "local",
  46. "Driver": "bridge",
  47. "EnableIPv6": false,
  48. "IPAM": {
  49. "Driver": "default",
  50. "Options": null,
  51. "Config": [
  52. {
  53. "Subnet": "172.17.0.0/16",
  54. "Gateway": "172.17.0.1"
  55. }
  56. ]
  57. },
  58. "Internal": false,
  59. "Attachable": false,
  60. "Ingress": false,
  61. "ConfigFrom": {
  62. "Network": ""
  63. },
  64. "ConfigOnly": false,
  65. "Containers": {
  66. "29298987c51b777b546bf6626560020ce235e390e1d7fcfe188c6db228ca4edf": {
  67. "Name": "mysql01",
  68. "EndpointID": "f6572c49234f74a6c0b652a379bb386f843ebd23b02abd59b1f6a9d1c9534b17",
  69. "MacAddress": "02:42:ac:11:00:02",
  70. "IPv4Address": "172.17.0.2/16", # 容器的IP
  71. "IPv6Address": ""
  72. },
  73. "cb1922b95b9316d129b54f3545fad9729092926e10a1d5517f8928db42706151": {
  74. "Name": "centos01",
  75. "EndpointID": "ef6cfa74f56bfa4f49143aa08cf323812002236bc63f75204dee7c3ec1162250",
  76. "MacAddress": "02:42:ac:11:00:03",
  77. "IPv4Address": "172.17.0.3/16", # 容器的IP
  78. "IPv6Address": ""
  79. },
  80. "cc6f510b9765ba018dbafd416c9774ddf5fd3ff55fa992827f55516e8dc70b6a": {
  81. "Name": "centos02",
  82. "EndpointID": "2f901aec8f8b455d1fb06112c9035a19f34cc597d8907f26f1b896f12d7eb7ba",
  83. "MacAddress": "02:42:ac:11:00:04",
  84. "IPv4Address": "172.17.0.4/16", # 容器的IP
  85. "IPv6Address": ""
  86. }
  87. },
  88. "Options": {
  89. "com.docker.network.bridge.default_bridge": "true",
  90. "com.docker.network.bridge.enable_icc": "true",
  91. "com.docker.network.bridge.enable_ip_masquerade": "true",
  92. "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  93. "com.docker.network.bridge.name": "docker0",
  94. "com.docker.network.driver.mtu": "1500"
  95. },
  96. "Labels": {}
  97. }
  98. ]

进入centos01,ping mysql容器的ip可以ping通,但是ping不同容器名

  1. docker exec -it cb1922b95b93 /bin/bash
  2. ping 172.17.0.2
  3. # docker0不支持容器名连接访问
  4. ping mysql01
  5. ping: mysql01: Name or service not known
  6. docker run 启动镜像的时候docker都会分配一个网卡地址
  7. #查看运行容器的ip
  8. docker inspect 容器ID | grep IPAddress

image.png

原理

只要我们安装了docker,就会有一个网卡docker0(相当于一个路由器),每启动一个docker容器,dockers都会给docker容器分配一个ip(连接路由器的终端,同一网段下终端可以互相通信), 通过evth-pair技术实现,evth-pair就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连,evth-pair充当一个桥梁,连接各种虚拟网络设备。 Docker网络使用的是Linux的桥接,宿主机是docker容器的网桥,docker0,最多分配65535个 删除容器之后,虚拟网卡就自动消失了。(虚拟网卡传递效率高!)

image.png
启动容器不设置网络,容器ip由docker0自动分配情况下,容器间的通信,要经过evth-pair技术实现,并不是直连的。
image.png
结论
tomcat01,tomcat02是公用的一个路由器,docker0
所有的容器启动时,如果不指定网络的情况下,都是docker0路由的。65535

image.png

Docker的网络驱动模型

Docker的网络驱动模型分类:

  1. bridge:Docker中默认的网络驱动模型,在启动容器时如果不指定则默认为此驱动类型;
  2. host:打破Docker容器与宿主机之间的网络隔离,直接使用宿主机的网络环境,该模型仅适用于Docker17.6及以上版本;
  3. overlay:可以连接多个docker守护进程或者满足集群服务之间的通信;适用于不同宿主机上的docker容器之间的通信;
  4. macvlan:可以为docker容器分配MAC地址,使其像真实的物理机一样运行;
  5. none:即禁用了网络驱动,需要自己手动自定义网络驱动配置;
  6. plugins:使用第三方网络驱动插件;
    1. # 查看docker网络
    2. [root@--- ~]# docker network ls
    3. NETWORK ID NAME DRIVER SCOPE
    4. feafa30d4051 bridge bridge local
    5. e8bf4fced9e2 host host local
    6. 6263db0933b9 none null local
    7. [root@--- ~]#
    Docker内置这三个网络,运行容器时,你可以使用该—network标志来指定容器应连接到哪些网络。
    该bridge网络代表docker0所有Docker安装中存在的网络。除非你使用该docker run —network=选项指定,否则Docker守护程序默认将容器连接到此网络。
    我们在使用docker run创建Docker容器时,可以用 —net 选项指定容器的网络模式,Docker可以有以下4种网络模式:
    host模式:使用 —net=host 指定。
    none模式:使用 —net=none 指定。
    bridge模式:使用 —net=bridge 指定,默认设置。
    container模式:使用 —net=container:NAME_or_ID 指定。
    1. docker run -it -P --name tomcat01 --net=bridge tomcat # 默认设置
    2. docker run -it -P --name tomcat02 --net=none tomcat
    3. ...

    容器通信问题

    由于不同容器通过veth pair连接在虚拟网桥docker0上,所以容器之间可以通过IP互相通信,但是无法通过容器名进行通信。docker0不支持容器名连接访问 默认网桥bridge上的容器只能通过IP互连,无法通过DNS解析名称或别名。假如我们在container1中部署了Web服务,在container2中部署了mysql,container1中的Web服务往往需要连接container2的mysql,这是只能靠IP进行连接,但是docker也无法保证容器重启后的IP地址不变,所以更好的方式是通过别名进行互联,在网络中加入DNS服务器,将容器名与IP地址进行匹配,省去了手动修改Web服务中连接mysql的IP的过程。

    为了实现不同容器通过容器名或别名的互连,docker提供了以下几种: 1、在启动docker容器时加入—link参数,但是目前已经被废弃,废弃的主要原因是需要在连接的两个容器上都创建—link选项,当互连的容器数量较多时,操作的复杂度会显著增加; 2、启动docker容器后进入容器并修改 /etc/hosts 配置文件,缺点是手动配置较为繁杂; 3、用户自定义bridge网桥,这是目前解决此类问题的主要方法,提供更好的隔离效果和更好的互通性(更好的隔离效果是针对外界网络,而更好的互通性则是指同一bridge下的不同容器之间),用户自定义bridge在容器之间提供了自动DNS解析。

容器在默认情况下以隔离方式运行,它们完全不知道同一计算机上有其他进程或容器。 那么,如何使容器能够彼此通信? 答案就是网络连接。 如果两个容器在同一网络上,那么它们可彼此通信。 如果没在同一网络上,则没法通信。

容器之间通信的主要方式

1、通过容器ip访问

  1. 容器重启后,ip会发生变化。通过容器ip访问不是一个好的方案。

2、通过宿主机的ip:port访问

  1. 通过宿主机的ip:port访问,只能依靠监听在暴露出的端口的进程来进行有限的通信。

3、通过—link建立连接(官方不推荐使用)

  1. 运行容器时,指定参数link,使得源容器与被链接的容器可以进行相互通信,并且接受的容器可以获得源容器的一些数据,比如:环境变量。<br />与/etc/hosts中的主机条目不同,如果重新启动源容器,则不会自动更新存储在环境变量中的IP地址。我们建议使用主机条目 /etc/hosts来解析链接容器的IP地址。<br />除了环境变量之外,Docker还将源容器的主机条目添加到/etc/hosts文件中。
  1. # 启动tomcat01,tomcat02
  2. docker run -it -P --name tomcat01 tomcat
  3. docker run -it -P --name tomcat02 tomcat
  4. --link 通过配置 /etc/hosts 实现连接,
  5. # 通过link建立连接的容器,被链接的容器能 ping 通源容器,反过来不行。
  6. # 被链接容器会继承源容器的环境变量信息
  7. docker run -it -P --name tomcat03 --link tomcat02 tomcat
  8. # 查看tomcat03 hosts配置
  9. [root@--- ~]# docker exec -it tomcat03 cat /etc/hosts
  10. 127.0.0.1 localhost
  11. ::1 localhost ip6-localhost ip6-loopback
  12. fe00::0 ip6-localnet
  13. ff00::0 ip6-mcastprefix
  14. ff02::1 ip6-allnodes
  15. ff02::2 ip6-allrouters
  16. 172.17.0.3 tomcat02 099602f3ff7f # --link命令配置生成的条目
  17. 172.17.0.4 a20a10b7e728
  18. [root@--- ~]#

4、🧨通过 User-defined networks(推荐)

用户自定义网桥

  1. # 1、创建用户自定义bridge网桥
  2. [root@--- ~]# docker network create test-network
  3. 799426d70aa28b73b4a777c85b338186eafadd1558b13c43e07a9fd9a8b545e7
  4. [root@iZm5e23n3ueobwkjtfartxZ ~]# docker network ls
  5. NETWORK ID NAME DRIVER SCOPE
  6. feafa30d4051 bridge bridge local
  7. e8bf4fced9e2 host host local
  8. 6263db0933b9 none null local
  9. 799426d70aa2 test-network bridge local # 创建的桥接网络
  10. # 删除网桥 docker network rm test-network
  11. # 2、把之前启动的 mysql01,centos01,centos02 容器加入到自定义bridge网桥中
  12. docker network connect test-network mysql01
  13. docker network connect test-network centos01
  14. docker network connect test-network centos02
  15. # 3、查看自定义bridge网桥信息
  16. docker network inspect 799426d70aa2
  17. [
  18. {
  19. "Name": "test-network",
  20. "Id": "799426d70aa28b73b4a777c85b338186eafadd1558b13c43e07a9fd9a8b545e7",
  21. "Created": "2021-10-03T20:30:03.325679562+08:00",
  22. "Scope": "local",
  23. "Driver": "bridge",
  24. "EnableIPv6": false,
  25. "IPAM": {
  26. "Driver": "default",
  27. "Options": {},
  28. "Config": [
  29. {
  30. "Subnet": "172.18.0.0/16", # test-network的子网
  31. "Gateway": "172.18.0.1" # test-network的网关
  32. }
  33. ]
  34. },
  35. "Internal": false,
  36. "Attachable": false,
  37. "Ingress": false,
  38. "ConfigFrom": {
  39. "Network": ""
  40. },
  41. "ConfigOnly": false,
  42. "Containers": {
  43. "29298987c51b777b546bf6626560020ce235e390e1d7fcfe188c6db228ca4edf": {
  44. "Name": "mysql01",
  45. "EndpointID": "a69560a1872a25af042c74132df5dcade6e0e93faf9102185c1de19f6c8b3b36",
  46. "MacAddress": "02:42:ac:12:00:02",
  47. "IPv4Address": "172.18.0.2/16", # mysql01 容器的IP,与之前不同
  48. "IPv6Address": ""
  49. },
  50. "cb1922b95b9316d129b54f3545fad9729092926e10a1d5517f8928db42706151": {
  51. "Name": "centos01",
  52. "EndpointID": "f0cf5feb77ec23526fe5cee217dba9271125b9b4106c81bc7d58253ac48a4caf",
  53. "MacAddress": "02:42:ac:12:00:03",
  54. "IPv4Address": "172.18.0.3/16", # centos01 容器的IP,与之前不同
  55. "IPv6Address": ""
  56. },
  57. "cc6f510b9765ba018dbafd416c9774ddf5fd3ff55fa992827f55516e8dc70b6a": {
  58. "Name": "centos02",
  59. "EndpointID": "6c88540d719014e441d3119c4388e62d311b07acf009106e16aa66d7ebaf5763",
  60. "MacAddress": "02:42:ac:12:00:04",
  61. "IPv4Address": "172.18.0.4/16", # centos02 容器的IP,与之前不同
  62. "IPv6Address": ""
  63. }
  64. },
  65. "Options": {},
  66. "Labels": {}
  67. }
  68. ]
  69. # 4、通过容器名或别名互连
  70. # 进入centos01容器,ping centos02, ping mysql01
  71. # 可以发现centos01可以和centos02、mysql01容器之间可以通信
  72. docker exec -it cb1922b95b93 /bin/bash
  73. [root@cb1922b95b93 /]# ping centos02
  74. PING centos02 (172.18.0.4) 56(84) bytes of data.
  75. 64 bytes from centos02.test-network (172.18.0.4): icmp_seq=1 ttl=64 time=0.118 ms
  76. 64 bytes from centos02.test-network (172.18.0.4): icmp_seq=2 ttl=64 time=0.113 ms
  77. ...
  78. ping mysql01
  79. PING mysql01 (172.18.0.2) 56(84) bytes of data.
  80. 64 bytes from mysql01.test-network (172.18.0.2): icmp_seq=1 ttl=64 time=0.107 ms
  81. 64 bytes from mysql01.test-network (172.18.0.2): icmp_seq=2 ttl=64 time=0.103 ms
  82. ...
  83. # 5、断开网络。
  84. # 由于我们的容器仍然连接着默认bridge网桥docker0,而现在我们已经不需要它,所以应该将容器与docker0的连接断开,执行以下操作:
  85. docker network disconnect bridge mysql01
  86. docker network disconnect bridge centos01
  87. docker network disconnect bridge centos02
  88. # 6、查看默认bridge网桥docker0的容器网络配置
  89. docker network inspect feafa30d4051
  90. [
  91. {
  92. "Name": "bridge",
  93. "Id": "feafa30d4051f24353508959bd420fd163ad0c98d6b30ec8ff13b59a59552bb1",
  94. "Created": "2021-09-26T15:10:27.167774553+08:00",
  95. "Scope": "local",
  96. "Driver": "bridge",
  97. "EnableIPv6": false,
  98. "IPAM": {
  99. "Driver": "default",
  100. "Options": null,
  101. "Config": [
  102. {
  103. "Subnet": "172.17.0.0/16",
  104. "Gateway": "172.17.0.1"
  105. }
  106. ]
  107. },
  108. "Internal": false,
  109. "Attachable": false,
  110. "Ingress": false,
  111. "ConfigFrom": {
  112. "Network": ""
  113. },
  114. "ConfigOnly": false,
  115. "Containers": {}, # 之前的容器服务,已经从默认网桥中移除
  116. "Options": {
  117. "com.docker.network.bridge.default_bridge": "true",
  118. "com.docker.network.bridge.enable_icc": "true",
  119. "com.docker.network.bridge.enable_ip_masquerade": "true",
  120. "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  121. "com.docker.network.bridge.name": "docker0",
  122. "com.docker.network.driver.mtu": "1500"
  123. },
  124. "Labels": {}
  125. }
  126. ]