热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于Docker构建-NET持续集成环境

  最近在考虑将整个项目组的产品,努力向着持续集成(CI)持续部署(CD)的方向靠拢,因为目前我们仅仅实现了基于Docker的自动化部署,而部署包的构建依然依赖于人工打包,而每个版本的测试和部

  最近在考虑将整个项目组的产品,努力向着持续集成(CI)/持续部署(CD)的方向靠拢,因为目前我们仅仅实现了基于Docker的自动化部署,而部署包的构建依然依赖于人工打包,而每个版本的测试和部署,基本上都要给所有相关人员发一遍邮件,而写邮件无非是填写版本号和变更历史。身处在这样一个社会化分工逐渐加剧的『摩登时代』,我们唯一的希望就追求技能的多元化,你越是担心有一天会被AI所替代,就越是应该去追求灵动与美。这个世界何尝不是一个运行中的大型机器,可恰恰就是这种掺杂了情感的冰冷法则,让我们意识到需要更多的理解和宽容。管理者常常迷信敏捷开发的人月神话,希望人可以像零件一样按部就班,在这场噩梦到来以前,为何不去做一点更有用的事情,让云计算帮我们解放双手。

背景说明

  我们的产品,从结构上来讲,分为后端、前端和客户端三个部分,其中,后端提供了从认证到上传、查询和下载等主要的AP接口;前端提供了基于后端API接口的页面,主要功能是监控和管理;客户端承担了主要的业务交互能力,主要功能是整合常用的硬件资源。从技术上来讲,后端是基于Spring Cloud的微服务架构,前端是基于node.js的典型前端工具链,而客户端是基于.NET/Win32的技术体系。所以,即使我们的客户端是运行在Window平台上,我们依然有大量的服务是运行在Linux环境下。负责部署的同事不愿意单独再构建一套持续集成(CI)环境,所以我们决定借助Docker完成整个持续集成(CI)环境的构建。

构建过程

  完成整个项目的构建,需要覆盖到代码编译、单元测试、静态检查、版本发布这四个基本环节,我们整体上使用Jenkins 作为内部持续集成的平台,这意味着我们只需要在提交代码或者合并代码的时候,触发一个构建指令即可。这里我们考虑通过Docker来完成这些工作,一个整体上的设计思路如下图所示:
构建思路

MSBuild

  首先是MSBuild,它是我们整个构建流程中最重要的环节,我们平时通过Visual. Studio编译一个项目,背后其实就是由MSBuild这个构建工具来驱动,而通过MSBuild我们定义更多的构建流程,例如执行单元测试、实现Zip打包等等的流程。在Window平台下我们安装Visual Studio后就可以使用MSBuild,那么在Linux平台下呢?目前,MSBuild已经被微软开源并托管在Github上,大家可以通过这个地址:https://github.com/Microsoft/msbuild来访问。通过阅读MSBuild的文档,我们了解到,目前MSBuild实际上有三个流向,分别是目前官方主推的.Net Core、传统.Net Framework以及由Mono托管的部分。

  .Net Core中MSBuild实际上被集成在.Net CLI中,熟悉.NET Core的朋友一定都知道,.NET Core类型的项目,是可以直接通过dotnet命令来创建项目、还原Nuget包、运行项目、构建项目和发布项目的,可以想象的到这些功能是依赖MSBuild和Nuget的,可惜这种目前对我们来说不太适合。接下来,我们有两个选择,一个是Full Framework,一个是Mono,因为我们的服务器是一台Linux服务器,所以Full Framework对我们来说不适合,我们在无奈的情况下选择了Mono,按照官方文档,从源代码安装过程如下:

git clone -b xplat-master https://github.com/mono/msbuild/
cd msbuild
make

  果不其然,这个无论是在Linux主机还是Docker中都失败了,官方的源代码我们编译不过去,那就只能考虑非源代码安装啦!按照官方的说法,我们需要Mono,所以兴奋地跑到Mono官方去安装,根据以前使用Mono的经验,飞快地在终端里输入下面两行代码:

