.Net微服务实战之CI/CD
系列文章
相关源码:https://github.com/SkyChenSky/Sikiro
地基
在软件工程不少的思想、概念来源于建筑工程,大家也喜欢把开发软件比喻成建房子。那么如果说运维是软件的地基,那么框架就是承重墙。起房子就是先打地基,再建承重墙。地基打得越稳,房子才能起得更高。也等同于运维技术越扎实,系统才能更加健壮。
特别在微服务兴起得时代,运维越发的现得尤为得重要,DevOps也风靡全球。只要聊起DevOps与微服务,CI/CD总是不能避免的。CI/CD不一定限制于微服务,我认为无论在什么样风格的架构和怎么样组织架构的团队,自动化技术越早使用收效越高。
我认为IT人员更多是脑力大于体力的劳动者,一些重复的、错误率高的、无法对自己有增长的工作应该尽早交给自动化技术处理,节省了不需要浪费的时间与精力,这样才能更好的去完成有价值、有意义的工作。
部署图
以上是我在虚拟机环境的部署图:
一共三台服务器,每台服务器都装了Docker,Server B是docker swarm的Manger角色,A和C是worker。
在Server B装了Jenkins、Docker Registry、dotnet sdk,Server A装了Gitlab,Server C装了私有Nuget。
那么工作流程是:
- 迁入代码push到Gitlab
- Gitlab触发webhook的push触发事件并主动通知Jenkins构建
- Jenkins在Gitlab获取源码并通过配置好的规则与shell脚本进行构建
- 如果是工具库则dotnet push到192.168.88.139:8081的私有Nuget
- 如果是Web应用则通过dockerfile构建docker镜像并push到192.168.88.141:6000的Docker Registry,然后由docker swarm create多节点
安装Docker
安装最新版本Docker,并在所有需要使用docker的服务器节点根据以下步骤安装
升级yum并安装基础组件
yum upgrade -y sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加安装源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker-ce
yum makecache fast
yum install docker-ce -y
vim /etc/docker/daemon.json {
"registry-mirrors" : [
"http://ovfftd6p.mirror.aliyuncs.com",
"http://registry.docker-cn.com",
"http://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"insecure-registries" : [
"registry.docker-cn.com",
"docker.mirrors.ustc.edu.cn"
],
"debug" : true,
"experimental" : true
}
启动docker
systemctl daemon-reload
systemctl enable docker
systemctl start docker
安装 Docker Registry(私有仓储)
选取一个服务器-Server B使用docker安装Registry
docker run -d -p : -v /root/docker_registry:/var/lib/registry --name private_registry registry
开放6000端口
firewall-cmd --permanent --add-port=/tcp
firewall-cmd --reload
以上就Registry安装完成了,但为了正常使用还需要做点配置修改
编辑所有需要docker registry使用的节点的daemon.json文件,确保能正常访问
vim /etc/docker/daemon.json {
"insecure-registries":["192.168.88.141:6000"]
}
重启docker
systemctl daemon-reload
service docker restart
如果需要推送镜像到私库确保标签(tag)前缀带有私库地址
docker push 192.168.88.141:/testdockerswarm
docker swarm的初始化
把相关涉及到docker swarm的节点端口开启
firewall-cmd --permanent --zone=public --add-port=/tcp
firewall-cmd --permanent --zone=public --add-port=/udp
firewall-cmd --permanent --zone=public --add-port=/udp
firewall-cmd --reload
选取Server B作为Manager节点,执行下面的指令后会出现docker swarm join的指令文本,复制保存下来
docker swarm init --advertise-addr 192.168.88.141
Server A和Server C为Worker节点,执行刚刚保存下来指令
docker swarm join --token SWMTKN--0odogegq3bwui4o76aq5v05doqqvuycb5jmuckjmvzy4bfmm59-ewht2cz6fo0r39ky44uv00aq5 192.168.88.141:
docker node ls
私有Nuget的安装
选择Server C基于docker的Nuget安装
docker run -d \
-p : \
--env NUGET_API_KEY=chengong \
-v /root/nuget/database:/var/www/db \
-v /root/nuget/packages:/var/www/packagefiles \
--name nuget-server \
sunside/simple-nuget-server
开放相关8081端口
firewall-cmd --permanent --add-port=/tcp
firewall-cmd --reload
上传包指令,注意包名有中文会导致上传出现bad request
dotnet nuget push --source http://192.168.88.139:8081/ -k chengong TestPackage.1.0.0.nupkg
删除包指令
dotnet nuget delete --source http://192.168.88.139:8081/ -k chengong TestPackage 1.0.0
如果在Windowsx系统可以通过工具上传
https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
Gitlab的安装
在Server A服务器上基于docker安装
sudo docker run -d \
--hostname 192.168.88.138 \
-p : -p : -p : \
--name gitlab \
--restart always \
-v /root/gitlab/config:/etc/gitlab:Z \
-v /root/gitlab/logs:/var/log/gitlab:Z \
-v /root/gitlab/data:/var/opt/gitlab:Z \
gitlab/gitlab-ce
开放端口
firewall-cmd --permanent --add-port=/tcp
firewall-cmd --reload
第一次启动会有点慢,需要耐心的等待一下(几分钟),初始化完了后进入系统设置root的密码,登录进去我们创建两个项目,一个Web应用,一个工具库,等会需要用到
Jenkins的安装
在Server B服务器基于docker安装Jenkins
mkdir -p /root/jenkins
setenforce
docker run --name jenkins -u -d --restart always -v /root/jenkins/jenkins_home:/var/jenkins_home -p : -p : jenkins/jenkins:lts
开放端口
firewall-cmd --permanent --add-port=/tcp
firewall-cmd --reload
启动完了后需要等待一会,我们先去查看Jenkins的docker log,我们找到下面那段密码,在Jenkins欢迎页输入,设置好管理员后,选择Custom Select,如果您对网络有自信就直接点继续,如果您对网络没自信,避免花了很长的时间还没安装好插件就直接啥都不选继续。(如果出现一个XXX失败代理的页面直接跳过)
docer logs xxx
Please use the following password to proceed to installation:
53d4a2880bf8460c8ff61936278855ca
插件自动下载完后了,终于进去了,如果有没有安装成功的都得保证以下三个插件安装好,Gitlab Hook 、Gitlab、Push Over SSH.
登录后,在左侧点击【系统管理】,拖下去点击 【插件管理】,确保Gitlab Hook 、Gitlab、Push Over SSH成功安装,如果无法顺利安装则到https://plugins.jenkins.io/下载插件手动上传。
docker exec -it /bin/bash
执行下面命令
tzselect cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ##查看时间
date -R
在Server B安装.Net SDK,因为在Server B安装了Jenkins,因此会基于Server B的环境进行.Net的应用进行打包、发布
添加下载源:
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
下载安装:
sudo yum install dotnet-sdk-3.1
dotnet nuget add source http://192.168.88.139:8081 -n LocalNugetServer
列出已有包源
dotnet nuget list source
当然可以通过 dotnet restore -s http://192.168.88.139:8081 指令指定还原包源,但是为了避免如果服务地址变动后shell脚本会大面积的修改,还是建议通过dotnet nuget add soure指令。
那么到这里所有的关于Linux的工具安装、初始化的准备工作都完成了,那么接下来就是讲解Jenkins结合Gitlab,把应用与工具包发布到Nuget与Docker。
Jenkins的使用
在一切开始之前得把SSH配置好,因为后续会使用到,在【SSH Servers】模块把服务器地址、账号密码填进去保存。
返回到首页面板点击【新建任务】-选择【构建一个自由风格的软件项目】(FreeStyle Project)。
自由风格的项目更多是使用shell脚本结合相应平台的指令实现自动化,因此建议大家对shell脚本有个初步的认识与学习,虽然Jenkins也提供了对应平台语言的一些插件,但是只要您熟悉了shell就会发现它的灵活性与便捷性。
接下来我们只要关注3个模块,源码管理、构建触发器、构建
源码构建,填写您要自动发布的项目的源码地址,并输入账号密码。
构建触发器,这里勾选Build when a chenge ……,把URL 复制记录下来,等下在Gitlab需要使用到。这里就是与Gitlab webhook做了联动,可以理解成Jenkins开放了一个接口,让Gitlab被push代码后会主动告诉Jenkins做一次自动化构建。
构建,这里其实就是执行shell脚本完成发布。这里得注意下我是用ssh,因为我的Jenkins是使用了docker安装的,如果我使用了【构建】模块里的【执行shell】就会在Jenkins环境里进行编译、打包,同时也需要安装相应的环境 例如dotnet sdk等。我的环境都是装在了Server B这个宿主环境,因此通过目录挂载与SSH完成了这一次构建。
当然有同学想在Jenkins环境先打包然后通过SSH的Transfers模块进行文件传也是可以的。
构建脚本
这个是工具库发布到私有Nuget的脚本
#脚本开始执行
echo '脚本开始执行' base_path=/root/jenkins/jenkins_home/workspace/TestNuget
nuget_url=http://192.168.88.139:8081/
nuget_api_key=chengong project_path=$base_path/TestNuget
package_path=$project_path/bin/Debug
cd $project_path rm -rf $package_path/*.nupkg dotnet pack $project_path &&
dotnet nuget push --source $nuget_url -k $nuget_api_key $package_path/*.nupkg >/dev/null if [ $? -eq 0 ]; then
echo '发布成功:'$project_path''
else
echo '发布失败:'$project_path''
fi echo '脚本执行结束'
下面这个是Web应用发布到单台服务器的脚本
#!/bin/bash
echo '脚本开始执行' base_path=/root/jenkins/jenkins_home/workspace/TestDockerSwarm project_name=testdockerswarm
project_path=$base_path/TestDockerSwarm
publish_path=$project_path/bin/Release/netcoreapp2./publish cd $project_path
rm -rf $project_path/bin dotnet publish -c Release && (
cd $publish_path &&
docker stop $project_name
docker rm $project_name
docker image rm $project_name
docker build -t $project_name . &&
docker run -d -p : -e ASPNETCORE_ENVIRONMENT="Development" --name $project_name $project_name &&
echo '发布成功:'$project_path'' ||
echo '发布失败:'$project_path''
) || echo '发布失败:'$project_path'' echo '脚本执行结束'
下面这个是通过Docker Swarm把Web应用发布到多台服务器
#!/bin/bash
echo '脚本开始执行' base_path=/root/jenkins/jenkins_home/workspace/TestDockerSwarm project_name=testdockerswarm
project_path=$base_path/TestDockerSwarm
publish_path=$project_path/bin/Release/netcoreapp2./publish
private_registry_url=192.168.88.141:
version=`date "+%Y%m%d%H%M%S"` cd $project_path
rm -rf $project_path/bin dotnet publish -c Release && (
(
cd $publish_path
docker service rm testdockerswarm
docker images | grep $private_registry_url/$project_name | awk '{print $3}' | xargs docker rmi
docker build -t $private_registry_url/$project_name:$version ./
docker push $private_registry_url/$project_name:$version
) &&
docker service create -d -p : --replicas -e ASPNETCORE_ENVIRONMENT="Development" --constraint=" node.role==worker" \
--name $project_name $private_registry_url/$project_name:$version &&
echo '发布成功:'$project_path'' ||
echo '发布失败:'$project_path''
) || echo '发布失败:'$project_path'' echo '脚本执行结束'
上面脚本有一处地址得注意下我指定了--constraint=" node.role==worker" 也就是woker节点才会部署应用,因为我定义了ServerA和C是Web服务器。当然各位可以按照自己的需要处理。
Dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE FROM base AS final
WORKDIR /app
COPY ./ /app
ENTRYPOINT ["dotnet", "TestDockerSwarm.dll"]
Gitlab的使用
进入Gitlab,点击【Admin Area】-【Network】,勾选选项后保存
进入一个Project,点击【Setting】-【Webhooks】,把刚刚在Jenkins的复制下来的Url填写进去,勾选相应的触发事件后保存。
结束
以上就是本篇的内容了,完成了部署后,可以在Jenkins点击【立刻构建】和在Gitlab迁入一次代码查看运行效果。Shell脚本作为一个demo,如果对脚本有更好的建议和优化的写法可以在评论区反馈给我。
.Net微服务实战之CI/CD的更多相关文章
- .Net微服务实战之Kubernetes的搭建与使用
系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术架构分层篇 .Net微服务实战之DevOps篇 .Net微服务实战之负载均衡(上) .Net微服务实战之CI/CD 前言 说到微服务就 ...
- .Net微服务实战之DevOps篇
技术只是基础 该系列的两篇文章<.Net微服务实战之技术选型篇>和<.Net微服务实战之技术架构分层篇>都是以技术角度出发描述微服务架构的实施. 如果技术选型篇叙述的是工具,那 ...
- 微软Azure AspNetCore微服务实战第2期
2018年1月28日,虽然上海的大雪在城区已经见不到踪影,但还是很冷.不过天气再冷,也阻止不了小伙伴参加活动的热情. 感谢王振,苏老师以及微软Azure API Management的产品经理Alvi ...
- 微软Azure AspNetCore微服务实战第1期【补充2017-09-09活动】
2017年09月09日,冒着酷暑,我们在(上海徐汇)虹桥路3号港汇中心2座10层组织了一次微软Azure AspNetCore微服务实战活动. 由于前期工作繁忙,活动完成之后,没能及时发布相关信息,特 ...
- SpringCloud微服务实战-Zuul-APIGateway(十)
本文转自:http://blog.csdn.net/qq_22841811/article/details/67637786#准备工作 1 API Gateway 2 Zuul介绍 2.1 zuul的 ...
- [高清·非影印]Spring实战+SpringBoot实战+Spring微服务实战+SpringCloud微服务实战(全4本)
------ 郑重声明 --------- 资源来自网络,纯粹共享交流, 如果喜欢,请您务必支持正版!! --------------------------------------------- 下 ...
- SpringCloud微服务实战三:Hystix的基本概念
1.说到隔离.熔断.降级,最出名的就是 Netflix 开源的 Hystrix 组件,Hystix官方对它描述为:Hystrix是一个延迟和容错库,旨在隔离远程系统.服务和第三方库,阻止级联故障,在复 ...
- SpringCloud微服务实战二:Spring Cloud Ribbon 负载均衡 + Spring Cloud Feign 声明式调用
1.Spring Cloud Ribbon的作用 Ribbon是Netflix开发的一个负载均衡组件,它在服务体系中起着重要作用,Pivotal将其整合成为Spring Cloud Ribbon,与其 ...
- Docker: Jenkins与Docker的自动化CI/CD流水线实战
什么是CI/CD 持续集成(Continuous Integration,CI):代码合并.构建.部署.测试都在一起,不断地执行这个过程,并对结果反馈.持续部署(Continuous Deployme ...
随机推荐
- onunload对应的js代码为什么不能执行?和onbeforeunload的区别?
为什么onunload对应的js代码不能执行? 为什么onbeforeunload才可以在离开页面时执行相应的js代码? 1.onunload和onbeforeunload都是在离开页面或者刷新页面的 ...
- 深入理解JVM(③)Java模块化系统
前言 JDK9引入的Java模块化系统(Java Platform Module System ,JPMS)是 对Java技术的一次重要升级,除了像之前JAR包哪有充当代码的容器之外,还包括: 依赖其 ...
- 112买卖股票的最佳时机II
from typing import List# 这道题和上一题很类似,但有一些不同,每天都可以买入,或者卖出# 那么利润最大化,就是i + 1 天的价格比i天的价格高的时候买入# 然后在i + 1天 ...
- CentOS 7安装Oracle 12c图文详解
环境: CentOS7@VMware12,分配资源:CPU:2颗,内存:4GB,硬盘空间:30GB Oracle 12C企业版64位 下载地址:http://www.oracle.com/techne ...
- React源码之组件的实现与首次渲染
react: v15.0.0 本文讲 组件如何编译 以及 ReactDOM.render 的渲染过程. babel 的编译 babel 将 React JSX 编译成 JavaScript. 在 ba ...
- Spring中AOP相关的API及源码解析
Spring中AOP相关的API及源码解析 本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 谈谈Spring ...
- 初探pandas——安装和了解pandas数据结构
安装pandas 通过python pip安装pandas pip install pandas pandas数据结构 pandas常用数据结构包括:Series和DataFrame Series S ...
- css3支持动画吗?css3可以用于网页动画的展现吗
CSS3 主要可以分为几个模块:边框和背景,渐变,文字特效,字体,2D/3D转换,动画(过渡动画和动画),选择器,盒模型,多列布局,用户界面. css3动画有2类:一种是transition的,另一种 ...
- 二、web自动化快速使用
1.启动浏览器 from selenium import webdriver # 启动谷歌浏览器,依赖:先安装好chromedriver.exe驱动 # 方式1.当chrome.driver放在p ...
- 03.springboot 整合RabbitMQ
1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...