把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,实际上就是把之前的工作都放到一个批处理文件里执行,将所有服务当做一个整体来管理,同时也提供了遍历站点扩容和降级的方式。看起来已经很方便了,当然还没完,后续还有大招。

时间: 2024-10-08 02:45:35

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

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

在上一part<把AspDotNetCoreMvc程序运行在Docker上-part3:使用独立的存储容器>,我们利用MySql容器和Volume实现了真正意义上的数据存储.整个结构非常简单,就是一个web容器和一个数据库容器,是一个简单的应用.如今都流行支持高并发,集群什么的,最起码要有多个web服务器,于是通常要用到负载均衡的技术,比如HAproxy,Nginx等等.那么这一部分,我们接着用Docker技术实现负载均衡,其实说严格还是用的老技术,只不过包装到了Docker容器中而已. 自定

在Windows版本Docker上运行GUI程序

看到很多人在Docker问题区讨论:如何在OS X和Windows的Docker上运行GUI程序, 随手记录几个参考资料: https://github.com/docker/docker/issues/8710 http://sourceforge.net/projects/xming/ https://www.gitbook.com/book/yeasy/docker_practice/details

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

tags: Microservice Restful Docker Author: Andy Ai Weibo:NinetyH GitHub: https://github.com/aiyanbo/docker-restful-demo 实现构思 1. 使用 Maven 进行项目构建 2. 使用 Jersey 实现一个 RESTful 风格的微服务 3. 在 Docker 里面执行 mvn package 对项目打包 4. 在 Docker 容器里运行这个微服务 实现一个微服务 场景 & 需求

NetCore 2.0 应用程序在centos 7上通过docker发布

一  安装netcore 2.0 SDK 在centos 上面安装netcore 2.0 与window上面是不太一样的,注意,linux是不支持同时安装两个版本的.netcore SDK的,由于我之前开发过netcore 1.04 的,现在需要升级到2.0的SDK 那如何升级. 1.找到当前的安装路径: 2.安装.netcore 2.0 在这边找到你要安装的对应的包:https://www.microsoft.com/net/download/linux 打开  yum instruction

记录第一次简单部署asp.netcore程序到Docker上

linux版本:centOS7 1.安装docker :yum -y install docker-io 2.安装dontnetcore镜像:docker pull microsoft/dotnet 如果出现 net/http: TLS handshake timeout 安装超时的错误,说明是无法进入docker.hub 解决办法添加国内镜像地址: vim  /etc/sysconfig/docker 打开docker的配置文件, 在OPTIONS上追加 --registry-mirror=h

简单C程序在IA-32 CPU上运行过程的分析

本文将通过编译器生成的汇编代码分析C程序在IA-32体系PC上的运行流程 实验环境: gcc 4.8.2 C语言程序的内存结构 C代码如下 int g(int x) { return x + 1; } int f(int x) { return g(x); } int main(void) { return f(2) + 3; } 使用编译命令gcc -S -O0 -o main.s main.c -m32编译出汇编文件,如下 g: pushl %ebp movl %esp, %ebp movl

【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”

原文网址:http://www.cnblogs.com/Dageking/archive/2013/05/15/3079394.html VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application” 升级vs2010到vs2012,突然发现build出来的应用程序无法运行,提示“不是有效的 win32 应用程序” or “not a valid win32 application”. 参考CSDN论坛

让VC编译的Release版本程序在其他机器上顺利运行

链接的时候分静态链接和动态链接两种. 静态连接的话,基本上就不需要向目标机器拷贝附加的文件了,方法如下: 1.修改编译选项,将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就 不再需要VC的dll了. 2.工程->属性->配置属性->常规->MFC的使用,选择“在静态库中使用mfc”. 动态连接的话,需要在目标机器上拷贝mfc所依赖的动态库.根据你使用的VC版本不同而不同: VC6的话,一般包括mfc42.dll.msvcrt.dll.ms

06、部署Spark程序到集群上运行

06.部署Spark程序到集群上运行 6.1 修改程序代码 修改文件加载路径 在spark集群上执行程序时,如果加载文件需要确保路径是所有节点能否访问到的路径,因此通常是hdfs路径地址.所以需要修改代码中文件加载路径为hdfs路径: ... //指定hdfs路径 sc.textFile("hdfs://mycluster/user/centos/1.txt") ... ? 修改master地址 SparkConf中需要指定master地址,如果是集群上运行,也可以不指定,运行时可以通