sudo apt-get install mono-runtime
sudo apt-get install mono-xbuild

  装完以后,发现可以使用Mono和XBuild,可无奈是XBuild版本实在太低,换句话说我们从Ubuntu官方源里安装完的Mono相当于.NET Framework 2.0的版本,这怎么可以呢?果断从Mono官方下载最新版本的Mono,这是一个经过反复试验的安装方法:

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
sudo apt install apt-transport-https -y
sudo apt-get install wget -y
echo "deb https://download.mono-project.com/repo/ubuntu stable-trusty main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt-get update
sudo apt-get install aptitude -y
sudo apt-get install -f
sudo apt-get install -y git
sudo aptitude install -y mono-complete

  这里顺带安装了git和wget,因为下面我们会用到这两个软件。aptitude实在是修复Linux依赖问题的神器,我准备找时间用它修复下我的Linux环境。apt-transport-https这个是为了支持https协议,这个不用说太多,我们选择了最全的一个Mono版本mono-complete,它包含了我们在Linux下可以使用的所有程序集,换句话说,这些程序集以外的程序集,或者是和Windows联系紧密的COM组件、OCX等等,想都不要想啦,只有一件事情是对的,对平台的依赖越少,跨平台的可能性越高。

Nuget

  Nuget是.NET下使用最多的包管理器,虽然目前.NET Core里的依赖管理越来越像Maven,可我觉得作为整个构建工具里的一环,还是应该考虑进来,虽然我们的项目中的第三方库基本都靠拷。Nuget只有单独的命令行版本和Visual Studo扩展两个版本,这里我们使用wget下载命令行版本,然后再通过Mono来调用nuget.exe:

sudo wget https://dist.nuget.org/win-x86-commandline/v4.6.2/nuget.exe /usr/local/bin/nuget.exe
alias nuget="mono /usr/local/bin/nuget.exe"

Sonar

  对于Sonar的话,这里我推荐用SonarCloud,因为我们只需要通过wget下载SonarScanner,然后通过Mono调用并提供SonarCloud提供的token即可。曾经博主写过一篇关于使用SonarCloud为.NET/.NET Core项目提供静态检查的文章,在这篇文章中我们提到,SonarCloud支持.NET Framework 4.6+以上的版本以及.NET Core版本,所以,这里我们沿用当时的脚本即可,想了解SonarCloud的朋友,可以找到这篇文章进行深入了解。下面给出脚本:

sudo wget https://github.com/SonarSource/sonar-scanner-msbuild/releases/download/4.3.0.1333/sonar-scanner-msbuild-4.3.0.1333-net46.zip sonar-scanner.zip
sudo unzip sonar-scanner.zip
sudo alias sonar-scanner="mono ./sonar-scanner/SonarQube.Scanner.MSBuild.exe"
sonar-scanner begin /k:"Sonar-HttpServer" /d:sonar.organization= /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login=
msbuild /t:Rebuild
sonar-scanner end /d:sonar.login=

NUnit

  既然我们有了Nuget,那么自然要用Nuget来做点事情。对于单元测试,微软提供的MSTest功能相对薄弱,关键是严重依赖Visual Studio,一旦我们想要移植到Linux平台下,就会发现阻力重重,所以在平时开发中,我更建议大家去使用NUnit或者XUnit,它们比MSTest功能强大,可以直接通过Nuget安装,同时自带TestRunner,这是一个控制台程序,我们直接通过Mono调用它,并把单元测试项目生成的动态链接库作为参数传递给它即可。
下面给出基本的脚本:

nuget install NUnit.Runners -Version 3.8.0 -OutputDirectory ./TestRunner
alias nunit="mono ./TestRunner/NUnit.ConsoleRunner.3.8.0/tools/nunit3-console.exe"
nunit <Your-UnitTest-Project>

