跨 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
跨 Docker 宿主机网络 overlay 类型的更多相关文章
- docker 访问宿主机网络
使用宿主机IP 在安装Docker的时候,会在宿主机安装一个虚拟网关docker0,我们可以使用宿主机在docker0上的IP地址来代替localhost. 首先,使用如下命令查询宿主机IP地址: i ...
- 宿主机网络中其它机器与Docker容器网络互通配置
前言 目前项目采用微服务架构进行开发,Nacos和其它服务部署到Docker中,Docker中容器采用的网络默认是桥接模式(Bridge),默认的子网码是172.17.0.1/16:宿主机是192.1 ...
- Docker多机网络
前言 前面的文章主要聚焦于单机网络上,对于生产环境而言,单机环境不满足高可用的特点,所以是不具备上生产的条件,因此在开始Docker Swarm篇的时候我们先来聊聊多机网络之间Docker的通信如何做 ...
- (为容器分配独立IP方法二)通过虚拟IP实现docker宿主机增加对外IP接口
虚拟IP.何为虚拟IP,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个虚IP,使用这两个IP中的任意一个都可以连接到这台主机,所有项目中数据库链接一项配 ...
- Docker桥接宿主机网络与配置固定IP地址
有些需求是把这个容器与宿主机在同一个网段,但是本人不建议这样子去操作,因为一个容器本身就是一个封装好的服务.建议去按默认的网络去实现. 临时设置 [root@linux-docker01 ~]# vi ...
- 17、docker多机网络通信overlay
理论上来说多台宿主机之间的docker容器之间是无法通讯的,但是多台宿主机之间的docker容器之间是可以通讯的,主要是通过VXLAN技术来实现的. GitHub上对于docker-overl ...
- docker 宿主机与容器直接文件移动命令
1.将容器中的文件复制到宿主机 我们把容器中的 nginx 目录整个复制到 宿主机/usr/local/nginx 目录下,使用如下命令: docker cp nginx_test: /etc/ng ...
- Docker宿主机管理
不需要每次输入sudo 在当前用户的用户目录.bashrc中增加以下内容,此后使用docker命令时不需要每次都增加sudo. echo 'sudo usermod -aG docker $USER' ...
- 如何配置 VirtualBox 中的客户机与宿主机之间的网络连接
如何配置 VirtualBox 中的客户机与宿主机之间的网络连接 作者: Aaron Kili 译者: LCTT rusking | 2017-03-01 13:40 评论: 3 收藏: 3 当你 ...
随机推荐
- Java_classpath
Java_classpath 什么是classpath? classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索class. 因为Java是编译型语言,源码文件是.java,而编译后的 ...
- Go连接到Linux服务器进行操作-执行shell命令&&上传文件
Go连接到Linux服务器进行操作 使用密码连接Linux服务器 package main import ( "fmt" "golang.org/x/crypto/ssh ...
- go配置私有仓库 (go mod配置私有仓库)
windows 配置go私有仓库 一.环境 1.私有gitlab (gitlab.xxx.com) 2.go 1.16.3 3.win10系统, 家目录:C:\Users\Administrator, ...
- springboot2集成log4j2
pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:// ...
- CAS 5.3服务器搭建
一.本例环境说明 JDK 1.8 CAS 5.3 apache-maven-3.6.0 二.CAS安装步骤 2.1 提前安装好JDK和Maven环境 安装步骤略 2.2 CAS环境搭建 2.2.1 C ...
- 解决微信官方SDK给出1.4.0等版本没有预览文件(previewFile)等接口
使用苹果手机测试 调用微信的js-sdk在系统中实现上传.预览附件的功能.在自己的手机测试通过后,直接丢给QA测试了 本以为相安无事了,没想到QA用安卓手机测的时候居然不得,使用的是下载下来的jwei ...
- 嵌入式Linux可用的防火墙——iptables:实现ip白名单、mac地址白名单
iptables是linux系统下的一个功能强大的模块,不仅可以用作防火墙,还可以实现NAT等众多路由功能.iptables的容器有很清晰的层次关系: 1. iptables是表的容器,iptable ...
- C#/VB.NET 将PDF转为OFD
OFD,全称Open Fixed-layout Document ,是一种可存储.读取以及编辑的国家标准版式的电子文档格式,属于中国的一种自主文件格式,在安全性上有可靠保证.为突破国外技术在我们软硬件 ...
- Django3使用WebSocket实现WebShell
前言 最近工作中需要开发前端操作远程虚拟机的功能,简称WebShell. 基于当前的技术栈为react+django,调研了一会发现大部分的后端实现都是django+channels来实现websoc ...
- 【译】JavaScript async / await:好的部分,陷阱和如何使用
async/await提供了一种使用同步样式代码异步访问资源的选项,而不会阻塞主线程.然而,使用它有点棘手.在本文中,我们将从不同的角度探讨async / await,并将展示如何正确有效地使用它们. ...