Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Jenkins #10

Open
16slowly opened this issue Oct 25, 2018 · 0 comments
Open

CI: Jenkins #10

16slowly opened this issue Oct 25, 2018 · 0 comments
Assignees
Labels
doc document

Comments

@16slowly
Copy link
Owner

16slowly commented Oct 25, 2018

以下所说的 CI 包含了持续集成,持续交付,持续部署。

什么是持续集成 (Continuous Integration)

Continuous Integration (CI) is a development practice where developers integrate code into a shared repository frequently, preferably several times a day. Each integration can then be verified by an automated build and automated tests

  • 持续集成:在写好新代码之后,立刻进行构建、(单元)测试。根据测试结果,确定新代码和原有代码能否正确地集成在一起。是持续交付,持续部署的前提
    (这个过程体现在每次提交 pr, 修改 pr 时都需要触发 CI 的构建,这样能及时发现 npm 依赖包出错等问题)

  • 持续交付: 在持续集成的前提下,将代码部署到已连接到测试数据库的「类生产环境:Staging」下进行更多的测试。
    (这个过程中,能及时发现接口所返回的数据是否一致,网络请求是否正确等问题, 我们的测试服域名为:next.xxx.vivedu.com)

  • 持续部署: 在持续交付的基础上,将部署到生产环境的过程自动化
    (需要做更多工作,具体是...)

Jenkins & Github

搭建 Jenkins 服务器,将 Jenkins 服务器与 Github 进行关联,配置每次提交代码到 github, 就能触发 Jenkins 依照 Jenkinsfile 执行拉取代码 => npm install => npm run test => npm run build => deploy dev => deploy product 等过程。并将每个阶段的执行结果反馈到 slack, 以跟踪进度,及时发现问题并解决问题。

准备工作

  • 拆分上传文件到 ali-oss 的 node 脚本

搭建步骤(基于 Linux/Ubuntu 发行版)

1. 安装 Java

apt-get install openjdk-8-jdk

2. 下载并安装 Jenkins

see https://jenkins.io/doc/book/installing/#debian-ubuntu.

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

3. 通过 ip:8080 访问 Jenkins 控制台

  • 获取 Jenkins 的初始登录密码进行登录
  • 安装社区推荐的插件
  • 重启 Jenkins 服务

4. 使用管理员账号登录到 github, 生成 github 的 token

Settings > Developer settings > Personal access tokens > Generate new token

勾选以下 scopes

  • repo
  • admin: repo_hook

5. 为 Jenkins 添加两种类型的 Credentials, 赋予 Jenkins 访问 Github 上的项目权限

在 Jenkins 控制台

Credentials > System > Global credentials > Add Credentials

  1. github-jenkins-token

Secret 填写第4步产生的 token

2018-03-22 6 58 52

  1. github-account
    1547865197

6. 转到需要构建的项目,为其配置 webhooks

Settings > Webhooks > Add webhook

  • 设置该 webhook 的 Payload URLhttp://[jenkins server ip]:8080/github-webhook
  • 设置 Content type 为 application/json

勾选以下几项,作为触发 CI 构建的时机:

  • Pull requests (提交 pr 时)
  • Pushes
  • Releases

7. 新建 Multibranch Pipeline 类型的项目,对需要构建的项目进行绑定并配置:

1547864964
2018-04-19 6 07 23

集成 Docker

1. Install Docker

see https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update

2. Pull node image

 docker pull node:8.10.0

3. Pipeline agent 指向 Docker

see https://jenkins.io/doc/book/pipeline/docker/

{
    agent {
        docker {
             image 'node:8.10.0'
            // 赋予 docker container(uid: 112, gid: 116) 访问镜像根目录的权限与免密登录 nginx 服务器的能力
             args '-u root:root -v /root/.ssh:/root/.ssh'
        }
    }
}

构建任务管理

对于相同的构建,新的构建总能终止前一次的构建。每次提交 pr,更新 pr 都将触发 CI 的构建,对于包含 code review 的工作流程来说,只有最后一次的构建是有效的, 无效构建将通过以下函数进行终止:

def abortPreviousBuilds() {
  def currentJobName = env.JOB_NAME
  def currentBuildNumber = env.BUILD_NUMBER.toInteger()
  def jobs = Jenkins.instance.getItemByFullName(currentJobName)
  def builds = jobs.getBuilds()

  for (build in builds) {
    if (!build.isBuilding()) {
      continue;
    }

    if (currentBuildNumber == build.getNumber().toInteger()) {
      continue;
    }

    build.doStop()
  }
}

需要注意的是,执行 System Groovy Script 将会带来一些安全问题:

"System groovy jobs has access to whole Jenkins, therefore only users with admin rights can add system Groovy build step and configure the system Groovy script. Permissions are not checked when the build is triggered, you can use this to alter the state of Jenkins"

更多相关可查看 https://wiki.jenkins.io/display/JENKINS/Groovy+plugin

解决办法可参考 http://blog.ehrnhoefer.com/2017-04-23-jenkins-groovy-security/ 中的以下做法:

  • 安装 Permissive Script Security 插件
  • 在 /etc/default/jenkins 文件中设置 -Dpermissive-script-security.enabled=true

磁盘空间管理

Jenkins 在进行构建时,会将分支代码 clone 到 Jenkins 服务器中,但不会自动清除对已完成构建的分支代码,导致这些代码占用了大量的磁盘空间。

image

  • 控制并发构建的 executors 数量

在 “系统管理 > 系统设置 > 执行者数量” 中根据实际情况进行设置

跨服文件传输

使用 scp 传输 nginx 相关的配置文件

Reset PR's Status

github status

加入 github status check 之后,当 CI 构建成功则说明该部分代码可以
所以当 npm run build 构建成功之后,通过 curl 设置 Github status 为 success

curl

Github status

授权

  • Jenkins 与 docker 进程之间的授权问题。

    介入 docker 之后,docker container 将伪装成 Jenkins 服务器与测试服/正式服通信。

  • 免密访问

    需要授予 Jenkins 服务器访问测试服与正式服的权限,使他们之间能够进行免密通信,Jenkins 需要执行重启服务器等工作。

Deploy

  • 设置环境变量,执行 npm run upload 将打包好的文件进行上传。
  • 传输 nginx 配置
  • 重启服务器

Jenkinsfile

@16slowly 16slowly self-assigned this Oct 25, 2018
@16slowly 16slowly changed the title CI: Jekins CI: Jenkins Oct 25, 2018
@16slowly 16slowly added the doc document label Dec 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc document
Projects
None yet
Development

No branches or pull requests

1 participant