跨 Docker 宿主机网络 overlay 类型
跨 Docker 宿主机网络 overlay 类型
前言
a. 本文主要为 Docker的视频教程 笔记。
b. 环境为 三台 CentOS 7.0 虚拟机 (Vmware Workstation 15 Player)
c. 上一篇:跨 Docker 宿主机 macvlan 类型
主要原理
在一个容器中安装管理软件,负责管理容器的网络和通信,并配置其它容器与该容器连接,以形成规模。
实际操作
主要步骤:在 docker03 的宿主机上安装 consul,并配置 Docker 以实现管理功能,在 docker01 和 docker02 上分别部署容器,最终实现功能。
由于在上一节中已经建立了虚拟机 docker01 和 docker02,在此处继续使用。
1. 在一台宿主机上安装 consul
新建一个虚拟机 docker03 ,在 docker03 上执行:
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server --bootstrap
其中 -h 表示主机名, --name 表示的是容器的名称。
此时访问 docker03 的 8500 端口可以使用图形化界面查看(在本例中为:http://192.168.88.130:8500):
2. 在其它宿主机上修改 Docker 的配置,使启动后即监听端口
在docker01 和docker02 中修改 /etc/docker/daemon.json,以使 docker 启动后即监听端口:
{
"hosts":["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]
}
并修改 Docker 守护进程的启动配置文件,删除如下部分:
使用命令 systemctl daemon-reload 重新加载守护进程的配置文件,并重新启动 Docker。
[root@docker02 ~]# systemctl daemon-reload
[root@docker02 ~]# systemctl start docker
[root@docker02 ~]# netstat -lntup | grep 2376
tcp6 0 0 :::2376 ::😗 LISTEN 1477/dockerd
可以看到 Docker 已经监听了 2376 端口。
TIPS:
如果不修改 Docker 的守护进程启动配置,则会出现以下情况:
[root@docker02 ~]# systemctl start docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
[root@docker02 ~]# systemctl status docker.service
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: activating (auto-restart) (Result: exit-code) since Sun 2020-09-06 16:47:45 CST; 831ms ago
Docs: https://docs.docker.com
Process: 1441 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
Main PID: 1441 (code=exited, status=1/FAILURE)
Sep 06 16:47:45 docker02 systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
Sep 06 16:47:45 docker02 systemd[1]: Failed to start Docker Application Container Engine.
Sep 06 16:47:45 docker02 systemd[1]: Unit docker.service entered failed state.
Sep 06 16:47:45 docker02 systemd[1]: docker.service failed.
大概是我们配置的监听方式与 Docker 默认的监听方式冲突了。
由于 Docker 是 C/S 的软件架构,因此理论上可以通过任意客户端访问服务端,Docker 也为我们提供了这个功能,此时可以在别的宿主机中使用 docker -H 指定服务器的地址来连接,例如在 docker03 中并执行对应命令:
[root@docker03 ~]# docker -H 192.168.88.129:2376 ps -a
error during connect: Get http://192.168.88.129:2376/v1.40/containers/json?all=1: dial tcp 192.168.88.129:2376: connect: no route to host
可以看到访问被禁止了,此时在 docker02 中关闭防火墙:
[root@docker02 ~]# systemctl stop firewalld
再次执行:
[root@docker02 ~]# docker -H 192.168.88.129:2376 ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35e37e78cf85 busybox "sh" 6 days ago Exited (137) 6 days ago optimistic_ishizaka
Docker 开放远程端口,让远程主机可以连接是十分危险的行为:远程主机可以挂载宿主机的根目录以进行入侵。但是我们要借助该端口进行通信,不得不开放。个人猜测,可能是在内网中部署好服务器,再将部分端口和地址映射到外网,以此保证安全。
在 docker01 中也进行同样的操作。
3. 再次修改 Docker 配置,加入自身身份标志
在 docker01 和 docker02 中修改 /etc/docker/daemon.json,加入后两行,分别表示中转站的地址(在本例中为 docker03 的地址,和自己的地址端口):
{
"hosts":["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"cluster-store": "consul://192.168.88.130:8500",
"cluster-advertise": "192.168.88.129:2376"
}
再次刷新网页,可以看到宿主机 docker01 和 docker02 已经被监测到!
4. 创建网络
因为 overlay是全局的网络,因此在任何一个节点(docker01 或 docker02)上执行创建网络的命令即可:
docker network create -d overlay overlay1
其中 -d 表示 --driver。
TIPS:
A. 原先执行的是 “docker network create -d overlay --subnet 192.168.88.0/24 --gateway 192.168.88.1 overlay1”,但发现在宿主机和其它容器中均无法 ping 通 docker02 的 web 服务。之后取消子网参数,并使用命令查看网络:
docker network inspect <NETWORK_ID>
可以看出自动创建的网络并不是实际存在任何网络,因此推测此处应当指定自定义的网络。尝试重新自定一个网络后,发现也可以访问通(执行的命令为:“docker network create -d overlay --subnet 192.168.20.0/24 --gateway 192.168.20.1 overlay2”)。
B. 如果不小心在管理节点上执行,则会出现:
[root@docker03 ~]# docker network create -d overlay --subnet 192.168.88.0/24 --gateway 192.168.88.1 overlay1
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
C. 关机后再次启动管理节点还遇到了错误:
[root@docker03 ~]# docker start d4c4761c4aa9
Error response from daemon: driver failed programming external connectivity on endpoint consul (5c64f70d740bbe7456dd6236b0125269f16338ed2ce4355866bb6b4c6d9acdbb): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8500 -j DNAT --to-destination 172.17.0.2:8500 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1))
Error: failed to start containers: d4c4761c4aa9
重新启动 Docker 后即可。
D. 可以看出创建的是全局网络,在 docker02 中也可以看到,且 id 与 docker01 中的一致:
[root@docker02 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0d7266a632b4 bridge bridge local
924e5ff7fdab host host local
67f14032c92b macvlan1 macvlan local
5d2cffbe41af none null local
37300f3726ef overlay1 overlay global
5. 创建容器
此处使用的是Docker容器的单向互联中的 zabbix 相关镜像。
在 docker01 和 docker02 上分别运行 zabbix 的部分容器,注意要指定网络为我们新创建的 overlay1。例如,在 docker01 中运行 mysql 和 gateway镜像,在 docker02 上运行 zabbix-server 和 zabbix-web 镜像:
# docker01 中
docker run --name mysql-server -t --network=overlay1 \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin
docker run --name zabbix-java-gateway -t --network=overlay1 \
-d zabbix/zabbix-java-gateway:latest
# docker02 中
docker run --name zabbix-server-mysql -t --network=overlay1 \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
--link mysql-server:mysql \
--link zabbix-java-gateway:zabbix-java-gateway \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql:latest
docker run --name zabbix-web-nginx-mysql -t --network=overlay1\
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--link mysql-server:mysql \
--link zabbix-server-mysql:zabbix-server \
-p 8080:8080 \
-d zabbix/zabbix-web-nginx-mysql:latest
访问 docker02 地址的 8080 端口,服务正常运行。
此时再次查看 overlay1 的网络,可以看到 4 个容器都使用了这个网络:
后记
把写好的 Docker 相关都发出来了,一晚上发了两篇QAQ。
终于看完了 Docker 网络这一章,感觉还是有很多搞得不太明白(macvlan)。这一节学到了太多的网络命令,感觉还是要买个网络相关的教程看看(大学的全国计算机等级考试还是太偏理论了),大概看了前几节 Wireshark, 还挺好玩的。两个结合起来效果应该会不错!
参考:
关闭防火墙:
https://www.jianshu.com/p/96aebba5d3cc
解决“driver failed programming external connectivity...”:
https://www.cnblogs.com/hailun1987/p/7518306.html
linux 下查看网关:
https://blog.csdn.net/x356982611/article/details/82260987
docker network 参数:
https://www.cnblogs.com/sxdcgaq8080/p/9555528.html
docker overlay:
https://www.cnblogs.com/wangxu01/articles/11364427.html
-H fd:// 的含义:
https://blog.csdn.net/onlyshenmin/article/details/81069047