Asp.NetCore轻松学-使用Docker进行容器化托管
前言
没有 docker 部署的程序是不完整的,在写了 IIS/Centos/Supervisor 3篇托管介绍文章后,终于来到了容器化部署,博客园里面有关于 docker 部署的文章比比皆是,作为硬核实战派,这里做的一定是一套打完带走的功法。本文使用的学习机器是由 Azure 倾情提供的 30 天试用版本,大家都可以申请的哈。
1. 为什么要使用 docker
1.1 docker 介绍
docker 带来的好处是显而易见的,使用 docker 可以在同一台服务器上部署多个版本的应用,彼此间不会引起冲突,更快的迁移过程,当需要增加服务实例的时候,只需要下载 docker 镜像即可部署运行,无需担心环境初始化等一系列前置工作,目前使用 docker 基于阿里云弹性计算的应用已经非常广泛,docker 容器内部就是一个独立的虚拟机,在容器中,你可以做一切你想做的工作,比如测试、代码编译,基于容器的版本回滚也非常的方便;有人说,使用了 docker 而没有使用容器编排的话是没有意义的;朋友们,不要听人云亦云, docker 的存在,本意并非面向大型应用,现在大量的微服务化就已经证明了 docker 是一个小巧、灵活的载体,所以,在单体应用中使用 docker 也是非常有必要的。
1.2 应用举例
举个例子,某外包公司为某企业开发了一款基于图像识别的程序套件,最初部署上线是使用 .NET Core 1.0 ,而由于技术迭代和业务的发展,甲方要求该套件必须升级到 .NET Core 2.0+,而该套件程序目前运行于正式环境中,且不能停机,这就是传说中的给飞行中的飞机换引擎;首先,在当前正式环境安装 .NET Core 2.0 风险较大,谁也不能保证没有兼容性问题;其次,使用另外一台服务做 .NET Core 2.0 的升级方案,但是该方案的缺点是需要增加服务器、且需要调整反向代理配置;开发方结合现实,给出 docker 部署升级的方案,通过容器化部署,对现有生产环境几乎就是零影响,且无需增加服务器和修改反向代理配置。
2 Centos 服务器安装前置条件
2.1 安装 docker-ce
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2

添加包源
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

开始安装 docker-ce
sudo yum install docker-ce docker-ce-cli containerd.io
安装完成,输入
docker --version

- 表示安装成功,但是仅仅是安装成功,截至目前, docker 还没有启动,我们还需要手动启动 docker 服务,输入下面的命令
sudo systemctl start docker
*测试运行
sudo docker run hello-world

看上图红框处的两个消息,当输入命令 sudo docker run hello-world,docker 检查到本地仓库没有名称为:hello-world 的镜像,马上从官方仓库中拉取了该镜像,然后执行,hellow-world 执行后输出信息在红框 2 处,表示您安装的 docker 程序已经安装成功并成功使用容器运行。
2.2 使用安装脚本安装 docker
好消息是,当你对上面的一堆命令非常茫然的时候,docker 官方提供了一份安装脚本,可以一键安装 docker ,地址在:https://github.com/docker/docker-install,注意使用该脚本的权限,并且始终验证脚本的合法性
3. 开始使用 Dockerfile
3.1 为 .NET Core 应用程序编写 Dockerfile 文件
为了将 .NET Core 应用程序进行容器化,我们需要为程序编写一个 Dockerfile 文件,正如其名称一样,该文件的名字也需要命名为 Dockerfile,,然后将其放入程序根目录下,还是以之前的 Deploy.Linux 程序为例子,在 Deploy.Linux 根目录下创建 Dockerfile
我们有两种创建 Dockerfile 文件的方式
通过开发工具 visual studio 右键点击项目:添加-> Docker 支持

