把AspDotNetCoreMvc程序运行在Docker上-part5:使用docker-compose
在上一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的更多相关文章
- 把AspDotNetCoreMvc程序运行在Docker上-part4:实现负载均衡
在上一part<把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器>,我们利用MySql容器和Volume实现了真正意义上的数据存储.整个结构非常简 ...
- 把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器
接上一篇博文<把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像>,这次我们看看如何使用docker存储数据. 背景 之前的示例都只有一个网站应用 ...
- 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...
- 把AspDotNetCoreMvc程序运行在Docker上-part1
接<基于ASP.Net Core学习Docker技术第一步:在CentOS7安装Docker平台>这个博文,在搭建完成Docker平台之后,可以开始让aspdotnetcore程序运行在d ...
- docker 上传到docker hub 采坑
前面是仓库名称 后面可以命名img名字 docker push gaodi2345/wj:docker_gui
- 小程序运行时如何助力传统APP转型?
小程序和H5或者RN有什么区别?优越性在哪里? 长期以来,移动互联网界一直在寻找一种既能获得Native原生的体验,又可以低门槛快速开发的技术.在这个过程中出现了很多尝试,例如React Native ...
- 在OSX和Windows版本Docker上运行GUI程序
看到很多人在Docker问题区讨论:如何在OS X和Windows的Docker上运行GUI程序, 随手记录几个参考资料: https://github.com/docker/docker/issue ...
- 在docker上运行.net core程序
一.安装docker及镜像 1.在centos上安装docker,命令如下: # yum install docker 2.让docker随机启动: # service docker start# c ...
- 在 Docker 上运行一个 RESTful 风格的微服务
tags: Microservice Restful Docker Author: Andy Ai Weibo:NinetyH GitHub: https://github.com/aiyanbo/d ...
随机推荐
- CSharp程序员学Android开发---1.初识AndriodIDE,掌握工具使用
最近公司组织项目组成员开发一个Android项目的Demo,之前没有人有Andoid方面的开发经验,都是开发C#的. 虽说项目要求并不是很高,但是对于没有这方面经验的人来说,第一步是最困难的. 项目历 ...
- 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第二节:MVC5项目结构
第一境 ASP.Net MVC5项目初探 — 第二节:MVC5项目结构 接下来,我们来看看,VS为我们自动创建的项目,是什么样子的? 可以通过菜单中[View]->[Solution Explo ...
- Validation failed for one or more entities. See ‘EntityValidationErrors’ property for moredetails[转]
这里给大家介绍一个Exception类,让我们能够轻松的知道具体的哪一个字段出了什么问题. 那就是 System.Data.Entity.Validation.DbEntityValidationEx ...
- 【cocos2d-x 手游研发----精灵的八面玲珑】
继续上一篇文章继续聊吧,这章内容会比较多,也会附上代码,很多朋友加了群,大家在群里面探讨了很多东西,这让大家都觉得受益匪浅,这便是极好的,废话不多了,精灵是游戏的重要组成部分,那ARPG里面的精灵必然 ...
- python中实现三目运算
python中没有其他语言中的三元表达式,不过有类似的实现方法 如: a = 1 b =2 k = 3 if a>b else 4 上面的代码就是python中实现三目运算的一个小demo, 如 ...
- Webstorm 的 Tab 键怎样调整缩进值? 调节成缩进成2个空格或者4个空格
原文:https://blog.csdn.net/niexia_/article/details/78280569 需求:因为用了eslint,对代码格式很严格.统一用空格.而用tab方式会省事很多. ...
- Storm集群参数调整
Supervisor 参数调整 修改${STORM_HOME}conf/storm.yaml文件内容 supervisor变更参数 slots 配置: 若storm host仅仅执行superviso ...
- Optimizing Your App for Today’s Internet
这个 session 的主讲人感觉是一个很典型的美国人,年纪也不小. 网络现状 四十亿人在使用因特网,大概占有世界人口的一半.上网人数的增长在减缓. 但是网络仍然在增长.增长点主要在物联网.第三世界国 ...
- C的Define
#define Conn(x,y) x##y //表示x连接y #define ToChar(x) #@x //给x加上单引号 #define ToString(x) #x //给x加双引号 #d ...
- D07——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D07 20180826内容纲要: 面向对象进阶学习 1 静态方法 2 类方法 3 属性方法 4 类的特殊成员方法(本节重点) 5 反射(本节重点) 6 异常(本 ...