当前位置: > Linux服务器 > Docker >

docker 集群(单主机)部署web 应用入门(Nginx)

时间:2017-02-18 02:34来源:linux.it.net.cn 作者:IT

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
  • docker compose 安装

(重要)检查 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。

【参考】


  1. Deploying NGINX and NGINX Plus with Docker https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/
  2. Install Docker Compose. https://docs.docker.com/compose/install/
  3. http://yaml.org/






(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容