或者手动创建该文件,一个标准的 Dockerfile 如下
FROM microsoft/dotnet:2.2-sdk #这是第一个指令,必须是 FROM 这里指定基础构建镜像
WORKDIR /app #工作目录,即程序运行根目录
COPY *.csproj ./ #复制文件到容器中
RUN dotnet restore #下载项目依赖项
COPY . ./ #将剩余文件复制到容器中
RUN dotnet publish "Deploy.Linux.csproj" -c Release -o /app #发布容器中的项目到 容器中 /app 目录
ENTRYPOINT ["dotnet", "Deploy.Linux.dll"] #运行镜像入口命令和可执行文件名称
3.2 构建镜像
创建完 Dockerfile 文件后,将项目文件 copy 到服务器上,定位到目录 Deploye.Linux ,执行以下命令
sudo docker build -t demo .
- 注意:上面这条命令后面的小数点不是笔误,是必须的!
看到输出结果提示:Successfully tagged demo:latest 表示镜像构建成功

输入命令查看仓库中的镜像,可以看到 demo 镜像已经安静的躺在那里等待我们去开发了
sudo docker images

3.3 运行镜像
现在,可以输入命令运行我们刚刚创建的 demo 镜像了
sudo docker run -d -p 80:80 -e --name demo demo:latest . -v /data/logs/demo:/data/logs/demo


现在大家打开我 Azure 云主机的地址访问:http://139.219.9.102/(学习机器,可能会过期) ,目前运行的程序正是基于 dokcer 容器的实例
非常开心,使用 docker 进行容器化部署成功!!!
4. 扩展的 docker 学习
当我们成功部署第一个 docker 应用后,后续的问题也随之而来了,比如更新,这个是无法回避的问题,从部署完成的那一刻开始就如影随形,所以,学习其它的 docker 命令是非常有必要的
4.1 更新程序
容器化部署的每一次更新都伴随着下面的步骤,长此以往,生生不息
*步骤说明
1、编译
2、打包
3、发布
4、运行
我们可以把这些步骤都整合成一份脚本文件,每次都去执行该脚本即可,方便又安全,当后续引入 Jenkins 进行自动化构建之后,我们直接把该脚本迁移到 Jenkins 中即可,还是以当前的实例 Deploy.Linux 为例子,编写 demo.sh 脚本文件如下:
sudo docker build -t demo . #开始执行Dockerfile进行构建
sudo docker images -a #列出现有仓库的镜像列表
sudo docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop #查找并停止镜像
sudo docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm #移除已停止的镜像
sudo docker images -q -a | xargs docker inspect --format='{{.Id}}{{range $rt := .RepoTags}} {{$rt}} {{end}}'|grep -v ':' #移除悬空镜像,没起作用,求指导
sudo docker ps -a #列出所有实例
sudo docker stop demo #停止demo实例
sudo docker rm demo #移除demo实例
sudo docker run -d -p 80:80 --name demo demo:latest . -v /data/logs/demo:/data/logs/demoo docker run -d -p 80:80 -e --names demo demo:latest . -v /data/logs/demo:/data/logs/demo #指定demo镜像,运行demo实例
为了使用脚本,我们必须为 docker 用户赋予 root 用户组权限,否则 docker 无权执行停止实例等操作,执行下面的命令
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp - docker
好了,现在可以愉快的执行脚本了,使用下面的命令执行一键构建镜像
sudo sh demo.sh

4.2 进入镜像
进入运行中的容器的方法有多种,掌握一种足够,在控制台输入命令
sudo docker exec -it demo /bin/bash

