自动化部署实例(donetcore GitLab CICD )

网友投稿 295 2022-10-20

自动化部署实例(donetcore GitLab CICD )

主要简单的介绍了一下 ​​GitLab CI​​​ 的持续集成以及持续部署,这篇将通过 ​​GitLab CI​​ 发布一个 .net core 项目,来带小伙伴们感受一下自动化的魅力,从此告别手动发布。

准备工作

创建一个空MVC项目来进行演示:

mkdir hello-worldcd hello-worlddotnet new sln -n HelloWorldmkdir srccd srcdotnet new mvc -n GitLabCIDemocd ../dotnet sln add .\src\GitLabCIDemo\GitLabCIDemo.csproj

完成以上创建后,用 vscode 打开应该是下面这个样子:

项目上传至 GitLab

在 gitlab 上新建一个 ​​hello-world​​ 的项目,将本地的项目上传。这个按照如下提示操作即可:

项目上传成功后,切一个 dev 分支出来,我这里的策略是,代码提交到 dev 分支是自动发布到开发环境进行验证的,生产环境是通过 master 分支打 tag 进行发布的。

切换到 dev 分支!切换到 dev 分支!切换到 dev 分支!

添加相关脚本

在 ​​hello-world​​​ 文件夹内创建 ​​.build/docker​​​ 文件夹,并添加如下脚本以及​​Dockerfile​​:

build-image.sh

docker build -f .build/docker/Dockerfile --build-arg PROJECT=$1 --build-arg ASPNETCORE_ENVIRONMENT=$2 -t $3 .

build-project.sh

set -efor arg in "$@"do target=$(pwd)/src/$arg dotnet restore -v n $target dotnet publish -c Release -o $target/publish $targetdone

push-image.sh

NEW_TAG="registry.cn-hangzhou.aliyuncs.com/xxx/$1"; // 这里得用你自己命名空间哦docker tag $1 $NEW_TAGdocker push $NEW_TAGdocker rmi $NEW_TAG

Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpineARG PROJECTARG ASPNETCORE_ENVIRONMENTENV ASPNETCORE_ENVIRONMENT ${ASPNETCORE_ENVIRONMENT}WORKDIR /appCOPY src/${PROJECT}/publish .RUN echo "#!/bin/bash \n dotnet ${PROJECT}.dll" > start.sh && chmod +x ./start.shENTRYPOINT ["./start.sh"]

这里构建镜像所使用 ​​3.1-alpine​​ 构建出来的镜像体积只有其他镜像版本构建出来体积的一半。推荐使用。到此目录结构就成了现在这样:

至此准备工作已经差不多了!我们先简单过一下 CI 的流程:

提交代码 --> 编译 --> 测试 --> 构建镜像 --> 发布

编译 -- Build

在 ​​hello-world​​​ 目录下添加 ​​.gitlab-ci.yml​​​ 文件,添加 ​​build​​ 任务:

stages: - buildhelloworld-build: stage: build tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - .build/docker/build-project.sh GitLabCIDemo artifacts: paths: - src/*/bin - src/*/publish

这里起一个容器来跑编译任务,具体细节可以看 ​​build-project.sh​​​ 脚本,用 ​​artifacts​​ 将发布出来的资源上传,给后面的 构建任务使用,不需要重复 build,节约时间。这里执行会出现如下错误:

/bin/bash: line 89: .build/docker/build-project.sh: Permission denied

这是因为脚本没有执行权限,通过 ​​chmod​​ 命令可以解决:

chmod +x build-image.sh build-project.sh push-image.sh

重新提交,触发 build 任务。打开 GitLab CI 界面,执行成功,是不是很开心呢?

测试 -- Test

现在项目里面没有测试代码,那就新建一个吧。在 ​​hello-world​​ 根目录下:

mkdir testcd testdotnet new xunit -n GitLabCIDemo.UnitTests

更新 ​​.gitlab-ci.yml​​ 添加 Test 任务:

stages: - build - testhelloworld-build: stage: build tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - .build/docker/build-project.sh GitLabCIDemo artifacts: paths: - src/*/bin - src/*/publishhelloworld-test: stage: test tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - dotnet test -c Release dependencies: - helloworld-build

等待一会,查看 CI 运行。

构建 Docker 镜像 -- Pack

我这里使用的是阿里云的镜像仓库,需要现在阿里云上创建对应的命名空间以及镜像名称。我这里给镜像名取名为 ​​hello-world​​​,别忘了修改 ​​push-image.sh​​ 中的命名空间哦!

更新 ​​.gitlab-ci.yml​​ 添加 Pack 任务:

stages: - build - test - packhelloworld-build: stage: build tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - .build/docker/build-project.sh GitLabCIDemo artifacts: paths: - src/*/bin - src/*/publishhelloworld-test: stage: test tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - dotnet test -c Release dependencies: - helloworld-buildhelloworld-pack-staging: stage: pack tags: - shell script: - .build/docker/build-image.sh GitLabCIDemo Staging hello-world:beta - .build/docker/push-image.sh hello-world:beta dependencies: - helloworld-build only: - dev

