内容简介:全部配置详见:安装 GitLab 、Node.js、Publish over SSH 插件今天踩了不少坑。。。
全部配置详见: https://github.com/xuexb/DevOps/tree/master/jenkins-node
目标
- [x] 负载均衡
- [ ] 快速回滚
- [x] 多机部署
- [ ] 灰度发布
服务说明
- GitLab - 用来存放示例代码、主动触发编译(Web Hook)
- Jenkins - 编译
- Nginx - 域名转发
- Node.js - 提供多个虚拟的容器做为目标服务器,且这些虚拟机中已经安装 Node.js Yarn PM2 ,因为没有这么多真实的机器,毕竟穷。。。
前置依赖
- 添加 Hosts :
127.0.0.1 fe.com jenkins.fe.com www.fe.com gitlab.fe.com node1.fe.com node2.fe.com node3.fe.com node4.fe.com node5.fe.com - 【可选】创建一个私有的 key :
rm -rf ssh/* && ssh-keygen -t rsa -N '' -f ssh/id_rsa,如果新创建的需要把ssh/id_rsa.pub复制到.env的AUTHORIZED_KEYS,用来免密码登录 Node.js 的各个节点,注意需要使用 Linux 系统生成,macOS Mojave 生成的是OPENSSH格式,在 Publish over SSH 插件时有问题,其实你大可以不用生成,使用默认的
域名、端口说明
-
node*.fe.com- 虚拟出来的多个 Node.js 主机,目前是1-5个,如node1.fe.com -
www.fe.com- 负载均衡到node1-5中 -
jenkins.fe.com- Jenkins 地址 -
gitlab.fe.com- GitLab 地址 -
宿主:80- 提供 Nginx 反代 -
宿主:22- 提供 GitLab ssh clone 代理 -
node*:3000- Node.js 容器内部使用 PM2 启动的服务,暴露的 Web Server 端口,由 Nginx 直接使用容器名称:3000做转发
GitLab 配置
- 把
ssh/id_rsa.pub公钥配置到帐户中,结合 Jenkins 安全凭证让 Jenkins 可以克隆 GitLab 项目 - http://gitlab.fe.com/profile/personal_access_tokens 创建 API token ,并记录下来,因为这个 token 只在第一次显示
- http://gitlab.fe.com/admin/application_settings/network#js-outbound-settings 管理员登录,开启
Allow requests to the local network from hooks and services
Jenkins 配置
安装 GitLab 、Node.js、Publish over SSH 插件
- 使用 GitLab 的 api token 创建一个 GitLab 插件使用的凭证,注意:
- API token - 是刚才在 GitLab 创建的 API token
- ID - 最好别设置,这个会自动生成一个唯一标识,在 pipeline 脚本中使用
- 描述 - 可以设置描述当前 API token 的功能
-
- 系统设置中配置 Publish over SSH 插件,host 为宿主对应的 Node.js 容器名称:
-
配置任务的编译后配置,注意:
- Source files - 匹配需要复制的源文件
- Remove prefix - 删除的目录前缀,其实就是替换路径的意思
- Remote directory - 远程路径,有个坑的是这里是基于 Publish over SSh 系统配置里的 Remote directory 的相对路径
- Exec command - 执行命令
-
-
系统设置中配置 GitLab 插件,注意:由于是通过 Jenkins 容器向 GitLab 连接,host 需要是 GitLab 的容器名 gitlab :
- 添加一个 gitlab-root 的凭证用于克隆项目,注意:这里的私钥是
ssh/id_rsa的内容,因为对应的公钥已经在 GitLab root 用户中添加了,这样就可以使用 gitlab-root 这个凭证克隆项目了,还要注意那个 host ,需要是 GitLab - 全局 工具 里配置 Node.js ,这里以 v10.x 为例
难题
今天踩了不少坑。。。
1. 密钥、公钥
- 需要把密钥配置在 Jenkins 里一个凭据,在 GitLab 里添加公钥以让可以克隆项目
- 密钥需要配置到
.env中,然后会透传给 https://hub.docker.com/r/dockerxman/docker-ubuntu-ssh/ 让其创建的 Node.js 虚拟服务器都可以使用公钥直接登录 - Publish over SSH 需要使用密钥,使其可以直接 SSH 免密码登录到 Node.js 虚拟服务器
- ssh key 不能使用 macOS Mojave 系统创建,否则不能过 Publish over SSH
2. Docker 配置的环境变量在 SSH 登录后不生效
为了更好的测试各个 Node.js 虚拟服务器分布,需要给每个虚拟服务器里配置个配置 ENV_LABEL ,表示当前服务器标签名,并在 Node.js 里设置了 Response.headers 的 X-Node-Label 字段,但发现在目标服务里的 Node.js 里获取不到,经过百般测试,发现需要:
- 首先需要在 Docker 里对各个虚拟 Node.js 服务器配置变量,在
docker-compose.yml文件对对各个节点配置environment。 - 在 Node.js 虚拟服务器的 Dockerfile 里以自定义文件
env.sh为入口(CMD),并在env.sh里向目标服务器写入到~/.env为当前变量(因为在docker-compose.yml里配置的变量,在 Dockerfile 里可以读取到),如:
#!/bin/bash
# 写入一个标签变量,因为在 docker-compose.yml 里配置的使用 ssh 登录获取不到
echo "ENV_LABEL=$ENV_LABEL" > /root/.env
echo '[ -s "$HOME/.env" ] && \. "$HOME/.env"' >> /root/.bashrc
# 运行 dockerxman/docker-ubuntu-ssh:latest 的入口文件
if [ -f /run.sh ]; then
/run.sh
fi
- 在部署的 Node.js 项目中的部署脚本里需要先读到
$HOME/.env,这样在部署脚本里就可以获取变量,但在 PM2 或者 Node.js 代码里还是获取不到,需要在部署脚本里export 变量=${变量}透传才可以 - 由于 Node.js 项目由 PM2 启动,在 PM2 里的变量需要透传到 Node.js app 中,如
pm2.config.jsPM2 启动配置:
module.exports = {
apps: [
{
name: 'app',
script: './index.js',
env: {
NODE_ENV: 'production',
// 透传变量
ENV_LABEL: process.env.ENV_LABEL,
},
},
],
};
Jenkins 任务日志
13:50:38 Started by user admin
13:50:38 Building in workspace /var/jenkins_home/workspace/node-demo
13:50:38 [WS-CLEANUP] Deleting project workspace...
13:50:38 [WS-CLEANUP] Deferred wipeout is used...
13:50:38 [WS-CLEANUP] Done
13:50:38 Cloning the remote Git repository
13:50:38 Cloning repository git@gitlab:root/node-demo.git
13:50:38 > git init /var/jenkins_home/workspace/node-demo # timeout=10
13:50:38 Fetching upstream changes from git@gitlab:root/node-demo.git
13:50:38 > git --version # timeout=10
13:50:38 using GIT_SSH to set credentials gitlab-root
13:50:38 > git fetch --tags --progress git@gitlab:root/node-demo.git +refs/heads/*:refs/remotes/origin/*
13:50:40 > git config remote.origin.url git@gitlab:root/node-demo.git # timeout=10
13:50:40 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
13:50:40 > git config remote.origin.url git@gitlab:root/node-demo.git # timeout=10
13:50:40 Fetching upstream changes from git@gitlab:root/node-demo.git
13:50:40 using GIT_SSH to set credentials gitlab-root-ssh
13:50:40 > git fetch --tags --progress git@gitlab:root/node-demo.git +refs/heads/*:refs/remotes/origin/*
13:50:41 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
13:50:42 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
13:50:42 Checking out Revision f6d9691839f578a4f880260871e2a39a263d2e45 (refs/remotes/origin/master)
13:50:42 > git config core.sparsecheckout # timeout=10
13:50:42 > git checkout -f f6d9691839f578a4f880260871e2a39a263d2e45
13:50:43 Commit message: "feat: fest"
13:50:43 > git rev-list --no-walk f6d9691839f578a4f880260871e2a39a263d2e45 # timeout=10
13:50:43 [node-demo] $ /bin/sh -xe /tmp/jenkins6335245445213181284.sh
13:50:43 + yarn -v
13:50:44 1.13.0
13:50:44 + node -v
13:50:44 v10.15.0
13:50:44 + npm -v
13:50:46 6.4.1
13:50:46 + yarn install
13:50:47 yarn install v1.13.0
13:50:47 [1/4] Resolving packages...
13:50:47 [2/4] Fetching packages...
13:50:47 [3/4] Linking dependencies...
13:50:49 [4/4] Building fresh packages...
13:50:49 Done in 2.55s.
13:50:49 + yarn test
13:50:50 yarn run v1.13.0
13:50:50 $ echo 'test'
13:50:50 test
13:50:50 Done in 0.27s.
13:50:50 + yarn build
13:50:51 yarn run v1.13.0
13:50:51 $ mkdir -p dist && ls | grep -vE '(README\.md|dist)' | xargs -I {} cp -r {} dist/
13:50:53 Done in 2.56s.
13:50:53 SSH: Connecting from host [541f45e72785]
13:50:53 SSH: Connecting with configuration [Node-1] ...
13:50:53 SSH: EXEC: STDOUT/STDERR from command [/bin/bash /root/app/deploy.sh] ...
13:50:54 Deploy in node1
13:50:54 v11.6.0
13:50:54 6.5.0-next.0
13:50:55 3.2.7
13:50:55 1.13.0
13:50:55 yarn install v1.13.0
13:50:55 [1/4] Resolving packages...
13:50:55 success Already up-to-date.
13:50:55 Done in 0.21s.
13:50:56 [PM2] Applying action reloadProcessId on app [app](ids: 0)
13:50:56 [PM2] [app](0) ✓
13:50:56 ┌──────────┬────┬─────────┬──────┬─────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
13:50:56 │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
13:50:56 ├──────────┼────┼─────────┼──────┼─────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
13:50:56 │ app │ 0 │ 1.0.0 │ fork │ 983 │ online │ 1 │ 0s │ 0% │ 10.9 MB │ root │ disabled │
13:50:56 └──────────┴────┴─────────┴──────┴─────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
13:50:56 Use `pm2 show <id|name>` to get more details about an app
13:50:56 SSH: EXEC: completed after 2,613 ms
13:50:56 SSH: Disconnecting configuration [Node-1] ...
13:50:56 SSH: Transferred 5 file(s)
13:50:56 SSH: Connecting from host [541f45e72785]
13:50:56 SSH: Connecting with configuration [Node-2] ...
13:50:56 SSH: EXEC: STDOUT/STDERR from command [/bin/bash /root/app/deploy.sh] ...
13:50:57 Deploy in node2
13:50:57 v11.6.0
13:50:57 6.5.0-next.0
13:50:57 3.2.7
13:50:57 1.13.0
13:50:58 yarn install v1.13.0
13:50:58 [1/4] Resolving packages...
13:50:58 success Already up-to-date.
13:50:58 Done in 0.19s.
13:50:58 [PM2] Applying action reloadProcessId on app [app](ids: 0)
13:50:58 [PM2] [app](0) ✓
13:50:58 ┌──────────┬────┬─────────┬──────┬─────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
13:50:58 │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
13:50:58 ├──────────┼────┼─────────┼──────┼─────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
13:50:58 │ app │ 0 │ 1.0.0 │ fork │ 972 │ online │ 1 │ 0s │ 0% │ 10.8 MB │ root │ disabled │
13:50:58 └──────────┴────┴─────────┴──────┴─────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
13:50:58 Use `pm2 show <id|name>` to get more details about an app
13:50:58 SSH: EXEC: completed after 2,408 ms
13:50:58 SSH: Disconnecting configuration [Node-2] ...
13:50:58 SSH: Transferred 5 file(s)
13:50:58 SSH: Connecting from host [541f45e72785]
13:50:58 SSH: Connecting with configuration [Node-3] ...
13:50:59 SSH: EXEC: STDOUT/STDERR from command [/bin/bash /root/app/deploy.sh] ...
13:50:59 Deploy in node3
13:50:59 v11.6.0
13:50:59 6.5.0-next.0
13:51:00 3.2.7
13:51:00 1.13.0
13:51:00 yarn install v1.13.0
13:51:00 [1/4] Resolving packages...
13:51:00 success Already up-to-date.
13:51:00 Done in 0.18s.
13:51:01 [PM2] Applying action reloadProcessId on app [app](ids: 0)
13:51:01 [PM2] [app](0) ✓
13:51:01 ┌──────────┬────┬─────────┬──────┬─────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
13:51:01 │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
13:51:01 ├──────────┼────┼─────────┼──────┼─────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
13:51:01 │ app │ 0 │ 1.0.0 │ fork │ 684 │ online │ 1 │ 0s │ 0% │ 20.0 MB │ root │ disabled │
13:51:01 └──────────┴────┴─────────┴──────┴─────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
13:51:01 Use `pm2 show <id|name>` to get more details about an app
13:51:01 SSH: EXEC: completed after 2,409 ms
13:51:01 SSH: Disconnecting configuration [Node-3] ...
13:51:01 SSH: Transferred 5 file(s)
13:51:01 SSH: Connecting from host [541f45e72785]
13:51:01 SSH: Connecting with configuration [Node-4] ...
13:51:01 SSH: EXEC: STDOUT/STDERR from command [/bin/bash /root/app/deploy.sh] ...
13:51:02 Deploy in node4
13:51:02 v11.6.0
13:51:02 6.5.0-next.0
13:51:03 3.2.7
13:51:03 1.13.0
13:51:03 yarn install v1.13.0
13:51:03 [1/4] Resolving packages...
13:51:03 success Already up-to-date.
13:51:03 Done in 0.19s.
13:51:04 [PM2] Applying action reloadProcessId on app [app](ids: 0)
13:51:04 [PM2] [app](0) ✓
13:51:04 ┌──────────┬────┬─────────┬──────┬─────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
13:51:04 │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
13:51:04 ├──────────┼────┼─────────┼──────┼─────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
13:51:04 │ app │ 0 │ 1.0.0 │ fork │ 685 │ online │ 1 │ 0s │ 0% │ 20.3 MB │ root │ disabled │
13:51:04 └──────────┴────┴─────────┴──────┴─────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
13:51:04 Use `pm2 show <id|name>` to get more details about an app
13:51:04 SSH: EXEC: completed after 2,809 ms
13:51:04 SSH: Disconnecting configuration [Node-4] ...
13:51:04 SSH: Transferred 5 file(s)
13:51:04 SSH: Connecting from host [541f45e72785]
13:51:04 SSH: Connecting with configuration [Node-5] ...
13:51:04 SSH: EXEC: STDOUT/STDERR from command [/bin/bash /root/app/deploy.sh] ...
13:51:05 Deploy in node5
13:51:05 v11.6.0
13:51:05 6.5.0-next.0
13:51:05 3.2.7
13:51:06 1.13.0
13:51:06 yarn install v1.13.0
13:51:06 [1/4] Resolving packages...
13:51:06 success Already up-to-date.
13:51:06 Done in 0.18s.
13:51:06 [PM2] Applying action reloadProcessId on app [app](ids: 0)
13:51:07 [PM2] [app](0) ✓
13:51:07 ┌──────────┬────┬─────────┬──────┬─────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
13:51:07 │ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
13:51:07 ├──────────┼────┼─────────┼──────┼─────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
13:51:07 │ app │ 0 │ 1.0.0 │ fork │ 685 │ online │ 1 │ 0s │ 0% │ 19.2 MB │ root │ disabled │
13:51:07 └──────────┴────┴─────────┴──────┴─────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
13:51:07 Use `pm2 show <id|name>` to get more details about an app
13:51:07 SSH: EXEC: completed after 2,409 ms
13:51:07 SSH: Disconnecting configuration [Node-5] ...
13:51:07 SSH: Transferred 5 file(s)
13:51:07 Finished: SUCCESS
最终效果
每个 Node.js 服务都带有当前环境标签:
负载均衡入口:
参考连接
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 机器学习项目是如何开发和部署的?
- Uber如何在公司范围内部署机器学习
- Oracle开源机器学习模型云端部署工具Graphpipe
- 机器学习模型部署--打通前后端任督二脉
- 如何将机器学习的模型部署到NET环境中?
- 全球AI人才需求两年暴增35倍 中国机器人部署量涨500%
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。