15-多容器复杂应用的部署
15-多容器復雜應用的部署
此節主要是通過部署一個復雜的應用場景,進而練習容器的網絡相關知識。
創建一個flask-web應用
創建一個 flask-web 文件夾
mkdir flask-web在此文件夾內創建 app.py 文件
cd flask-web touch app.py編寫一個簡單的 web 程序
import os import socket import redis from flask import Flaskapp = 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)創建一個 redis 數據庫容器
創建容器
docker run -d --name redis redis這里為什么沒有增加端口呢,是因為我們想內部自己訪問,不想暴露給外面,這樣也比較安全。
查看運行情況
[vagrant@10 flask-web]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d9916db96279 redis "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp redis部署
創建自定義的 web 程序鏡像
首先編寫Dockerfile
FROM python:2.7 LABEL maintaner="vincent <jeffmanword@gmail.com>" COPY ./app.py /app/ WORKDIR /app RUN pip install flask redis EXPOSE 5000 CMD ["python", "app.py"]構建鏡像
docker build -t vincent/flask-redis .創建 flask-redis 的容器
docker run -d --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis-d 是后臺執行
–link 是連接redis容器,使 flask-redis 容器可以訪問 redis 容器
-e 設定容器的環境變量,下面講
問題解決
上一步構建完成后,查看容器運行情況
docker ps發現剛剛創建的flask-redis容器并沒有運行,而是停止了,說明工作不正常,那么我怎么辦?
首先我們查看運行日志
[vagrant@10 flask-web]$ docker logs flask-redis Traceback (most recent call last):File "app.py", line 7, in <module>redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) NameError: name 'Redis' is not defined發現這里有一個錯誤,這是使用redis錯誤導致的,app.py 修改如下
import os import socket import redis from flask import Flaskapp = Flask(__name__) redis = 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)重新構建鏡像
docker rm flask-redis && docker rmi vincent/flask-redis重新創建容器
docker run -d --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis進入 flask-redis 容器
docker exec -it flask-redis /bin/bash查看 env
root@99a298edd5da:/app# env我們能在返回的內容中找到這樣一條環境變量
REDIS_HOST=redis說明剛剛創建容器的時候參數 -e的作用就在此。
測試網絡
測試ping redis 查看是否連通
root@99a298edd5da:/app# ping redis PING redis (172.17.0.4) 56(84) bytes of data. 64 bytes from redis (172.17.0.4): icmp_seq=1 ttl=64 time=0.079 ms 64 bytes from redis (172.17.0.4): icmp_seq=2 ttl=64 time=0.068 msping redis 是通的。這是因為
redis = redis.Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)在這里的 REDIS_HOST 被替換成了我們設定的名字,其實這段代碼在訪問的時候其實是直接訪問的 redis,因為設定了 --link 參數,那么是可以訪問的,而不需要ip。到這里有的人會有疑問,為什么不直接在代碼中寫 redis 呢?原因是方便我們后續更改名稱,我們只需要在創建容器的時候指定名稱即可,你可以叫 redis1,redis2 都可以。
我們在這個容器內訪問 web 服務
root@99a298edd5da:/app# curl 127.0.0.1:5000 hello Container World! I have been seen 1 times and my hostname is 99a298edd5da.這個web程序運行是正常的。
設定端口
退出容器,測試訪問本地 5000 端口
[vagrant@10 flask-web]$ curl 127.0.0.1:5000 curl: (7) Failed connect to 127.0.0.1:5000; 拒絕連接我們無法訪問,這是因為我們只是暴露了 容器的 5000端口,但是并沒有和本地端口進行綁定。
那我們重新創建容器
docker stop flask-redis && docker rm flask-redis docker run -d -p 5000:5000 --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis再次測試訪問本地 5000 端口
[vagrant@10 flask-web]$ curl 127.0.0.1:5000 hello Container World! I have been seen 2 times and my hostname is e2ecfc2256f7.總結
我們通過這個例子我們創建了兩個容器,并且相互之間有訪問設定,這很符合我們前后端開發的一個模式,一般 web程序 和 數據是分離的,這也是我們把 redis 單獨封裝在一個容器的原因。
這里我們在創建容器的時候使用了 -e 參數,我們詳細介紹一下。
創建一個帶-e參數的test4 容器
docker run -d -e PENG=vincent --name test4 busybox /bin/sh -c "while true; do sleep 3600; done"進入容器
docker exec -it test4 /bin/sh這里說明一下何時加 -it 參數當我們使用 exec 的時候需要加,這時我們想進入一個容器,如果我們在創建一個容器的時候,也就是run命令,那么是否加-it取決于,這個容器內的啟動命令配置,例如: 如果使用 ENTRYPOINT [“ls”] 那么我們不需要加 -it,如果什么都沒有設置,那么就需要加,一般這樣使用docker run -it test1 /bin/sh ls
執行 env
/ # env HOSTNAME=51801dc17c67 SHLVL=1 HOME=/root TERM=xterm PENG=vincent PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/我們可以看到 PENG=vincent 已經被設置在容器內了。這有什么用呢,有的時候有些程序需要讀取環境變量才能工作,這就很有用了。
最后我們再回顧一下這節部署的程序網絡模型圖
我們部署的兩個容器是在同一臺linux主機內的,他們可以訪問是很簡單的,那么如果是兩臺linux呢?
我們假設這兩臺linux主機是可以通信的,現在我們想把 redis 部署在一臺linux主機上,flask-web 部署在另一臺linux主機上,他們如何通信?如何配置? 大家思考一下。
答案將在下一節我們講解。
總結
以上是生活随笔為你收集整理的15-多容器复杂应用的部署的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Go 安装配置
- 下一篇: 【动态规划】魔法石矿