JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

通过CI/CD实现自动化部署web,小项目也可以玩的高大上

wys521 2024-10-19 10:12:42 精选教程 19 ℃ 0 评论

即使是最小的侧项目也值得它的CI/CD管道

前言

使用当今的工具,建立一个简单的CI/CD管道并不困难。即使是做一个小项目,这样做也是学习很多东西的好方法。Docker、GitLab和Portainer是用于此设置的一些很棒的组件。

一个Demo小项目

这里我们以https://sophia.events/为案例,我们保证页面的event为最新的。页面的events在这里[1]

免责声明:这是一个简单的项目,但是项目的复杂性在这里并不重要。我们将详细介绍的CI/CD管道的组件可以以几乎相同的方式用于更复杂的项目。不过,它们非常适合微服务。

废话不说,直接上代码

{
"events": [
{
"title": "All Day DevOps 2018",
"desc": "We're back with 100, 30-minute practitioner-led sessions and live Q&A on Slack. Our 5 tracks include CI/CD, Cloud-Native Infrastructure, DevSecOps, Cultural Transformations, and Site Reliability Engineering. 24 hours. 112 speakers. Free online.",
"date": "17 octobre 2018, online event",
"ts": "20181017T000000",
"link": "https://www.alldaydevops.com/",
"sponsors": [{"name": "all-day-devops"}]
},
{
"title": "Création d'une Blockchain d'entreprise (lab) & introduction aux smart contracts",
"desc": "Venez avec votre laptop ! Nous vous proposons de nous rejoindre pour réaliser la création d'un premier prototype d'une Blockchain d'entreprise (Lab) et avoir une introduction aux smart contracts.",
"ts": "20181004T181500",
"date": "4 octobre à 18h15 au CEEI",
"link": "https://www.meetup.com/fr-FR/IBM-Cloud-Cote-d-Azur-Meetup/events/254472667/",
"sponsors": [{"name": "ibm"}]
},
…
]
}

将mustache[2]模板应用于此文件,以生成最终的web页面。

基于Docker的多层构建

生成web 页面之后,将它们复制到nginx image中——部署在目标机器上的image。

然后构建完成了两个部分,由于多阶段构建:

· 资产的生成

· 创建包含资产的最终映像

这是Dockerfile用于构建:

