(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

Jenkins+Docker 部署方案

开始新的方案前,先复习一下上面的内容建议用云处理器学习,重装什么都简单,按小时购买成本也不高.

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

什么是CICD 

CI / CD的采用改变了开发人员和测试人员如何发布软件。

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品的技术路线。随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery)、持续部署(Continuous Deployment)的新方法。传统的软件开发和交付方法正在迅速变得过时。从历史上看,在敏捷时代,大多数公司会每月,每季度,每两年甚至每年发布部署/发布软件。然而,现在,在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。很多时候,他们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。今天,我们将介绍什么是CI / CD / CD,以及现代软件公司如何使用工具将部署代码的流程自动化。持续集成的重点是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。持续交付的目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。持续部署是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署。这些阶段中的每一个都是交付管道的一部分 。在Humble和Farley的书《持续交付:可靠的软件版本中,通过构建,测试和部署自动化》,解释“对软件的每次更改,都会在发布过程中经历一个复杂的过程。该过程涉及构建软件,然后通过多个测试和部署阶段进行这些构建。反过来,这需要许多人之间的合作,也许需要几个团队之间的合作。部署管道对此过程进行建模,并且它在持续集成和发布管理工具中的实现,使您能够在从版本控制转移到各种测试和部署,以向用户发布时查看和控制每个更改的进度。”

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

软件交付流水线

持续集成(CI)
通过持续集成,开发人员能够频繁将其代码集成到公共代码仓库的主分支中。开开发人员能够在任何时候多次向仓库提交作品,而不是独立地开发每个功能模块并在开发周期结束时一一提交。这里的一个重要想法是让开发人员更快,更频繁地做到这一点,从而降低集成成本。实际情况中,开发人员在集成时经常会发现新代码和已有代码存在冲突。如果集成较早并更加频繁,那么冲突将更容易解决且执行成本更低。当然,还有一些权衡。此流程变更不提供任何额外的质量保证。实际上,许多组织发现这种集成变得更加昂贵,因为它们依赖于手动过程来确保新代码不会引入新的错误,并且不会破坏现有代码。为了减少集成任务期间的摩擦,持续集成依赖于测试套件和自动化测试执行。然而,要认识到自动化测试和持续测试是完全不同的这一点很重要,我们会在文章结尾处详细说明。CI 的目标是将集成简化成一个简单、易于重复的日常开发任务,这将有助于降低总体构建成本,并在周期的早期发现缺陷。要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建,并且在发现 bug 的早期积极解决。
持续交付(CD)
实际上是 CI 的扩展,其中软件交付流程进一步自动化,以便随时轻松地部署到生成环境中。CD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统,可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试,并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。AWS上提供了现代CI / CD管道的可靠展示。亚马逊是云计算提供商之一,提供令人印象深刻的CI / CD 管道环境,并提供一个演练过程,您可以从其中选择众多开发资源,并将它们链接在一个易于配置且易于监控的管道中。

许多人认为持续交付的吸引力主要在于,它自动化了从提交代码到仓库,再到测试和发布产品过程的所有步骤。这是构建和测试过程细致的自动化,但是如何发布以及发布什么仍然是需要人工操作,持续部署可以改变这一点。

持续部署(CD)
持续部署扩展了持续交付,以便软件构建,在通过所有测试时自动部署。在这样的流程中,不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。随着 DevOps 的发展,新的用来实现 CI/CD 流水线的自动化工具也在不断涌现。这些工具通常能与各种开发工具配合,包括像 GitHub 这样的代码仓库和 Jira 这样的 bug 跟踪工具。此外,随着 SaaS 这种交付方式变得更受欢迎,许多工具都可以在现代开发人员运行应用程序的云环境中运行,例如 GCP 和 AWS。最受欢迎的自动化工具是 Jenkins(以前的 Hudson),这是一个由数百名贡献者和商业公司 Cloudbees 支持的开源项目。Cloudbees 甚至聘请了 Jenkins 的创始人,并提供了一些 Jenkins 培训项目和附加组件。除了开源项目之外,还有一些更现代化的商业产品例如 CircleCI,Codeship 和 Shippable。这些产品各有优缺点,我鼓励开发人员在开发流程中一一尝试它们,以了解它们在您的环境中的工作方式,以及它们如何与您的工具、云平台、容器系统等协作。
什么Jenkins

Jenkins 是一个可扩展的持续集成引擎。

创建自己的Jenkins容器

DockerHub

Jenkins容器安装

构建流水线

构建自动发布

Docker部署Vue 前端工程Jenkins 持续集成(CI)工具创建Jenkins 容器