​​Staging​​: 用来设置环境变量 ​​ASPNETCORE_ENVIRONMENT​​,让 ​​.net core​​ 读取对应的配置文件,可以设置​​Development​​,​​Staging​​,​​Production​​ 三种,可以在对应的环境设置对应环境变量,使用不同配置。beta: 因为是开发环境,就一直使用同一个 tag 去覆盖之前的镜像,每次 pull 最新的镜像就好了,也可以使用 ​​$CI_COMMIT_SHORT_SHA​​ 使用当前 git 提交的 hash 值作为版本号

CI 应该执行的差不多,再去瞧瞧呗! 又是全绿,真是开心!额,全绿,怪怪的...

打开阿里云镜像容器服务,查看一下刚刚上传的容器镜像吧!

部署 -- Deploy

这里我图方便就使用 ​​docker-compose​​ 来做演示了,通常部署环境都是使用集群来部署的,当然单机部署也不是不无可能的,我内网用 k3s 搭建的一个集群,为啥不用 k8s,因为要求资源配置比较高,k3s 刚好够用。但是部署到 k3s 需要写挺多的配置的文件,可以单独写一篇博文介绍。

作为自动化最后一步,无论你是用 ​​k8s​​​,​​k3s​​​,​​docker swarm​​​......,都是拉取对应的镜像,进行部署。思路是一样的,只是部署方式略有不同。这里通过 docker-compose 来发布 ​​hello-world​​ 应用咯。

在部署的 Linux 服务器上创建文件夹 ​​/deploy​​​ ,在目录下添加 ​​docker-compose.yml​​ 文件,添加如下内容:

version: "3.8"services: hello-world: image: registry.cn-hangzhou.aliyuncs.com/jd-rd/hello-world:beta container_name: hello-world restart: always ports: - 5013:80 networks: - basic_service networks: basic_service:

更新 ​​.gitlab-ci.yml​​,添加部署任务:

stages: - build - test - pack - deployhelloworld-build: stage: build tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - .build/docker/build-project.sh GitLabCIDemo artifacts: paths: - src/*/bin - src/*/publishhelloworld-test: stage: test tags: - docker image: mcr.microsoft.com/dotnet/core/sdk:3.1 script: - dotnet test -c Release dependencies: - helloworld-buildhelloworld-pack-staging: stage: pack tags: - shell script: - .build/docker/build-image.sh GitLabCIDemo Staging hello-world:beta - .build/docker/push-image.sh hello-world:beta dependencies: - helloworld-build only: - devdeploy-staging: stage: deploy tags: - staging script: - cd /deploy && docker-compose pull && docker-compose up --force-recreate -d && docker ps only: - dev

等待整个CI跑完,查看 CI 运行结果

通过服务器IP + 5013 访问应用了,就可以看到服务更新

修改一下 ​​Index.cshtml​​​ 将 ​​Welcome​​​ 修改为 ​​Hello Devops !​​ ,重新提交一下,稍等片刻,重新访问即可看到变化了。

至此一个简单的 CI 流程已经走完了,各位看官可以根据自己的需求,继续探索。

题外话

如果将脚本都放在项目里面的话,将来涉及到脚本变更,需要每个项目都给改过去,这是十分痛苦的事情。这里推荐小伙伴可以通过 ​​git submodule​​ 子模块的方式进行引用,将公共的脚本都给提取出来,项目通过子模块来加载脚本项目,将来脚本变更,每个项目只需要更新一下子模块就好。

总结

通过以上一个小案例已经带小伙伴了解了一圈 ​​GitLab-CI​​​ 如何来发布一个 ​​.net core​​​ 应用,感受了一下 ​​GitLab-ci​​​ 的魅力。但是以上方案还是有瑕疵的,对于单体应用来说,没有太大问题,但并不适合微服务项目。在微服务项目中,如果多个服务散落在多个仓库中,需要多个项目代码改动其实是很不方便的,所以现在很多的微服务项目都采用 ​​Mono​​​ 仓库风格及将所有的服务都放在一个仓库里面,仓库体积虽然大,但是改动起来更方便。本篇就先到这里了,有关于 ​​GitLab-CI​​​ 对于 ​​Mono​​​ 仓库风格项目 ​​CI&CD​​ 探索实践,且听下回分解。

常见问题:

1、ci时报错:bash: line 119: dotnet: command not found

Unable to locate package dotnet-sdk-5.0

E: Couldn’t find any package by glob ‘dotnet-sdk-5.0’

E: Couldn’t find any package by regex ‘dotnet-sdk-5.0’

#解决方案:

wget -q -O packages-microsoft-prod.deb

sudo dpkg -i packages-microsoft-prod.deb

sudo apt-get update

apt search dotnet-sdk

然后重新运行安装指令即可。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:使用HttpSessionListener监听器实战
下一篇:Docker系列 | SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Try again768
相关文章

 发表评论

暂时没有评论,来抢沙发吧~