把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 ...
随机推荐
- Eclipse使用Maven搭建Java Web项目,并直接部署Tomcat(转载)
原文地址:http://www.cnblogs.com/hackyo/p/6527910.html 1.环境: win10 Java 1.8 Maven 3.3.9 Eclipse IDE for J ...
- Excel 帮助无法正常工作的解决方法
Excel 中出现错误:帮助无法正常工作,但您仍可以转到 Office.com,以获得最新和最好的文章.视频和培训课程. 英文消息:Help isn't working, but you can st ...
- Windows下常用的100个CMD指令以及常见的操作
gpedit.msc—–组策略 2. sndrec32——-录音机 3. Nslookup——-IP地址侦测器 ,是一个 监测网络中 DNS 服务器是否能正确实现域名解析的命令行工具. 它在 Wind ...
- OC 数组以及字符串拼接与分割
//@""空的字符串对象-------分割 NSString * ptr = @"I am a man"; NSArray * array = [ptr com ...
- Python:Selenium Chrome无弹窗+property/attribute/text
我们在用Selenium写自动化程序时候,并不希望程序在实际运行过程中一直弹Chrome窗口,这个时候就需要让Chrome默默打开,自动读取数据,然后默默关闭掉就好. 以下是让chrome用无界面形式 ...
- Disruptor使用简介
disruptor是lmax公司开发的一款java高性能并发框架,其本质是一种类似队列的实现“生产者—消费者 ”模式的组件. 下面是其示例代码: public class DisruptorServe ...
- 程序媛计划——python初级class5~13
列表和元组都是可迭代对象(可以用于for in) 列表 [] #添加列表元素: list.append(argu) #修改列表: list[2] = 2017 #删除列表元素 Del list[2] ...
- A - 开门人和关门人(sort+结构体)
点击打开链接 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签 到.签离记录,请根据记录找出当天开门和关门的人. Input 测试输入的第一行给出记录的总天数N ( ...
- LOJ#3086. 「GXOI / GZOI2019」逼死强迫症(矩阵快速幂)
题面 传送门 题解 先考虑全都放\(1\times 2\)的方块的方案,设防\(i\)列的方案数为\(g_i\),容易推出\(g_i=g_{i-1}+g_{i-2}\),边界条件为\(g_0=g_1= ...
- Swift里字符串(六)Shared strings
Shared strings do not have tail-allocated storage, but can provide access upon query to contiguous U ...