创建Dockerfile

FROM jenkins/jenkins
# 说明该镜像的制作者和联系方式MAINTAINER nine ninthmrj@vip.qq.com
# Switch to root to install .NET Core SDKUSER root
# Show distro information!RUN uname -a && cat /etc/*release
# Based on instructiions at https://www.microsoft.com/net/download/linux-package-manager/debian9/sdk-current# Install dependency for .NET Core 3.1/5/6RUN apt-get updateRUN apt-get install -y curl libunwind8 gettext apt-transport-https
# Based on instructions at https://www.microsoft.com/net/download/linux-package-manager/debian9/sdk-current# Install microsoft.qpgRUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpgRUN mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpgRUN sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/dotnetdev.list'
# Install the .NET Core framework Choose one Because I need several versions here, I installed three SDKsRUN apt-get updateRUN apt-get install -y dotnet-sdk-3.1RUN apt-get install -y dotnet-sdk-5.0 RUN apt-get install -y dotnet-sdk-6.0 
# Install the npm RUN apt-get install -y curl \&& curl -sL https://deb.nodesource.com/setup_14.x | bash - \&& apt-get install -y nodejs \&& curl -L https://www.npmjs.com/install.sh | sh
# Install cnpmRUN npm install cnpm -g
# Install yarnRUN npm install -g yarn
RUN npm -vRUN cnpm -vRUN yarn --version
# Switch back to the jenkins user.USER jenkins

构建镜像(build)

# 进入home目录(假设home目录为空)  $ cd /home# 创建一个dockerfile文件,用于创建自己的Jenkins容器  $ touch Dockerfile# 编辑文件,vi、vim熟练的或者linux数量的直接进行操作,# 本人不才,我用finalshell直接粘贴过去的,反正实现把上面的命令复制过去就行  $ vi Dockerfile # 在jenkinsdockerfile目录下进行,确认是否在此目录,enter 创建容器  # 不指定文件构建镜像,此时规定Dockerfile的名称一定是Dockerfile,其他名字无法构建容器,或者使用指定文件构建镜像  $ docker build -t jenkinsdockerfile .   # 指定文件构建镜像 -t 镜像名称 jamnine/jenkins  -f 指定文件生成镜像  $ docker build  -t jamnine/jenkins -f /home/JenkinsDockerfile .  ----------漫长等待.....大概十五分钟吧,以下这段为实例示例----------  [root@nine home]# docker build -t jenkinsdockerfile .  Sending build context to Docker daemon   16.9kB  Step 1/20 : FROM jenkins/jenkins  latest: Pulling from jenkins/jenkins  e4d61adff207: Pull complete   eacef06daf30: Pull complete   ca581b0141a3: Pull complete   d872c65909bb: Pull complete   bcce550e05a9: Pull complete   3461f061a833: Pull complete   3b6f8a58a68d: Pull complete   6d47f55855ba: Pull complete   baa80a92c8e4: Pull complete   39889d888af7: Pull complete   18b5e0e36b4c: Pull complete   a53e22d026ad: Pull complete   a281963da5b5: Pull complete   2366689c95a7: Pull complete   27cbe8a0f233: Pull complete   fffccee1c284: Pull complete   a6afec98241f: Pull complete   Digest: sha256:a5215b81a7f6e111ed6625b342521145e24c232891615be29ce3a251a631feac  Status: Downloaded newer image for jenkins/jenkins:latest   ---> f7d565ddb272  Step 2/20 : MAINTAINER nine ninthmrj@vip.qq.com   ---> [Warning] IPv4 forwarding is disabled. Networking will not work.   ---> Running in 47cecef5c92c  Removing intermediate container 47cecef5c92c   ---> 13dd258b38bc  Step 3/20 : USER root  ..........后续省略..........----------容器创建---结束------------------------------

创建容器