牛刀小试

  下面我们来试试在Docker里完成镜像的构建,其实这里更推荐在Linux下安装Docker,博主在Window平台下安装了Docker for Windows,需要系统支持虚拟化技术。因为博主在构建镜像的时候,一直提示磁盘空间不足,所以,这里我们把Dockerfile放到DaoCloud上去跑,关于Docker的安装以后有机会在同大家分享。这里,DaoCloud你可以理解为一个帮我们装好了Docker的云主机,事实上用DaoCloud以后,感觉测试Dockerfile可以更省时间啦,效率上相差十倍啊!Dockerfile其实就是本文中这些脚本的集合,这里我们给出完整的Dockerfile,这个文件可以从这里获取:

FROM ubuntu:14.04
LABEL vendor="qinyuanpei@163.com"

# Install Mono && XBuild
RUN sudo apt-get update
RUN sudo apt-get upgrade -y
RUN sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN sudo apt install apt-transport-https -y
RUN sudo apt-get install wget -y
RUN echo "deb https://download.mono-project.com/repo/ubuntu stable-trusty main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
RUN sudo apt-get update
RUN sudo apt-get install aptitude -y
RUN sudo apt-get install -f
RUN sudo apt-get install -y git
RUN sudo apt-get install -y zip
RUN sudo apt-get install -y unzip
RUN sudo aptitude install -y mono-complete

# Intall Nuget
RUN sudo wget -O nuget.exe https://dist.nuget.org/win-x86-commandline/v4.6.2/nuget.exe 
#RUN alias nuget="mono nuget.exe"

# Install Sonar-Scanner
RUN sudo wget -O sonar-scanner.zip https://github.com/SonarSource/sonar-scanner-msbuild/releases/download/4.3.0.1333/sonar-scanner-msbuild-4.3.0.1333-net46.zip
RUN sudo unzip sonar-scanner.zip -d ./sonar-scanner
#RUN alias sonar-scanner="mono .SonarQube.Scanner.MSBuild.exe"

# Install NUnit
RUN mono nuget.exe install NUnit.Runners -Version 3.8.0 -OutputDirectory ./TestRunner
#RUN alias nunit="mono ./TestRunner/NUnit.ConsoleRunner.3.8.0/tools/nunit3-console.exe"

# Build Project && Sonar Analyse && UnitTest
RUN git clone https://github.com/qinyuanpei/HttpServer.git
RUN sudo mono ./sonar-scanner/SonarQube.Scanner.MSBuild.exe begin /k:"Sonar-HttpServer" /d:sonar.organization="qinyuanpei-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="db795a28468dc7c12805b330afed53d362fdd2d9"
RUN msbuild /p:COnfiguration=Release ./HttpServer/HTTPServer/HTTPServer.sln
RUN sudo mono ./sonar-scanner/SonarQube.Scanner.MSBuild.exe end /d:sonar.login="db795a28468dc7c12805b330afed53d362fdd2d9"
# RUN mono ./TestRunner/NUnit.ConsoleRunner.3.8.0/tools/nunit3-console.exe ./HttpServer/HTTPServer/HTTPServerLib.UnitTest/bin/Release/HttpServerLib.UnitTest.dll
EXPOSE 2048

好了,下面我们通过Dockerfile来构建镜像,这里不需要考虑部署,我们就是在Docker这个环境里跑跑结果(PS:不知道为什么alias在Docker里不起作用):

docker build -t httpserver:v1 . 

可以看到,我们整个过程除了单元测试没有通过以外,其它的环节都非常顺利,这其中一个重要的原因是,博主这个项目对Window依赖较少,它是一个C#开发的简易Web服务器,主要是类库和控制台程序,可以完美地运行在Linux平台下,所以,跨平台最终考验的还是开发人员。
Docker中构建的结果

