8天入门docker系列 —— 第七天 让你的container实现跨主机访问
当你有若干个容器之后,你可能就希望实现容器的跨机部署访问了,比如aspnetcore在一台host上,mysql在另外一个host上,如果要实现这样的功能,需要你
借助docker自带的overlay网络模型了。
一: overlay网络模型
要想快速的搭建overlay网络,你可以通过docker默认的swarm集群给你默认生成的名ingress的overlay网络,这样会默认开放一些端口供底层机器内的访问,比如:
UDP 4789 是用于overlay network 流量传输的,作为开发角度,你只需要知道这是一个基于底层物理网络构建出的一个上层虚拟网络,而你的程序都是跑在这个虚拟网
络上,如果要画图,大概就是这样吧!
二:通过docker swarm构建overlay网络
为了构建overlay网络,需要备有两台机器(使用虚拟机即可):
- 192.168.23.146 manager
- 192.168.23.147 worker
使用起来很简单,在 146机器上执行 docker swarm init 初始化一个集群,同时默认了该机作为 cluster 的manager节点。
- [root@manager ~]# docker swarm init
- Swarm initialized: current node (g0o8vkgzruv63hsx4pkjs0yfk) is now a manager.
- To add a worker to this swarm, run the following command:
- docker swarm join --token SWMTKN--0oxo6qrxwvl8xlneq0jqz2zd87nkj7c0vyf1h9m8kcj3qbzd4v-3eu9zb5athq0s2n79rncbejb1 192.168.23.146:
- To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
- [root@manager ~]# docker node ls
- ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
- g0o8vkgzruv63hsx4pkjs0yfk * manager Ready Active Leader 18.09.
- [root@manager ~]#
当执行完init之后,通过node ls 可以看到,当前cluster集群中只有一个node节点,而且还是Leader,同时docker还告诉我们怎么将其他node加入到集群中作为
worker节点,验证方式是token,好了,那我可以将这段output copy到 147 的 shell上。
- [root@worker ~]# docker swarm join --token SWMTKN--0oxo6qrxwvl8xlneq0jqz2zd87nkj7c0vyf1h9m8kcj3qbzd4v-3eu9zb5athq0s2n79rncbejb1 192.168.23.146:
- This node joined a swarm as a worker.
最后通过在 146 上执行 docker node ls 看一下集群信息,可以看到146,147都在一个集群了。
- [root@manager ~]# docker node ls
- ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
- g0o8vkgzruv63hsx4pkjs0yfk * manager Ready Active Leader 18.09.
- ojjngean30orjzswh72o25rsr worker Ready Active 18.09.
接下来再看一下,4789端口是否开放了,同时看一下ingress的overlay是否开启了,如下:
- [root@manager ~]# docker network ls
- NETWORK ID NAME DRIVER SCOPE
- f5fbe8d71b5a bridge bridge local
- 91cfc77a3c7f docker_gwbridge bridge local
- ac4a48a43517 host host local
- 5eux1lz4yom7 ingress overlay swarm
- 02f9bfe179ca none null local
- [root@manager ~]# netstat -tlnpu
- Active Internet connections (only servers)
- Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
- tcp 0.0.0.0: 0.0.0.0:* LISTEN /sshd
- tcp 127.0.0.1: 0.0.0.0:* LISTEN /master
- tcp6 ::: :::* LISTEN /dockerd
- tcp6 ::: :::* LISTEN /dockerd
- tcp6 ::: :::* LISTEN /sshd
- tcp6 ::: :::* LISTEN /master
- udp 0.0.0.0: 0.0.0.0:* /avahi-daemon:
- udp 0.0.0.0: 0.0.0.0:* /dhclient
- udp 0.0.0.0: 0.0.0.0:* /chronyd
- udp 127.0.0.1: 0.0.0.0:* /chronyd
- udp 0 0 0.0.0.0:4789 0.0.0.0:* -
- udp 0.0.0.0: 0.0.0.0:* /avahi-daemon:
- udp 0.0.0.0: 0.0.0.0:* /dhclient
- udp6 ::: :::* /chronyd
- udp6 ::: :::* /chronyd
- udp6 ::: :::* /dhclient
- udp6 ::: :::* /dockerd
默认名为ingress 的overlay driver是默认是不支持standalone容器加入的,所以我需要重新new一个overlay,并设置一下允许standalone容器加入此网络,好了,
说干就干,new了一个 test-net的overlay网络,通过--attachable 开启附加功能。
- [root@manager ~]# docker network create --driver=overlay --attachable test-net
- dajh2glpfattdnq2ahqchlhur
- [root@manager ~]# docker network ls
- NETWORK ID NAME DRIVER SCOPE
- f5fbe8d71b5a bridge bridge local
- 91cfc77a3c7f docker_gwbridge bridge local
- ac4a48a43517 host host local
- 5eux1lz4yom7 ingress overlay swarm
- 02f9bfe179ca none null local
- dajh2glpfatt test-net overlay swarm
三:python 跨机连接 redis
我准备把redis放在147机器上, python application 放在 146上,python 通过 对方的容器名(some-redis) 进行连接,如下图所示:
1. 在147上执行docker run时附加 network 为指定的 test-net 网络
- [root@worker ~]# docker run --network test-net --name some-redis -d redis
- eca08e67e35160661e090ca42a61dacaee5dd8ca99f8e9c25e59ae6927d66328
2. python应用程序
主要有三个部分,app.py, Dockerfile, requirements.txt。
《1》 app.py
下面要注意的是,在redis的构造函数中指定了host= some-redis ,也就是 147启动容器名。
- from flask import Flask
- from redis import Redis, RedisError
- import os
- import socket
- # Connect to Redis
- redis = Redis(host="some-redis", db=0, socket_connect_timeout=2, socket_timeout=2)
- app = Flask(__name__)
- @app.route("/")
- def hello():
- try:
- visits = redis.incr("counter")
- except RedisError:
- visits = "<i>cannot connect to Redis, counter disabled</i>"
- html = "<b>Hostname:</b> {hostname}<br/>" \
- "<b>Visits:</b> {visits}"
- return html.format(hostname=socket.gethostname(), visits=visits)
- if __name__ == "__main__":
- app.run(host='0.0.0.0', port=80)
《2》 Flask 和 Redis 依赖包 (requirements.txt)
- Flask
- Redis
《3》 最后就是dockerfile
- FROM python:2.7-slim
- WORKDIR /app
- COPY . .
- EXPOSE 80
- RUN pip install --trusted-host pypi.python.org -r requirements.txt
- VOLUME [ "/app" ]
- CMD [ "python", "app.py" ]
有了这三个,接下来就可以构建image了。
- [root@manager app]# docker build -t pyweb:v1 .
- Sending build context to Docker daemon .608kB
- Step / : FROM python:2.7-slim
- 2.7-slim: Pulling from library/python
- fc7181108d40: Already exists
- 8c60b810a35a: Pull complete
- d207b275197c: Pull complete
- 63184f224d60: Pull complete
- Digest: sha256:1405fa2f8e9a232e2f60cafbb2b06ca2f1e0f577f4b4c397c361d6dba59fd24e
- Status: Downloaded newer image for python:2.7-slim
- ---> ca96bab3e2aa
- Step / : WORKDIR /app
- ---> Running in 6b8324c10dc0
- Removing intermediate container 6b8324c10dc0
- ---> a85fb403c57b
- Step / : COPY . .
- ---> f13015df5bf7
- Step / : EXPOSE
- ---> Running in 408a718df2b4
- Removing intermediate container 408a718df2b4
- ---> 39d30c3a092d
- Step / : RUN pip install --trusted-host pypi.python.org -r requirements.txt
- ---> Running in 0ee0982739d5
- DEPRECATION: Python 2.7 will reach the end of its life on January 1st, . Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
- Collecting Flask (from -r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/c3/31/6904ac846fc65a7fa6cac8b4ddc392ce96ca08ee67b0f97854e9575bbb26/Flask-1.1.0-py2.py3-none-any.whl (94kB)
- Collecting Redis (from -r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/ac/a7/cff10cc5f1180834a3ed564d148fb4329c989cbb1f2e196fc9a10fa07072/redis-3.2.1-py2.py3-none-any.whl (65kB)
- Collecting Jinja2>=2.10. (from Flask->-r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
- Collecting click>=5.1 (from Flask->-r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
- Collecting Werkzeug>=0.15 (from Flask->-r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/9f/57/92a497e38161ce40606c27a86759c6b92dd34fcdb33f64171ec559257c02/Werkzeug-0.15.4-py2.py3-none-any.whl (327kB)
- Collecting itsdangerous>=0.24 (from Flask->-r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
- Collecting MarkupSafe>=0.23 (from Jinja2>=2.10.->Flask->-r requirements.txt (line ))
- Downloading https://files.pythonhosted.org/packages/fb/40/f3adb7cf24a8012813c5edb20329eb22d5d8e2a0ecf73d21d6b85865da11/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl
- Installing collected packages: MarkupSafe, Jinja2, click, Werkzeug, itsdangerous, Flask, Redis
- Successfully installed Flask-1.1. Jinja2-2.10. MarkupSafe-1.1. Redis-3.2. Werkzeug-0.15. click-7.0 itsdangerous-1.1.
- Removing intermediate container 0ee0982739d5
- ---> 704e7d655494
- Step / : VOLUME [ "/app" ]
- ---> Running in 0c4ad68db249
- Removing intermediate container 0c4ad68db249
- ---> 5b0ce6eef187
- Step / : CMD [ "python", "app.py" ]
- ---> Running in 388d972cbd6d
- Removing intermediate container 388d972cbd6d
- ---> fd7a0ffca7fc
- Successfully built fd7a0ffca7fc
- Successfully tagged pyweb:v1
- [root@manager app]# docker run -d --network test-net -p 80:80 -v /app:/app --name pyapp pyweb:v1
- 9d419507b00adddd003f8e45580ec1ee48d4a0347091b65da1bc183a8bbe1dc2
- [root@manager app]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 9d419507b00a pyweb:v1 "python app.py" seconds ago Up seconds 0.0.0.0:->/tcp pyapp
- [root@manager app]#
然后访问一下 http://192.168.23.146,每刷新一下page,都会执行一次redis.incr操作。,这样就实现了多容器之间的跨机器访问,大家也可以把这些放到
docker-compose文件中哦。
好了,本篇就说到这里,希望对你有帮助。
8天入门docker系列 —— 第七天 让你的container实现跨主机访问的更多相关文章
- 利用虚拟网桥实现Docker容器的跨主机访问
最近在研究Docker,Docker的网络配置是比较令人头疼的部分,尤其是跨主机的容器间通信,很多解决方案都比较复杂,这里,我只用虚拟网桥来实现Docker的跨主机访问,分享出来,希望对Docker学 ...
- 8天入门docker系列 —— 第一天 docker出现前的困惑和简单介绍
docker出来也有很多年了,但用到的公司其实并不是很多,docker对传统开发是一个革命性的,几乎颠覆了之前我们传统的开发方法和部署模式,而大多 公司保守起见或不到万不得已基本上不会去变更现有模式. ...
- 8天入门docker系列 —— 第三天 使用aspnetcore小案例熟悉对镜像的操控
上一篇我们聊到了容器,现在大家应该也知道了,没有镜像就没有容器,所以镜像对docker来说是非常重要的,关于镜像的特性和原理作为入门系列就不阐 述了,我还是通过aspnetcore的小sample去熟 ...
- 8天入门docker系列 —— 第八天 让程序跑在swarm集群上
真正的落地部署都是希望程序跑在集群下,而不是单机版下测测玩玩,所以这篇就来聊一下怎么使用docker swarm进行部署,因为是swarm是docker自带的, 所以部署起来还是非常简单的. 一:前置 ...
- 8天入门docker系列 —— 第四天 使用aspnetcore小案例熟悉端口映射和挂载目录
到目前为止大家应该对镜像和容器有了一个大概认知,而且也用了docker进行了一个简单化的部署,但仔细一看问题还有很多,所以这篇我们继续完善. 一:如何让外网访问到容器内应用 我们知道容器内拥有自己的子 ...
- 8天入门docker系列 —— 第五天 使用aspnetcore小案例熟悉容器互联和docker-compose一键部署
这一篇继续完善webnotebook,如果你读过上一篇的内容,你应该知道怎么去挂载webnotebook日志和容器的远程访问,但是这些还远不够,webnotebook 总要和一些数据库打交道吧,比如说 ...
- 8天入门docker系列 —— 第二天 通过一个aspnetcore程序加深对容器的理解
我们知道容器是一个打包了应用和相关依赖的盒子,那怎么去操控这个盒子呢? 这一篇我通过一个简单的aspnetcore程序来加深对盒子的理解,使用之前先 安装一下Docker的环境. 一:Docker的安 ...
- 8天入门docker系列 —— 第六天 搭建自己的私有镜像仓库Registry
这一篇我们来聊聊私有仓库的搭建,其实不管你是通过docker build还是compose的方式进行构建,最终还是要将生成好的镜像push到远程的仓库中,这样多个 平台可以方便的获取你registry ...
- Docker系列-第七篇Docker构建SpringBoot应用
1.基于Dockerfile构建SpringBoot镜像 1.1准备工作 将SpringBoot项目通过maven打成jar包 mvn clean package #使用maven打包项目 1.2使用 ...
随机推荐
- Rust 2017 调查报告:学习曲线是最大痛点(最大的问题是这门语言太偏底层了,现在做底层的少了。还有C这个绕不过去的存在)
Rust 官方在社区上做了一次调查,以了解用户如何看待 Rust 的发展.调查共收到 5368 份回复,其中有 大约 2/3 的是 Rust 用户,剩下的 1/3 是非 Rust 用户,调查结果如下. ...
- blockchain_eth客户端安装 & geth使用 &批量转账(二)
回顾一下,前面我们讲到启动geth geth --rpc --datadir "F:/geth/Geth/" --light console 2>console.log 这一 ...
- cocos2D-X从的源代码的分析cocos2D-X学习OpenGL(1)----cocos2D-X渲染架构
个人原创.欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man 从本篇文章開始,将分析cocos2D-X 3.0源码,第一部分是从cocos2D-X学习OpenGL ...
- .net core响应缓存
按照官网资料操作无效,这里使用https://github.com/speige/AspNetCore.ResponseCaching.Extensions的扩展包 安装AspNetCore.Resp ...
- php将两个数组相同的key合并到一个数组
$arr = array( array( 'id' => 1, 'user_name'=>'test1' ), array( 'id' =& ...
- .NET VS 自定义新建代码文件模板
参考:http://www.cnblogs.com/fightingtong/p/3765914.html 在VS中新建文件时,可使用模板在文件中生成指定内容.只需要把IDE安装目录下的模板进行修改保 ...
- 微信小程序把玩(三十二)Image API
原文:微信小程序把玩(三十二)Image API 选择图片时可设置图片是否是原图,图片来源.这用的也挺常见的,比如个人中心中设置头像,可以与wx.upLoadFile()API使用 主要方法: wx. ...
- C# ACCESS 查询提示“至少一个参数没有被指定”问题
错误的SQL指令如下: sqlStr = “select * from tb_userInfo where userName=” + userName; //错误的 sql 指令 正确的SQL ...
- 宿主机与虚拟机系统的USB设备切换
有时候我们需要在虚拟机的操作系统中进行一些USB设备的测试,但默认情况下USB设备是在宿主机系统里面的,那这个时候我们就要进行切换才能够达到目的,具体要怎么操作呢?下面讲解一下: 1. Ctrl+ ...
- 从Java和JavaScript来学习Haskell和Groovy
直击现场 记得刚接触计算机的时候,我就受到了两个非常巨大的错误观念的影响,这个观念最初是来自于老师的传授还是学长的教诲已经记不清了,但是直到我工作几年以后,才慢慢有了实际的体会: 学习和使用什么编程语 ...