# 查看创建好的镜像$  docker images
-----------------------示例-----------------------------[root@nine]:# docker imagesREPOSITORY                                      TAG            IMAGE ID       CREATED         SIZEjamnine/jenkins                                 latest         20fd31570796   2 hours ago     1.93GBjamnine/jenkins                                 net-6.0        7bc780e637ba   3 hours ago     1.23GBjamnine/jenkins                                 net-5.0        2111cd8eef2b   4 hours ago     1.13GBjamnine/jenkins                                 net-core-3.1   1281c5c8b81c   5 hours ago     1.08GBjenkins/jenkins                                 latest         f7d565ddb272   7 days ago      460MBlaozhangisphi/jenkins_with_dnt-cnpm_by_docker   latest         1cd6e938cd08   16 months ago   1.72GB-----------------------示例-----------------------------
# 如果你是第一次使用build,当然只有一个容器,这里我是有6个容器  jamnine/jenkins      # 镜像名字,docker 上传(docker仓库)规范 jamnine/jenkins  前面为作者名/镜像名  latest               # 镜像标签,一个镜像可以有多个不同标签,相当于一个版本  20fd31570796         # 镜像的缩略ID(ID唯一,但是缩略ID可能会重复,确定唯一性可以使用镜像名称:标签)  2 hours ago         # 创建于两小时前  1.93GB              # 大小1.93GB
# 创建你的第一个容器  $  docker run -u root -it  -d -p 8099:8080 --name jenkinsnine \  -e TZ=Asia/Shanghai \  -v /etc/localtime:/etc/localtime \  -v /usr/bin/docker:/usr/bin/docker \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /home/jenkinsnine/jenkins_home:/var/jenkins_home \  jamnine/jenkins# 注解------------------------------------------------------------------------------------------------------------------  --rm                            命令选项,等价于在容器退出后,执行 $ docker rm -v  ,测试可写,生产环境记住去掉  -p 3000:8080                    端口映射 容器端口3000映射到宿主机8080  --name jenkins                  容器名称    -v /etc/localtime:/etc/localtime 挂载在宿主机,后面为具体挂载路径 冒号":"前面的目录是宿主机目录,后面的目录是容器内目录                                   路径不能为相对路径,需要以/开头                                    laozhangisphi/jenkins_with_dnt-cnpm_by_docker  最后一句代表了镜像名称,这里没有多个tag,直接写镜像名称即可,latest可省略,                                  如果是要创建jamnine/jenkin 的容器,不写tag则创建latest镜像的容器,否则改写tag,如6.0则是 jamnine/jenkin:net-6.0                                    -i                                以交互模式运行容器,通常与 -t 同时使用;-t                                为容器重新分配一个伪输入终端,通常与 -i 同时使用;-d                                后台运行容器,并返回容器ID;-e TZ=Asia/Shanghai               解决Jenkins时区问题# 注解------------------------------------------------------------------------------------------------------------------
# 查看容器  $  docker ps  $  docker ps -a    -a                             显示所有容器,不带-a显示正在运行的容器      docker exec jenkinsnine cat /var/jenkins_home/secrets/initialAdminPassword[root@nine ~]# docker exec jenkinsnine cat /var/jenkins_home/secrets/initialAdminPassword619506eb3e0546e68c20bc2f52de3d35
    
# 补充下复制的知识  从容器复制到宿主机:docker cp 容器名字/ID:容器路径 宿主机本地路径  从宿主机复制到容器:docker cp 宿主机本地路径 容器名字/ID:容器路径  # 那我们把容器删除,挂载的还会存在吗?  答案存在的;这也是为什么要挂载的原因;但尽可能重要的数据库还是不要用docker启动   不要将数据储存在容器中,这也是 Docker 官方容器使用技巧中的一条。容器随时可以停止、或者删除。当容器被rm掉,   容器里的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。但是容器的 Volumes 设计是围绕 Union FS 镜像层提供持久存储,   数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。    # 这里的时区有点问题,具体可以在Jenkins里面执行  $  System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')

测试容器

[root@localhost ~]# docker ps -aCONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES[root@localhost ~]# docker run -u root -it  -d -p 8099:8080 --name jenkinsnine \> -v /etc/localtime:/etc/localtime \> -v /usr/bin/docker:/usr/bin/docker \> -v /var/run/docker.sock:/var/run/docker.sock \> -v /home/jenkinsnine/jenkins_home:/var/jenkins_home \> jamnine/jenkinsWARNING: IPv4 forwarding is disabled. Networking will not work.c5d0fd961901b673ceb7beb9766836ce938ce43fd6641de0b7a5ebca7d0aeb1adocker: Error response from daemon: driver failed programming external connectivity on endpoint jenkinsnine (81aaf37c44e24f28201ebf45cd6a6b6dd5bd78ea89506a9da6ba1bc828e81cf6):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8099 -j DNAT --to-destination 172.17.0.2:8080 ! -i docker0: iptables: No chain/target/match by that name. (exit status 1)).

推送镜像到DockerHub
推送Jenkins 容器到DockrHub

