前戏
我们启动一个 nginx 和 mysql 的容器,nginx 经常需要到 mysql 的容器里去读取数据。这两个容器之间的 ip 是可以互通的,我们只需要在 nginx 容器内配置一下 mysql 的地址就可以了。当有一天,我们的 mysql 挂了,重新启动一个 mysql 容器,在去 nginx 容器内部配置一下就可以了。而实际上,nginx 和 mysql 都是集群部署的。当有一个 mysql 挂了之后,我们就需要一个一个进入到 nginx 容器内部进行修改。而 docker 也替我们考虑到了这种情况
Docker 容器间基于 Link 实现单向通信
什么叫单向通信呢?拿上面的例子来说,就是 nginx 可以 ping 通 mysql,而 mysql 不能 ping 通 nginx
启动 mysql 容器
docker run --name mydb -d -e MYSQL_ROOT_PASSWORD=zou123456 mysql:5.7
启动 nginx 应用容器并 link 到 mysql 数据库:
docker run -itd --name mynginx --link mydb nginx
其中的 --link mydb 表示 link 到 mysql 数据库,这样 nginx 就能和 mysql 单向通信了
注意:mydb 这个容器一定要存在!
进入到 nginx 容器内部 ping 一下 mydb (不使用 ip)
如果你是拉取的 nginx 镜像,需要安装一下 ping 的插件,在 nginx 容器内部安装哦。
apt-get update && apt-get install iputils-ping
进入到 mysql 容器里,是 ping 不通 mynginx 镜像的。但是 ip 是可以 ping 通的
Docker 容器间利用 brige 网桥实现双向通信
上面我们使用 link 实现了单向通信,而单向通信往往不能满足我们的全部需求,可以利用 bridge 实现双向通信
使用 docker network ls 查看下有哪些网络模式
这是 docker 默认的三种网络模式。创建一个新的网桥叫 my_bridge
docker network create -d bridge my_bridge
-d bridge my_bridge 表示创建一个 bridge 的网桥叫做 my_bridge
启动两个容器,mysql 和 nginx
docker run -d --name mydb mysql:5.7
docker run -d --name mynginx nginx
把两个容器 mydb 和 mynginx 加入 my_bridge 的网桥
docker network connect my_bridge mydb docker network connect my_bridge mynginx
进入两个容器分别验证,ping mynginx 和 ping mydb 是可以互相 ping 通的
部署flask应用
现在我们有一个 flask 应用,需要部署到服务器上,flask 代码如下
from flask import Flask from redis import Redis import os import socket app = Flask(__name__) redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) @app.route('/') def hello(): redis.incr('hits') return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname()) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)
这个 flask 应用还需要用到 redis,所以我们需要两个容器,一个是 redis 容器,还有一个是 python 容器。
先来拉取 redis 和 python3.7 的镜像
docker pull redis docker pull python:3.7
启动 redis 容器
docker run -d --name myredis redis
redis 只供自己内部访问,不提供给外部访问,所以不需要 -p 参数暴露出端口
在来创建 python 的 dockerfile,内容如下
FROM python:3.7 LABEL maintaner="zouzou" COPY app.py /app/ WORKDIR /app RUN pip install flask redis EXPOSE 5000 CMD ["python","app.py"]
这样我们的 flask 代码和 Dockerfile 都准备好了,构建 python 镜像
docker build -t flask-python:v1 .
启动 python 镜像
docker run -d --name myflask -p 8002:5000 --link myredis -e REDIS_HOST=myredis flask-python:v1
其中的 -e REDIS_HOST=myredis 是设置环境变量,REDIS_HOST 的变量值为 myredis,这样 flask 代码就能根据 myredis 获取到 ip 地址了
浏览器访问 8002 端口,如下