🧊 Jenkins+Docker 部署方案 🧊
开始新的方案前,先复习一下上面的内容建议用云处理器学习,重装什么都简单,按小时购买成本也不高
CI / CD的采用改变了开发人员和测试人员如何发布软件。
最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品的技术路线。随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery)、持续部署(Continuous Deployment)的新方法。传统的软件开发和交付方法正在迅速变得过时。从历史上看,在敏捷时代,大多数公司会每月,每季度,每两年甚至每年发布部署/发布软件。然而,现在,在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。很多时候,他们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。今天,我们将介绍什么是CI / CD / CD,以及现代软件公司如何使用工具将部署代码的流程自动化。持续集成的重点是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。持续交付的目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。持续部署是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署。这些阶段中的每一个都是交付管道的一部分 。在Humble和Farley的书《持续交付:可靠的软件版本中,通过构建,测试和部署自动化》,解释“对软件的每次更改,都会在发布过程中经历一个复杂的过程。该过程涉及构建软件,然后通过多个测试和部署阶段进行这些构建。反过来,这需要许多人之间的合作,也许需要几个团队之间的合作。部署管道对此过程进行建模,并且它在持续集成和发布管理工具中的实现,使您能够在从版本控制转移到各种测试和部署,以向用户发布时查看和控制每个更改的进度。”
软件交付流水线
持续集成(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 SDK
USER 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/6
RUN apt-get update
RUN 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.qpg
RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
RUN mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
RUN 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 SDKs
RUN apt-get update
RUN apt-get install -y dotnet-sdk-3.1
RUN 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 cnpm
RUN npm install cnpm -g
# Install yarn
RUN npm install -g yarn
RUN npm -v
RUN cnpm -v
RUN 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 images
REPOSITORY TAG IMAGE ID CREATED SIZE
jamnine/jenkins latest 20fd31570796 2 hours ago 1.93GB
jamnine/jenkins net-6.0 7bc780e637ba 3 hours ago 1.23GB
jamnine/jenkins net-5.0 2111cd8eef2b 4 hours ago 1.13GB
jamnine/jenkins net-core-3.1 1281c5c8b81c 5 hours ago 1.08GB
jenkins/jenkins latest f7d565ddb272 7 days ago 460MB
laozhangisphi/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/initialAdminPassword
619506eb3e0546e68c20bc2f52de3d35
# 补充下复制的知识
从容器复制到宿主机: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 -a
CONTAINER 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/jenkins
WARNING: IPv4 forwarding is disabled. Networking will not work.
c5d0fd961901b673ceb7beb9766836ce938ce43fd6641de0b7a5ebca7d0aeb1a
docker: 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:v1Jenkins 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.2npm 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.0npm 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.0npm 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
定
Jenkins 创建 Core 项目自动集成
本文分享自 NetCore 从壹开始 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!