docker tag 用于给镜像打标签,语法如下:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
① 比如我现在有一个 centos 镜像:
[root@localhost ~]$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE centos              latest              1e1148e4cc2c2 weeks ago         202MB
② 我对 centos 进行开发,开发了第一个版本,我就可以对这个版本打标签,打完标签后会生成新的镜像:
[root@localhost ~]$ docker tag centos centos:v1
[root@localhost ~]$ docker images REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE centos              latest              1e1148e4cc2c2weeks ago         202MB centos              v1                  1e1148e4cc2c2 weeks ago         202MB
③ 我继续对 centos 进行开发,开发了第二个版本,继续打标签:
[root@localhost ~]$ docker tag centos centos:v2
[root@localhost ~]$ docker images REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE centos              latest              1e1148e4cc2c2weeks ago         202MB centos              v1                  1e1148e4cc2c2weeks ago         202MB centos              v2                  1e1148e4cc2c2 weeks ago         202MB
④ 以此类推,每开发一个版本打一个标签,如果以后我想回滚版本,就可以使用指定标签的镜像来创建容器:
[root@localhost ~]$ docker run -itd centos:v1
Jenkins DockrHub变更记录
变更记录
记录每次修订的内容,方便追溯。
最近更新时间:2022-03-22
2022-03
增加Net 6.0 SDK编译Web API项目
其他组件常规升级
根据SDK不同划分几个标签

版本号

标签

作者

不同组件

发布日期

1.2.0

latest

Jamnine(何拾玖)

Core SKD 3.1/5/6

2022-03-23

1.2.0

v1.2.0-net-3.1-5-6

Jamnine(何拾玖)

Core SKD 3.1/5/6

2022-03-23

1.2.0

v1.2.0-net-6.0

Jamnine(何拾玖)

Core SKD 6

2022-03-23

1.2.0

v1.2.0-net-5.0

Jamnine(何拾玖)

Core SKD 5

2022-03-23

1.2.0

v1.2.0-net-core-3

Jamnine(何拾玖)

Core SKD 3.1

2022-03-22

●注:latest等同 tag:v1.2.0-net-3.1-5-6
●共同组件

1.2.0共同组件

Jenkins 2.339|Core SKD 3.1/5/6|NodeJs 14.19.1|Git 2.30.2
npm 8.5.5|cnpm 7.1.1|yarn 1.22.18|linux x64 3.10.0-957.21.3.el7.x86_64

2021-05
增加yarn编译前端项目使用
添加Git拉取代码
增加Net 5.0 SDK编译Web API项目
其他组件常规升级

版本号

标签

作者

不同组件

发布日期

1.1.0

v1.1.0-

Jamnine(何

Core SKD 3.1/5

05-05

1.1

v1.1.0-

Jamnine(何

Core SKD 5

2021-5

1.1

v1.1.0-

Jamnine(何

Core SKD 3.1

202105

●共同组件

1.1共同组件

Jenkins 2.257|Core SKD 3.1/5|NodeJs 14.16.1|Git 2.11.0
npm 7.11.1|cnpm 6.2.0|yarn 1.22.10|linux x64 3.10.0-1127.19.1.el7.x86_64

2020-11
制作第一个容器
包含Jenkins 2.266Core SKD 3.1NodeJs 14.15.0Git 2.11.0
npm 6.14.8cnpm 6.1.1linux linux x64 3.10.0-957.21.3.el7.x86_64
CICD初体验,编译Web API Core版本,Vue 2.x 项目

版本号

标签

作者

不同组件

发布日期

1.0.0

v1.0.0-net-core-

Jamnine(何拾玖)

Core SKD 3.1

2020-11

●共同组件

1.0.0共同组件

Jenkins 2.266|Core SKD 3.1|NodeJs 14.15.0|Git 2.11.0
npm 6.14.8|cnpm 6.1.1|yarn 1.22.10|linux x64 3.10.0-957.21.3.el7.x86_64

使用Docker安装Jenkins
Jenkin基本使用
docker中jenkins修改时区
1root身份进入jenkins容器docker exec -it -u root my_jenkins /bin/bash
2修改容器内系统时区。此时可以date查看系统时间已经修改过来,但是jenkins内部时间没有改变。cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3既然docker容器的时间正确了,但是jenkins的时间还是不对的,说明jenkins的时区使用的不是/etc/localtime,而是另有他处。在jenkins-》系统管理-》系统信息中可以看到有关时区的是user.timezone属性值是Etc/UTC。哪里存放的这个值呢,应该是/etc/timezone了。所以尝试下/etc/timezone的设置。echo Asia/Shanghai > /etc/timezone
4重启jenkins,观察右下角时间已经正确。http://localhost:8080/restart

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

Jenkins 创建 Core 项目自动集成

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结

(4/4) .NET Core Web API + Vue By Linux and Windows 部署方案知识点总结