在容器内部使用命令和在 Centos 系统中一样,可以看到我们 demo 程序的执行目录 /app
结束语
通过本文,我们学习了以下内容
1、在 Centos 中安装 docker
2、编写 Dockerfile 文件
3、在容器中构建 .NET Core 程序
4、编写自动化构建脚本,为迁移到 Jenkins 做准备
5、学习了一些基本的 docker 扩展命令
Asp.NetCore轻松学-使用Docker进行容器化托管的更多相关文章
- 目录---Asp.NETCore轻松学系列【目录】
随笔分类 - Asp.NETCore轻松学系列 Asp.NETCore轻松学系列阅读指引目录 摘要: 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进 ...
- 【目录】Asp.NETCore轻松学系列
随笔分类 - Asp.NETCore轻松学系列 Asp.NETCore轻松学系列阅读指引目录 摘要: 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进 ...
- Asp.NETCore轻松学系列阅读指引目录
前言 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进阶,适合没有 .NETCore 编程经验到小白同学,也适合从 .NET Framework 迁移 ...
- Asp.NetCore轻松学-使用Supervisor进行托管部署
前言 上一篇文章 Asp.NetCore轻松学-部署到 Linux 进行托管 介绍了如何在 Centos 上部署自托管的 .NET Core 应用程序,接下来的内容就是介绍如何使用第三方任务管理程序来 ...
- ASP.NET Core使用Docker进行容器化托管和部署
一.课程介绍 人生苦短,我用.NET Core!今天给大家分享一下Asp.Net Core以Docker进行容器化部署托管,本课程并不是完完全全的零基础Docker入门教学,课程知识点难免有没覆盖全面 ...
- Asp.NetCore轻松学-部署到 IIS 进行托管
前言 经过一段时间的学习,终于来到了部署服务这个环节,.NetCore 的部署方式非常的灵活多样,但是其万变不离其宗,所有的 Asp.NetCore 程序都基于端口的侦听,在部署的时候仅需要配置侦听地 ...
- Asp.NetCore轻松学-部署到 Linux 进行托管
前言 上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS,且学习了进程内托管和进程外托管的区别:接下来就要说说应用 Asp.Net Core 的特性(跨平台),将 .Ne ...
- Asp.NetCore轻松学-配置服务 apollo 部署实践
前言 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置 ...
- Asp.NetCore轻松学-实现一个轻量级高可复用的RabbitMQ客户端
前言 本示例通过对服务订阅的封装.隐藏细节实现.统一配置.自动重连.异常处理等各个方面来打造一个简单易用的 RabbitMQ 工厂:本文适合适合有一定 RabbitMQ 使用经验的读者阅读,如果你还没 ...
随机推荐
- MySQL的变量分类总结
在MySQL中,my.cnf是参数文件(Option Files),类似于ORACLE数据库中的spfile.pfile参数文件,照理说,参数文件my.cnf中的都是系统参数(这种称呼比较符合思维习惯 ...
- JavaScript高级程序设计(二)
一.函数 1.1 JS中函数无重载,同一作用域下定义两个函数,而不会引发错误,但真正调用的是后面定义的函数.例如: function doAdd(iNum){ alert(iNum+100); } f ...
- 重温《STL源码剖析》笔记 第一章
源码之前,了无秘密. --侯杰 经典的书,确实每看一遍都能重新收获一遍: 第一章:STL简介 STL的设计思维:对象的耦合性极低,复用性极高,符合开发封闭原则的程序库. STL的价值:1.带给我们一套 ...
- VueJs 权限管理
程序运行时,router只配置登陆 首页404 等基本页面 import Main from '@/views/Main.vue'; // 不作为Main组件的子页面展示的页面单独写,如下 expor ...
- 由清除float原理到BFC
关于浮动 设置为浮动的元素会脱离当前文档流,向左或向右移动直到边缘遇到另一个浮动元素或者到达边界.普通元素不会对齐造成影响. 浮动是把双刃剑,在给我们的布局带来便利的同时有一些缺点需要我们去解决.例如 ...
- java定时任务调度-Timer(1)
一.定义 有且仅有一个后台线程对多个业务线程进行定时定频率的调度 二. Timer ----> Timer Task (中有run();方法) 通过 new Timer().schedul ...
- CDN及CDN加速原理
本想自己写这个主题的文章,但网上已经有人写了一篇非常好的文章,觉得难以望其项背.就没有必要再写,直接转载如下: 在不同地域的用户访问网站的响应速度存在差异,为了提高用户访问的响应速度.优化现有Inte ...
- String的indexOf()用于获取字符串中某个子字符串的位置
indexOf作用:用于检索一个字符串在另一个字符串中的位置. indexOf的几个重载方法如下: int indexOf(String str) 意思为在字符串中检索str第一次出现的位置,如果找 ...
- capwap学习笔记——初识capwap(三)(转)
2.5.6 CAPWAP状态机详解 2.5.6.1 Start to Idle 这个状态变迁发生在设备初始化完成. ¢ WTP: 开启CAPWAP状态机. ¢ AC: 开启CAPWAP状态机. ...
- iOS常用控件尺寸大集合
元素控件 尺寸(pts) Window(含状态栏) 320 x 480 Status Bar的高度 20 Navigation Bar的高度 44 含Prompt的Navigation Bar的高度 ...