One More Thing

  这里我们主要针对的是.NET Framework,那么针对传统的ASP.NET以及最新的.NET Core又该如何做持续集成呢?这里简单说一下思路,具体的Dockerfile大家可以去DockerHub去找(抄),这里我就不帮大家写了。对于传统的ASP.NET,在本文的基础上增加Jexus就可以做Linux下的部署,当然,前提是要避免和Window太过紧密的耦合,否则即便是大罗神仙亲临,这持续集成永远都是个梦。对于.NET Core,只要安装了它的SDK,编译、依赖管理、发布、部署都不再是问题,只要完善下单元测试和静态检查就可以,因为它是可以自部署的,并且天生就是为了跨平台而生,如果有可能,还是考虑用.NET Core吧,Windows最适合的还是吃鸡打游戏(逃……

本文小结

  读过我之前博客的朋友,一定会发现,我今天这篇博客里所做的事情,同我曾经在.NET项目上使用TravisCI是完全一样的,所不同的是,TravisCI里的构建环境是别人提供好的,而这里的构建环境是我们自己搭建的。这并不是在做无用功,如果你需要搭建私有的Linux下的构建环境,我相信这篇文章会带给你一点启示。项目组最后还是放弃了这个方案,因为产品里集成了太多和Window关联的东西。而负责部署的同事最终如释重托,因为他们不必去踩这些无聊的坑,可对我来说,这像一道屈辱的烙印刻在我的心上,我甚至试过在Docker环境里搭建Window的环境,哪怕最终我发现我不能把Docker当一个虚拟机来用,我越来越害怕自己对那些变化一无所知,还庆幸自己可以在时光的影子里偷懒。

  有时候,人们假装配合持续集成的流程,因为它听上去非常美好,可对环境的依赖不愿意削弱,对单元测试不是那么重视,对代码质量不是那么在意,这一切又永远都只是听上去美好而已。我听到有面试官在面试的时候,批评面试者所做的运维工作不是那么的高大上,毕竟我们只是写了点脚本而已,离面试官心中的DevOps相去甚远。可MSBuild是XML写成的脚本,make不过是个纯文本的脚本,到底哪一种更高大上?我在这篇文章里使用了Docker,能否让我的工作显得高大上?我们的工作到底有多少能适应DevOps?我觉得想清楚这个再谈高大上,不是不可以啊?对吧?好了,这就是这篇文章的全部内容啦,谢谢大家!


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 如何利用 Myflash 解析 binlog ?
    本文主要介绍了对Myflash的测试,从准备测试环境到利用Myflash解析binl ... [详细]
  • DockerDataCenter系列(四)-离线安装UCP和DTR,Go语言社区,Golang程序员人脉社 ... [详细]
  • 这么多流媒体服务器?你怎么技术选型?
    在上一篇文章里我们介绍了我们介绍了MCU和SFU的优缺点,webRTC通信方案SFU和MCU的区别?下面就来探讨下常见的SFU开源解决方案,当然,你也可以自己实现SFU流媒体服务器 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文详细介绍了如何创建和使用VUE uni-app开发环境,包括通过HBuilderX可视化界面和通过vue-cli命令执行的方法。文章内容简单清晰,易于学习与理解。通过学习本文,读者可以深入了解VUE uni-app开发环境,并通过实践验证掌握具体的使用情况。编程笔记将为读者推送更多相关知识点的文章,欢迎关注! ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • k8s+springboot+Eureka如何平滑上下线服务
    k8s+springboot+Eureka如何平滑上下线服务目录服务平滑上下线-k8s版本目录“上篇介绍了springboot+Euraka服务平滑上下线的方式,有部分小伙伴反馈k ... [详细]
  • 这篇文章给大家介绍怎么从源码启动和编译IoTSharp ,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。IoTSharp项目是 ... [详细]
  • 1jdk去网站下载,然后拷贝到linux上;或直接wgethttp:download.oracle.comotn-pubjavajdk8u181-b1 ... [详细]
author-avatar
手机用户2502929291_707
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有