代码改变世界

docker+aspnetcore+gogs+jenkins 持续部署

2020-07-19 17:25  糯米粥  阅读(630)  评论(5编辑  收藏  举报

jenkins 是很好的一个CI/CD工具

我们现在用jenkins做个CD 玩玩,毕竟在开发阶段,需要频繁的提交。发布,这样繁琐的工作,

如果由人工操作,会很累

 

安装就不讲了。看看我前面的文章

  docker 安装:https://www.cnblogs.com/nsky/p/10372287.html

  jenkins安装:https://www.cnblogs.com/nsky/p/13339473.html

  gogs安装:https://www.cnblogs.com/nsky/p/13339343.html

 

首先我说下我遇到的坑,刚开始我是在阿里云服务器跑着玩的,环境都搭建好后,

我一构建开始,jenkins容器就挂了,查看logs也没有exit原因,

刚开始以为是权限的问题,后来又以为是镜像的原因,我用了jenkins镜像自己打包

又用了jenkinszh/jenkins-zh,用了jenkins/jinkins,jenkinsci/blueocean 等没错都是一构建就挂

后来才发现是配置低了。我的配置是1核1G的。本来就是买来玩玩的。配置低,所以价格才便宜

我之所以不在本地玩,是想更趋向于实战,

不过我还有一台搬*工的是2H1G的。

 

既然有2台电脑。所以,就完成2个目标

1:本地构建(jenkins和gogs都在同一台服务器)

2:远程触发构建(jenkins和gogs不在同一台服务器)

 

那么阿里云服务器叫A,搬*工服务器叫B

服务器名称  IP 安装软件
阿里云服务器(A) 39.105.144.51 gogs
搬*工(B) 104.128.92.44 jenkins,gogs

 

 

本地构建(jenkins和gogs都在同一台服务器)

这里是操作服务器B

机制:

就是当用户提交代码到gogs上,gogs通知jenkins,构造部署。所以这里用到了web钩子:webhook

其实jenkins 是把git代码拉取到了本地,下面可以演示出来

 

1:创建一个core程序,上传到gogs上

 

 

 

core 项目的Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
ENV TZ Asia/Shanghai

#EXPOSE 443 FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build WORKDIR /src COPY . . RUN dotnet restore RUN dotnet build FROM build AS publish RUN dotnet publish "mytest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app # 从发布阶段的中拷贝编译结果到当前镜像中 COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "mytest.dll"]

 

 

 

2:jenkins 安装gogs插件

在系统管理=》插件管理=》可选插件=》搜索gogs

 

 

 

安装后,开始配置,新建任务

 

 

 

 

几个重点配置

 

 

 

Repository URL :填写你的仓库地址

Credentials:选择你的凭据

如果你没有添加全局凭据,这里下拉是没有值的

1:可以在用户凭据中添加

2:可以直接单击这个添加,跳转到添加凭据界面

 

 

 输入用户名密码。就是我们工作中拉取git的用户名和密码,其他的不填写,单击添加后,选择刚添加的

 

 

 提示成功了

 

 

 

这里指定分支,我这是测试。默认就是master

 

 

 

 

连接上了gogs。那么就是构建部署了。构建肯定要执行命令是吧。那么这里就要添加构建部署的命令

 

 

 

 输入命令:这命令我有参考网络修改,有很多提示的文字,自己修改,这不是重点

echo "获取当前容器是否存在-----------------------------------------------------------------"
containerps=$(docker ps -f name=mymvc -q)
containerstop=$(docker ps -a -f name=mymvc -q)
for alpha in "$containerps";do
    if [ "$alpha" = "" ];then
    echo "检查是否存在停止的容器-------------------------------------------------"
        for alpha1 in "$containerstop";do
          if [ "$alpha1" = "" ];then
          echo "不存指定容器-----------------------------------"
          else
          echo "存在停止了的 然后直接删除-----------开始------------------"
          docker rm $alpha1
          echo "存在停止了的 然后直接删除-----------完成------------------"
        fi
       done
    else
    echo "存在-停止运行 然后删除----------------------开始-----------------"
    docker stop $alpha
    docker rm $alpha
     echo "存在-停止运行 然后删除---------------------完成------------------"
    fi
done



echo "获取当前镜像是否存在-----------------------------------------------------------------"
dockerlist=$(docker images mvcimage:latest -q)
for alpha2 in "$dockerlist";do
  if [ "$alpha2" = "" ];then
     echo "不存在指定镜像-------------------------------------------------" 
  else
       echo "存在当前指定的镜像 删除镜像--------------开始-----------------------------------"
      docker rmi $alpha2
     echo "存在当前指定的镜像 删除镜像--------------完成-----------------------------------"
  fi
done
echo "开始输入工作目录-----------------------------------------------------------------"
echo $WORKSPACE
echo "转到项目工程目录-----------------------------------------------------------------"
cd $WORKSPACE/myproject
echo "构建Docker镜像-------------------------------开始----------------------------------"
docker build -t mvcimage .
echo "构建Docker镜像-------------------------------完成----------------------------------"
echo "运行Docker容器-------------------------------------开始----------------------------"
docker run  --name=mymvc -p 8802:80 -d mvcimage

 

我们在build镜像的过程中,可能会产生一些临时的不具有名称也没有作用的镜像他们的名称一般都是<none>,我们可以执行下面的命令将其清除掉:

所以在脚本最后加条命令

docker rmi $(docker images -f "dangling=true" -q)

 

noneImage = docker rmi $(docker images -f "dangling=true" -q)

if [ ! -n  "$noneImage"]; then

else 

docker rmi $(docker images -f "dangling=true" -q
fi

精简版本
docker stop Web
docker rm Web
echo $WORKSPACE
cd $WORKSPACE/project
docker build -t myimages .
docker run  --name=Web -p 8802:80 -d myimages
docker rmi $(docker images -f "dangling=true" -q)

 

 

 

 

 

 然后单击保存即可

jenkins是把git上的代码拉取到了workspace文件夹下。

所以你会看到命令中有cd  $WORKSPACE

 

 

 

 

可以看看文件具体位置。在jenkins_home/workspace下有拉取的项目

 

 

 /docker/jenkins_home/workspace 这个目录,是你挂载的目录

 

 

 进去就可以看到。里面有源代码,

 

 

 

如果想测试,看是否配置正确。可以单击立即构建,我这里就不演示了

 

 

 

 

 

jenkins配置完成了。然后去gogs配置

 

 

 

 

 

 

 

 

 

 

 

然后配置如下:推送地址中的参数,job=myproject,是必须跟我们在jenkins创建任务的名称匹配才行

推送事件,根据自己的需求来。然后单击添加

http://104.128.92.44:8080/gogs-webhook/?job=myproject

 

 

 

 

 

 

 

 

上面那个,是我之前测试的。可以忽略,然后单击进去,可以测试推送下

 

 

 测试成功

 

 

 

回到jenkins面板,看看构建记录

 

 

 

进去,看控制台输出

 

 

 看容器也已经启动,端口是8802,尝试访问一下

 

 

访问成功:

 

 

 

 

 

好了。接下来,打开项目,修改下文件,提交

 

 

 

 

 

 

 

至此,这样在本地构建部署就完成了,

 

 

远程触发构建(jenkins和gogs不在同一台服务器)

说明:

 阿里云服务器(A)上安装了gogs

搬*工服务器上(B)上安装了jenkins

 

当有人提交代码给gogs,就会触发jenkins

所以:

远程触发原理就是:

 A触发B。告诉B。有人提交代码,你需要触发A构建代码,

B会把本地的一个命令文件上传到A,然后在A上执行这个命令,完成部署

那么要保证A上的代码必须是最新的,所以在A上必定需要git操作,

当然,B不一定要上传文件到A。可以直接触发A上某个脚本,下面会提到

 

现在阿里云服务器上的gogs是没有任何仓库的

 

把上面测试的项目添加到gogs上

 

 

 

 

在A上安装git

yum install  -y git

1.配置一个用于提交代码的用户,输入命令:

git config --global user.name "Your Name"

2.配置一个用户邮箱,输入命令:

git config --global user.email "email@example.com"

3.生成公钥和私钥,输入命令后一路回车即可

ssh-keygen -t rsa -C "youremail@example.com"

公钥路径,待会会用到

 

 

 

进入gogs,仓库设置=》管理部署密钥

 

 

 

 

把密码添加进去保存

 

 

 

在服务器A指定一个目录,拉取代码

 

 

 

一段小插曲,如果clone的时候出现

 

 

 用OpenSSH的人都知ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当

下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告,

如果我们重新安装系统,其公钥信息还在,连接会出现如上截图情况

网络收集:

方法一:

rm -rf ~/.ssh/known_hosts

++++++++++++++++++

优点:干净利索

缺点:把其他正确的公钥信息也删除,下次链接要全部重新经过认证

 

方法二:

vi ~/.ssh/known_hosts

删除对应ip的相关rsa信息(本例可知删除53行信息即可)

++++++++++++++++++

优点:其他正确的公钥信息保留

缺点:还要vi,还要找到对应信息,稍微优点繁琐

 

方法三:

清除旧的公钥信息

ssh-keygen -R 192.168.0.100

++++++++++++++++++

优点:快、稳、狠

缺点:没有缺点

 

这样的git算是弄好了。然后去jenkins上配置任务。

远程触发,需要安装插件:Publish Over SSH

 

 

 

安装后。进入系统配置

 

 

这里要配置被连接电脑的用户名和密码,

现在是B连接A。所以这里配置A服务器的地址

 

 Passphrase:登录电脑的密码

SSH Servers:服务器的配置

  Name:名称(自定义)

  Hostname:服务器地址

  Username:用户名

  Remote Directory:默认远程服务器的地址

 

 

 

 

这里单独创建个任务叫:remote

既然是远程触发,源代码这里就不用设置了

 

 

 

 

 

 

 

 

 

 

 

Transfers:

  Source files:源文件地址,地址的目录是相对于jenkins workspace的目录,如果只需要执行命令不需要传输文件的时候,此处可以为空

     我这里是上传文件,a.sh,那么在workspace会有个对应的任务名称的文件夹 remote

     所以全路径是:jenkins_home/workspace/remote/a.sh

 

  Remove prefix:去除的文件地址。在Source files输入框中填入的地址,会默认在服务器下创建相同的文件夹,所以需要将我们不需要的文件夹在这里剔除掉

   比如:

    Source files 填写的是 u/a.sh,Remove prefix 为空,那么就会在是这样 /root/u/a.sh

如果Remove prefix 填写u 就是剔除u文件夹,那么在A服务器上就是 /root/a.sh

 

  Remote directory:远程服务器接收文件的地址,这里配置的 就是在 根目录 下

  Exec command:文件传输任务执行完毕后,在远程服务器上执行的命令,要执行的命令,

文件在根目录下,那么全路径就是 /root/a.sh

 

a.sh输入脚本,其实就2句重点

/root/project/mytest/mytest:是我服务器拉取git的路径

sh publish.sh 是执行脚本

那么publish.sh放什么脚本命令呢?

就是上面测试过的打包命令

 

 那么在/root/project/mytest/mytest 中创建一个publish.sh

 

 几个重点,先切目录,git下

然后在切到Dockerfile 目录下。如果不想切。那么得改打包的命令,指定Dockerfile目录

docker build  -f  /root/project/mytest/mytest/Dockerfile  -t mvcimage /root/project/mytest/mytest

最后别忘了在A服务上gogs配置weghook

http://104.128.92.44:8080/gogs-webhook/?job=remote

然后自己测试,我就不演示了

 

当然。你这里的jenkins远程触发,也可以直接执行服务器A上的脚本,不一定要上传一个脚本

总得来说,就研究和尝试了这么多,

哎,写博客太费时了。以后要少写。。。。。