# Generate the assets
FROM node:8.12.0-alpine AS build
COPY . /build
WORKDIR /build
RUN npm i
RUN node clean.js
RUN ./node_modules/mustache/bin/mustache events.json index.mustache > index.html# Build the final image used to serve 
them 
FROM nginx:1.14.0
COPY --from=build /build/*.html /usr/share/nginx/html/
COPY events.json /usr/share/nginx/html/
COPY css /usr/share/nginx/html/css
COPY js /usr/share/nginx/html/js
COPY img /usr/share/nginx/html/img

本地测试

测试目的:只需要clone repo 然后在运行test.sh。test.sh 会创建一个image然后运行。

$ git clone :lucj/sophia.events.git$ cd 
sophia.events$ ./test.sh
Sending build context to Docker daemon 2.588MB
Step 1/12 : FROM node:8.12.0-alpine AS build 
---> df48b68da02a
Step 2/12 : COPY . /build 
---> f4005274aadf
Step 3/12 : WORKDIR /build 
---> Running in 5222c3b6cf12Removing intermediate container 5222c3b6cf12 
---> 81947306e4af
Step 4/12 : RUN npm i 
---> Running in de4e6182036bnpm notice created a lockfile as package-lock.json. You should commit this file.npm WARN www@1.0.0 No repository field.added 2 packages from 3 contributors and audited 2 packages in 1.675sfound 0 vulnerabilitiesRemoving intermediate container de4e6182036b ---> d0eb4627e01f
Step 5/12 : RUN node clean.js 
---> Running in f4d3c4745901Removing intermediate container f4d3c4745901 
---> 602987ce7162
Step 6/12 : RUN ./node_modules/mustache/bin/mustache events.json index.mustache > index.html 
---> Running in 05b5ebd73b89Removing intermediate container 05b5ebd73b89 
---> d982ff9cc61c
Step 7/12 : FROM nginx:1.14.0 
---> 86898218889a
Step 8/12 : COPY --from=build /build/*.html /usr/share/nginx/html/ 
---> Using cache 
---> e0c25127223f
Step 9/12 : COPY events.json /usr/share/nginx/html/ 
---> Using cache 
---> 64e8a1c5e79d
Step 10/12 : COPY css /usr/share/nginx/html/css 
---> Using cache 
---> e524c31b64c2
Step 11/12 : COPY js /usr/share/nginx/html/js 
---> Using cache 
---> 1ef9dece9bb4
Step 12/12 : COPY img /usr/share/nginx/html/img 
---> e50bf7836d2fSuccessfully built e50bf7836d2fSuccessfully tagged registry.gitlab.com/lucj/sophia.events:latest
=> web site available on http://localhost:32768

在输出的信息下面有一个网址 http://localhost:32768

我们打开网址:

环境

在swarm中运行docker

在这里我们用swarm来管理docker。而不是用K8s,swarm稍微简单些, 也便于大家通过这篇文章来自己实现CI/CD。

让应用程序运行在docker中

docker compose 如下

version: "3.7"
services: 
 www: 
 image: registry.gitlab.com/lucj/sophia.events 
 networks: 
 - proxy 
 deploy: 
 mode: replicated 
 replicas: 2 
 update_config: 
 parallelism: 1 
 delay: 10s 
 restart_policy: 
 condition: on-failurenetworks: 
 proxy: 
 external: true

简单说明:

· image被放在了gitlab.com私有仓库中

· 服务处于具有两个副本的复制模式,这意味着服务的两个任务/容器同时运行。VIP(虚拟IP地址)通过集群与服务相关联,因此每个针对服务的请求都在两个副本之间实现负载平衡。

· 每次更新服务(部署web站点的新版本)时,更新一个副本,10秒后更新第二个副本。这确保在更新过程中web站点仍然可用。我们也可以使用回滚策略,但是现在还不需要。

· 该服务附加到外部代理网络,因此TLS终端(运行于部署在集群上的另一个服务中,但不在此项目中)可以向www服务发送请求。

我们通过如下命令运行docker服务:

docker stack deploy -c sophia.yml sophia_events

Docker管理平台portainer.io

Portainer平台有一个很棒的web UI界面,它允许用户非常容易地管理Docker主机和Docker集群。下面是Portainer界面的截图,它列出了集群中可用的应用。

我们看到有三个实例

· portainer自己

· Sophia_events

· TLS

下面列出位于Sophia_events中的www服务的详细信息,我们可以看到服务webhook已被激活。自从Portainer 1.19.2(到目前为止的最后一个版本)以来,这个特性就可用了,它允许我们定义一个HTTP Post端点,可以调用它来触发服务的更新。稍后我们将看到,GitLab运行器负责调用这个webhook。

注意:从屏幕截图中可以看到,我从localhost:8888访问Portainer UI。由于我不想将Portainer实例暴露给外部世界,所以通过ssh隧道进行访问,使用以下命令打开ssh隧道:

ssh -i ~/.docker/machine/machines/labs/id_rsa -NL 8888:localhost:9000 $USER@$HOST

然后,所有针对端口8888上的本地机器的请求都通过ssh发送到虚拟机上的端口9000。9000是Portainer在VM上运行的端口,但是这个端口不对外开放,所以是相对安全的。

注意:在上面的命令中,用于连接VM的ssh密钥是Docker机器在创建VM期间生成的密钥。

Gitlab runner

GitLab runner 是一个负责执行. GitLab –ci.yml 文件的驱动 ,当代码被push到主分支的时候,会自动执行预先写好的脚本,从而实现自动化。对于这个项目,我们将自己的GitLab runner定义为VM上的docker服务。

下面是配置脚本:

docker run — rm -t -i \
-v $CONFIG_FOLDER:/etc/gitlab-runner \
gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
--docker-image docker:stable \
--url "" \
--registration-token "$PROJECT_TOKEN" \
--description "Exoscale Docker Runner" \
--tag-list "docker" \
--run-untagged \
--locked="false" \
--docker-privileged

可以使用PROJECT_TOKEN在gitlab上注册额外的runners

注册后,我们直接start

CONFIG_FOLDER=/tmp/gitlab-runner-configdocker run -d \ 
--name gitlab-runner \ 
--restart always \ 
-v $CONFIG_FOLDER:/etc/gitlab-runner \ 
-v /var/run/docker.sock:/var/run/docker.sock \ 
gitlab/gitlab-runner:latest

一旦start成功,我们就会在gitlab上看到项目的信息:

当研发把代码提交到gitlab上,runners会一次执行:测试、构建、部署等在.gitlab-ci.yml里面定义好的操作。

· 测试阶段运行一些预检查以确保events. json文件格式正确并且images完整 。

· 构建阶段构建image并将其推送到GitLab registry 。

· deploy阶段通过发送到Portainer的webhook触发服务的更新。WWW_WEBHOOK变量在GitLab.com项目页面的CI/CD设置中定义。

注:

这个runners在swarm的容器中运行。我们可以使用一个共享的runner——他们可以在托管的主机上共享资源——但是,runner需要访问Portainer endpoint (发送webhook),因为我不希望Portainer被玩不访问。

此外,因为运行器在容器中运行,所以它将webhook发送到Docker0桥接网络的IP地址,以便通过它在主机上公开的端口9000与Portainer联系。因此,webhook的格式如下:http://172.17.0.1:9000/api[…]a7-4af2-a95b-b748d92f1b3b

部署过程回顾

网站新版本的更新工作流程如下:

1. 开发人员将一些更改推给GitLab。这些更改基本上涉及事件中的一个或多个新事件。json文件加上一些额外的赞助商的标志。

2. GitLab运行器执行. GitLab -ci.yml中定义的操作。

3. GitLab运行器调用Portainer中定义的webhook。

4. 在webhook接收端,Portainer部署了www服务的新版本。它这样做,调用Docker Swarm API。Portainer可以作为套接字/var/run/ dockerr访问API。袜子启动时是绑定安装的

5. 然后用户就可以在web上看到最新的信息了。

小案例

修改一些配置,然后push到gitlab。

$ git commit -m 'Fix image'$ git push origin master

下面的截图显示了GitLab.com项目页面中的提交触发的信息

在Portainer端,接收webhook并执行服务更新。我们无法在这里清楚地看到它,但是已经更新了一个副本,使web站点可以通过第二个副本访问。然后,几秒钟后,第二个副本被更新。

总结

即使对于这个小项目,设置一个CI/CD管道也是一个很好的练习,尤其是要更加熟悉GitLab。这是一个优秀的产品。这也是使用期待已久的Portainer(1.19.2)最新版本的webhook特性的好机会。另外,对于像这样的一个小项目,使用Docker Swarm是很简单的——它很酷,而且很容易使用!

[1]:https://gitlab.com/lucj/sophia.events

[2]:https://gitlab.com/lucj/sophia.events/blob/master/index.mustache

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表