docker 集群(单主机)部署web 应用入门(Nginx)
本文探讨的场景是使用 Nginx 部署一个应用,可能涉及 Nginx 服务,web 服务,web service 服务,缓存服务,数据库服务等,这时就需要多个容器协作,这些容器之间依赖关系非常复杂。面对动态地址,我们难以检查每个容器网络地址,然后做配置。这里仅是简单介绍单机 Docker compose 的应用。
准备环境
-
假设你比较熟悉 docker run 等命令
-
简单了解 Nginx 的配置
-
下载 Nginx 并检查1
sudo docker pull nginx
sudo docker run -d --name ng1 -p 8080:80 nginx
curl http://localhost:8080/
sudo docker rm -f ng1
(重要)检查 pip 与 Python 版本一致性
pip --version
python --version
如果没有 pip 的 python 与 python 版本不一致, 需要安装/重新 pip
进入 https://pip.pypa.io/en/stable/installing/ 右键保存 get-pip.py 文件
python get-pip.py
安装检查 docker compose,更多细节参考2:
pip install docker-compose
docker-compose --version
1、docker compose 简介
用一个 docker-compose.yml 文件配置多个 docker 应用服务,用一个简单命令创建并启动这些应用。
官方很解释简洁。让我们看 docker-compose.yml (YAML 是对程序员友好的数据序列化标准3)的案例:
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
这文本层次结构,定义了两个服务(services,注:docker 就概念是 Container,随着服务概念的兴起,新的说法是一个服务一个容器)分别是 web 和 Redis,和一个 docker 卷;这些命令几乎不用解释,与 docker run , docker create 等命令类似,例如 port 就是 -p 参数,详细参考:Compose file reference
* 官方的快速指南*
1、创建工作目录
mkdir composetest
cd composetest
2、创建 python 的 web 应用 app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
3、创建 Dockerfile
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install flask redis
CMD ["python", "app.py"]
这个文件告诉 docker 构建一个新的镜像采用的配置:
-
基础配置来源 python:3.4-alpine
-
把当前目录添加入镜像中 /code 路径下
-
设置镜像启动时当前工作目录 /code
-
在镜像中安装 python 的 flask web 框架 与 redis 访问客户端
-
启动时执行命令 python app.py
4、用 Compose 创建镜像并运行
按上述内容创建 docker-compose.yml。
运行
sudo docker-compose up
sudo docker ps
看到几个服务(容器)按要求启动。输入:
curl http://localhost:5000
返回结果:Hello World! I have been seen 1 times.
2、核心服务-app 网络
在 python 程序中,代码 redis = Redis(host=’redis’, port=6379) 中 host=’redis’ 这里没有用绝对地址!!!,事实上,你进入其中任何一个容器,ping redis, ping web 都是通的哦。
官方文档 docker-compose 为每个项目默认建立 [projectname]_default 网络,使得服务之间可以方便的通讯。
3、Nginx 部署 web 应用
3.1 清除所有服务(容器)
sudo docker rm -f $(sudo docker ps -a -q)
3.2 了解 Nginx 容器文件空间
sudo docker run -it --rm nginx /bin/bash
进入 nginx 容器。按官网信息查看目录和文件:
-
/etc/nginx 各种配置文件,其中 nginx.conf 是主配置文件,一般不需要修改
-
/etc/nginx/conf.d 虚拟机配置目录。只有一个 default.conf 文件
-
/usr/share/nginx/html 官方推荐静态文件挂载点
在 ~/composetest 目录下,执行
sudo docker cp 9899eb303ff6:/etc/nginx/conf.d $(pwd)/conf.d
这时本地有了配置虚拟机的模板。
3.3 修改 docker-compose.yml 配置
添加 nginx 和 web 服务:
version: '2'
services:
nginx:
image: nginx
volumes:
- ./conf.d:/etc/nginx/conf.d
ports:
- "8080:80"
links:
- web1
- web2
web1:
image: web1:1.0
links:
- redis
web2:
image: web1:2.0
volumes:
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
构建 web 镜像
sudo docker build . -t web1:1.0
修改 app.py 的输出语句,例如将 “I” 改为 “They” 以区别镜像。然后:
sudo docker build . -t web1:2.0
启动服务并测试:
sudo docker-compose up
打开新终端
curl http://localhost:8080
sudo docker ps
找到 nginx 服务的 ID, 例如:b4372021a8e1。进入该容器
sudo docker exec -it b4372021a8e1 /bin/bash
ping web1 -c4
ping web2 -c4
ping redis -c4
exit
按 ctrl+c 终止容器服务,清除所有服务。
3.4 修改 conf.d/default.conf
upstream backends {
server web1:5000;
server web2:5000;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location = / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy to webs
location = /test {
proxy_pass http://backends/;
}
}
-
upstream backends 定义了参与 web 负载均衡的服务。详细 upstream 配置
-
location 定义了不同 url 的处理。详细nginx location匹配规则
-
proxy_pass 定义了代理对象。注意 有url 和 无url 的区别(rewrite,transport)。详细proxy_pass
3.5 运行程序
sudo docker-compose up
请特别注意每个服务输出,特别是 Nginx 的输出,如果 Nginx 先启动,可能会报错找不到 web 服务器
服务启动顺序 ,up函数,得到当前工程中的所有服务,并根据服务的依赖性(links,external links – 本工程或docker-compose之外的容器,多用于多项目共用容器,网络容器net-from以及数据容器volume-from)进行排序。
案例 docker-compose.yml 实际启动顺序:
Creating composetest_redis_1
Creating composetest_web2_1
Creating composetest_web1_1
Creating composetest_nginx_1
... ...
测试输出:
[~]$ curl http://localhost:8080/test
Hello World! I have been seen 1 times.
[~]$ curl http://localhost:8080/test
Hello World! They have been seen 2 times.
[~]$ curl http://localhost:8080/test
Hello World! I have been seen 3 times.
[~]$ curl http://localhost:8080/test
Hello World! They have been seen 4 times.
小结
docker compose 使用配置文件启动服务集群,并提供集群内部网络支持,方便了部署。 由于服务之间的依赖关系,必须正确显式定义依赖(利用 links 等),减少不确定性 bug。
【参考】
-
Deploying NGINX and NGINX Plus with Docker https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/
-
Install Docker Compose. https://docs.docker.com/compose/install/
-
http://yaml.org/
(责任编辑:IT) |