在上一part《把AspDotNetCoreMvc程序运行在Docker上-part4:实现负载均衡》中,我们通过几个比较复杂的步骤在docker平台上实现了对网站程序的负载均衡,配置步骤比较多。如果实际的站点较少,整个架构比较简单的情况下,这么做没有太大问题,如果应用较多的时候,会容易出错。那么这时候我们可能会想到自己写一些脚本来实现自动化,当然这是可行的。然而docker已为我们着想好,给我们提供了docker-compose功能,利用它我们可以实现对复杂应用的管理,包括容器、网络、volume等。

准备工作

先删除上一part我们创建的容器、网络和volume(不用觉得可惜,后面用上docker-compose可以轻易实现)

docker rm -f $(docker ps -aq)
docker network rm $(docker network ls -q)
docker volume rm $(docker volume ls -q)

安装docker-compose

在linux平台上需要手动执行如下命令安装

sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

(最新版本可以从这里https://github.com/docker/compose/releases获知)

安装之后,运行docker-compose –version检查是否成功

准备MVC站点程序

可以从这里下载

https://github.com/shenba2014/AspDotNetCoreMvcDocker/tree/docker-compose

然后执行

dotnet restore

bower install

一会用到这个站点程序创建一个镜像以及对应的容器

创建docker-compose配置文件

新建docker-compose.yml文件(在docker所在宿主服务器直接创建也可以)

version: "3"

volumes:

productdata:

networks:

frontend:

backend:

services:

mysql:

image: "mysql:8.0.0"

volumes:

- productdata:/var/lib/mysql

networks:

- backend

environment:

- MYSQL_ROOT_PASSWORD=password

- bind-address=0.0.0.0

这个文件足够的自描述,把上一节我们用到的内容都作出了定义,还是简单解释一下

version:版本号,目前最新的是3.0

volumes:之前的《把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器》里面有介绍过,用于在docker容器外存储数据

networks:在上一part说过,定义了两个网络:frontend和backend

services:定义将要用到的容器,这里只定义了mysql容器,这些参数跟使用docker create命令创建容器的参数一致。具体可参考上一part《把AspDotNetCoreMvc程序运行在Docker上-part4:实现负载均衡》。

docker-compose执行构建

 

执行如下构建命令

docker-compose –f docker-compose.yml build

输出结果

WARNING: Some networks were defined but are not used by any service: frontend, backend

mysql uses an image, skipping

这里的警告信息意思是我们定义的两个网络还没被任何服务组件使用。

运行了这个命令只是定义,并没有真正的创建volume、network或者容器。

接下来运行docker-compose.yml定义的应用,才会真正的创建内容

docker-compose -f docker-compose.yml up

可以理解为启动刚才我们定义的组件,然后会有一堆的输出内容

WARNING: Some networks were defined but are not used by any service: frontend
Creating network "dockertemp_backend" with the default driver
Creating dockertemp_mysql_1 ...
Creating dockertemp_mysql_1 ... done
Attaching to dockertemp_mysql_1

很明显docker-compose在依次创建network、容器实例。

名字看起来比较奇怪,都带了dockertemp_前缀。因为docker-compose.yml所在的目录命令是dockertemp,所以最终提供的名称有这个前缀,避免了命名冲突。

而为什么是mysql_1,带有_1后缀,后续会用到,这里是为了用于横向扩展做集群的时候用到。

进一步通过如下命令验证volume、network和容器是创建成功的

docker volume ls

docker netowrk ls

docker ps –a

使用docker-compose –f docker-compose.yml down -v可删除network、容器和volume,全自动完成(保存在volume的数据也会删除,如果要保留volume把-v去掉即可)。

现在docker-compose文件里只定义了一个service,接下来继续添加MVC站点容器以及负载均衡容器。

添加MVC站点容器以及负载均衡容器

首先从以下路径下载代码

https://github.com/shenba2014/AspDotNetCoreMvcDocker/tree/docker-compose

这个分支跟之前的不一样,增加了对支持docker-compose的一些改动。

代码拉下来之后执行如下命令

dotnet restore

dotnet publish --framework netcoreapp2.0 --configuration Release --output dist

cd dist | npm install

dist文件夹里的内容就是我们后续要用到的MVC站点内容。

从源代码查看完整的docker和docker-compose.yml文件

先看看docker文件的更新内容

FROM microsoft/aspnetcore:2.0.0

COPY dist /app

COPY dist/node_modules/wait-for-it.sh/bin/wait-for-it /app/wait-for-it.sh

RUN chmod +x /app/wait-for-it.sh

WORKDIR /app

EXPOSE 80/tcp

ENV WAITHOST=mysql WAITPORT=3306

ENTRYPOINT ./wait-for-it.sh $WAITHOST:$WAITPORT --timeout=0 && exec dotnet AspDotNetCoreMvcDocker.dll

红色部分是新增的内容,这里拷贝了一个wait-for-it的脚本到了容器内部,并且在ENTRYPOINT里设置了等待mysql启动之后再启动MVC容器。

简单解释一下,因为使用了docker-compose启动容器之后,我们不能确保mysql容器服务是否已正常启动,如果mysql没有启动,那么站点也没法使用。所以容器必须在mysql容器启动之后执行,这里就引入了一个npm的package:wait-for-it,这个只能在Linux平台下使用。

接下打开完整的docker-compose.yml文件,这里只列出新增的service(完整文件内容不列出,可查看代码)

dbinit:
     build:
       context: .
       dockerfile: Dockerfile
     networks:
       - backend
     environment:
       - INITDB=true
       - DBHOST=mysql
       - DBPASSWORD=password
     depends_on:
       - mysql
   mvc:
     build:
       context: .
       dockerfile: Dockerfile
     networks:
       - backend
       - frontend
     environment:
       - DBHOST=mysql
       - DBPASSWORD=password
     depends_on:
       - mysql

loadbalancer:
     image: dockercloud/haproxy
     ports:
       - 3000:80
     links:
       - mvc
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
     networks:
       - frontend

这里才原来的基础上增加了dbinit,mvc和loadbalancer三个service,分别描述如下

dbinit:主要是用于初始化数据库,这里是把它当做一个容器来执行,实际在完成了数据库初始化自后就会退出。

mvc:这里就是MVC站点的容器,跟我们上一part定义MVC的参数类似。主要是增加了depends_on参数,指明mvc容器依赖于mysql容器。

loadbalancer:顾名思义,就是负载均衡服务器容器,通过links参数指向了其代理的站点是MVC容器,并且通过volumes参数配置了/var/run/docker.sock文件映射为主机的文件,具体作用不描述,主要是为了在扩容的时候通知到负载均衡服务器。

启动站点

把上一步的dist文件夹docker、docker-compose.yml文件拷贝到docker服务器(如果开发机就是docker服务器可以忽略),然后在这些文件的所在目录执行如下命令

docker-compose -f docker-compose.yml build

这个命令之前提到过,类似于编译,检查是否有错误,实际上不会创建容器

接着运行

docker-compose -f docker-compose.yml up dbinit

开启dbinit容器,之前我们提到,这个dbinit也是个MVC容器,但是只是负责数据库初始化,完成之后会自动关闭,这是这个命令的output

Creating network "dockertemp_frontend" with the default driver
Creating network "dockertemp_backend" with the default driver
Creating volume "dockertemp_productdata" with default driver
Creating dockertemp_mysql_1 ...
Creating dockertemp_mysql_1 ... done
Creating dockertemp_dbinit_1 ...
Creating dockertemp_dbinit_1 ... done
Attaching to dockertemp_dbinit_1
dbinit_1        | wait-for-it.sh: waiting for mysql:3306 without a timeout
dbinit_1        | wait-for-it.sh: mysql:3306 is available after 16 seconds
dbinit_1        | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
dbinit_1        |       No XML encryptor configured. Key {1b1e827d-d1d0-4d0c-a92d-8632ee0791ef} may be persisted to storage in unencrypted form.
dbinit_1        | Preparing Database...
dbinit_1        | Applying Migrations...
dbinit_1        | Creating Seed Data...
dbinit_1        | Database Preparation Complete
dockertemp_dbinit_1 exited with code 0

从output可以看到有一个等待mysql启动的步骤,等待了16秒。然后是执行了数据库初始化,创建表以及插入一些种子数据。最后一个行输出表明该容器自动退出。

好了数据库准备好之后,就可以启动MVC和负载均衡容器,还是通过docker-compose命令

docker-compose -f docker-compose.yml up mvc loadbalancer

执行完成之后,就可以访问我们的MVC站点了,这里我们只启用了一个MVC站点,试试从浏览器打开http://192.168.115.136:3000/,一切正常的话就能看到网站和数据了

做了这么多步骤,就是为了实现负载均衡,接下来一行命令让他立即扩容到4个MVC站点

docker-compose -f docker-compose.yml scale mvc=4

秒级扩容就是这简单,不信的话运行docker ps看看下面是不是有4个MVC站点容器,还不相信的话手动多刷几次http://192.168.115.136:3000/,会发现from server的值是会发生变化的。

好了,如果这时候要实现优雅降级怎么办,没问题,还是一行命令

docker-compose -f docker-compose.yml scale mvc=1

系统自动移除了三个MVC站点容器,当然也是秒级的。

最后关闭所有服务的命令是

docker-compose -f docker-compose.yml stop

写了这么多就是为了描述docker-compose的使用方法,对比上一part,实际上就是把之前的工作都放到一个批处理文件里执行,将所有服务当做一个整体来管理,同时也提供了遍历站点扩容和降级的方式。看起来已经很方便了,当然还没完,后续还有大招。

把AspDotNetCoreMvc程序运行在Docker上-part5:使用docker-compose的更多相关文章

  1. 把AspDotNetCoreMvc程序运行在Docker上-part4:实现负载均衡

    在上一part<把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器>,我们利用MySql容器和Volume实现了真正意义上的数据存储.整个结构非常简 ...

  2. 把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器

    接上一篇博文<把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像>,这次我们看看如何使用docker存储数据. 背景 之前的示例都只有一个网站应用 ...

  3. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像

    在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...

  4. 把AspDotNetCoreMvc程序运行在Docker上-part1

    接<基于ASP.Net Core学习Docker技术第一步:在CentOS7安装Docker平台>这个博文,在搭建完成Docker平台之后,可以开始让aspdotnetcore程序运行在d ...

  5. docker 上传到docker hub 采坑

    前面是仓库名称 后面可以命名img名字 docker push gaodi2345/wj:docker_gui

  6. 小程序运行时如何助力传统APP转型?

    小程序和H5或者RN有什么区别?优越性在哪里? 长期以来,移动互联网界一直在寻找一种既能获得Native原生的体验,又可以低门槛快速开发的技术.在这个过程中出现了很多尝试,例如React Native ...

  7. 在OSX和Windows版本Docker上运行GUI程序

    看到很多人在Docker问题区讨论:如何在OS X和Windows的Docker上运行GUI程序, 随手记录几个参考资料: https://github.com/docker/docker/issue ...

  8. 在docker上运行.net core程序

    一.安装docker及镜像 1.在centos上安装docker,命令如下: # yum install docker 2.让docker随机启动: # service docker start# c ...

  9. 在 Docker 上运行一个 RESTful 风格的微服务

    tags: Microservice Restful Docker Author: Andy Ai Weibo:NinetyH GitHub: https://github.com/aiyanbo/d ...

随机推荐

  1. H2内存数据库支持存储到文件

    准备工作 1.下载JDK(本人下载的版本为JDK1.7).设置环境变量JAVA_HOME,设置PATH(%JAVA_HOME%\bin%). 2.下载并解压:h2-2014-07-13.zip 官网下 ...

  2. BitAdminCore框架更新日志20180518

    20180518更新内容 1.重构调整QQ登录代码,使用JObject,减少代码,增加access_token自动续期(未测试). 2.重构调整微信登录代码,使用JObject,减少代码,增加acce ...

  3. 浅谈.NET,C#三层架构(自己总结)

     三层架构 常见架构: 三层(经典) MVC MVVM MVP   开发中常见的23种设计模式: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种: ...

  4. Elasticsearch入门 + 基础概念学习

    原文地址:https://www.cnblogs.com/shoufeng/p/9887327.html 目录 1 Elasticsearch概述 1.1 Elasticsearch是什么 1.2 E ...

  5. 用redis统计大量用户的登陆情况[只判断是否活跃]

    有这样的一个场景需求:有上亿的用户,要统计这批用户的登陆情况,例如一周连续登陆,连续三天是是否登陆,一周活跃天数等用户 存在的挑战 数据如何尽可能用小的空间存储 如何能快速获取指定的数据 如果使用文件 ...

  6. 【ocp新题】OCP 12c 062认证考试出现大量新题-8

    8. Which are two ways for a database service to be recognized by a listener in Oracle Database 12c? ...

  7. “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  8. Educational Codeforces Round 34 (Rated for Div. 2) C. Boxes Packing

    C. Boxes Packing time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  9. nginx 开启GZIP、域名指向index.html

    nginx 虽然默认开启了gzip压缩,但是有关压缩文件.压缩效率没有开启,在建设我的(个人博客)[www.fayinme.cn]中,直观的感受到gzip带来的访问速度提升的快感. 如何开启GZIP ...

  10. 一个MySQL 5.7 分区表性能下降的案例分析

    告知MySQL5.7.18的使用者分区表使用中存在的陷阱,避免在该版本上继续踩坑.同时通过对源码的讲解,升级MySQL5.7.18时分区表性能下降的根本原因,向MySQL源码爱好者展示分区表实现中锁的 ...