Jenkins 与 GitLab 的自动化构建之旅

一、Gitlab 的安装及仓库创建

1.1 下载 Gitlab 安装包

1).官网下载速度较慢 建议先行下载

国内的源里面可以找到最新的版本,请单击这里查看。

2).安装依赖

sudo apt-get install curl openssh-server ca-certificates postfix

3).配置 postfix 邮箱

未分类

选择 Internet Site (F12) Enter 下一步

未分类

这里设置FQDN 使用默认即可。

1.2 安装 Gitlab

在终端执行:sudo dpkg -i gitlab-ce9.5.4ce.0amd64.deb 进行安装。

未分类

出现 It looks like… 表示安装成功!

1.3 安装 Git 工具

未分类

1.4 生成密钥文件

使用 ssh-keygen 生成密钥文件 .ssh/id_rsa.pub。

未分类

未分类

这里生成的两个秘钥很重要,会在后面 Gitlab 的仓库配置与 Jenkins 的构建免密连接时候用到。

二、GitLab 简单配置及项目新建

2.1 配置 Gitlab

这一步在官方的文档里面没有,但是如果没有配置的话,直接启动 GitLab,会出现不正确的 FQDN 错误,导致无法正常启动。因此必须做配置。

sudo gedit /etc/gitlab/gitlab.rb

把 external_url 改成部署机器的域名或者IP地址。

未分类

然后对 GitLab 进行重配置 (这一步也是启动 GitLab):

sudo gitlab-ctl reconfigure

查看启动状态:

sudo gitlab-ctl status

未分类

在浏览器的地址栏中输入服务器的公网 IP 即可登录 GitLab 的界面,第一次登录使用的用户名和密码为 root 和 5iveL!fe。

未分类

首次登录会强制用户修改密码。密码修改成功后,输入新密码进行登录。

2.2 Gitlab 项目新建

在 GitLab 的主页中新建一个 Project:

未分类

未分类

添加 ssh key 导入步骤2中生成的密钥文件内容(秘钥前面1.4节已生成):

未分类

ssh key 添加完成:

未分类

项目地址,该地址在进行 clone 操作时需要用到:

未分类

2.3 代码上传

克隆项目,在本地生成同名目录,并且目录中会有所有的项目文件 git clone [email protected]:gavin/test.git:

未分类

进入到项目目录,拷贝自己的项目文件到此目录上传:

cd test/ 
cp –rf  自己项目路径/*   .
git add .
git commit -m “add README” #将代码提交到本地仓库
git push -u origin master #将文件同步到GitLab服务器上

在网页中查看上传的文件已经同步到 GitLab 中:

未分类

三、Jenkins 安装与配置

3.1 Java 环境配置

Jenkins 基于 Java,Linux 下安装 Java 只要配置 Java 环境变量即可。 首先,解压java到相应目录,我一般习惯把安装的软件放到目录/usr/local下。

tar -zxvf jdk-6u45-linux-x64.tar.gz /usr/local

编辑环境变量,在 /etc/profile 文件中添加环境变量,Linux 的所有用户都可以使用。

vim /etc/profile

在文件最后添加内容如下:

export JAVA_HOME=/usr/local/jdk1.6.0_45
export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

这样,Java 就配置完成:

未分类

3.2 安装 Jenkins

简单来说需要下面四步:

  • wget -q -O – https://pkg.jenkins.io/debian/jenkins-ci.org.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

未分类

这样之后就安装完成。可以查看进程信息。

ps -ef |grep jenkins

未分类

3.3 Jenins 配置

上面只是安装完成了 Jenkins,还需要进行一些配置才可以。 在这个系统端口中,8080已经在使用中了。所以在 /etc/default/jenkins.修改 Jenkins 默认端口设置:

gavin@gavin:~$ gedit /etc/default/jenkins

未分类

修改默认端口为 HTTP_PORT=8090,这时通过浏览器就可以访问 Jenkins 了。比如我的地址:http://192.168.0.122:8090/

未分类

可以看到提示,为了确保 Jenkins 的安全,将管理员的密码写入文件,需要复制到下面的文本框做验证。

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

然后把输出的内容复制到上面密码框处。

然后,到了选择插件的界面,通过附加功能扩展 Jenkins 可以支持许多不同的需求。

未分类

未分类

未分类

插件安装完成,就到了创建用户的界面,这里可以创建一个 Jenkins 用户。

未分类

到这里,基本配置就完成了。

未分类

未分类

如果在后续使用中,有插件需要安装,通过在已运行的 Jenkins 主页中,点击左侧的系统管理—>管理插件进入如下界面搜索安装:

未分类

四、Android 项目构建

4.1 SDK 环境变量的设置

在“系统管理”—>“系统设置”—>“全局属性”设置 SDK 的环境变量名称与本地 SDK 的路径。

未分类

未分类

4.2 新建 Android 项目

开始创建一个 AndroidDemo 项目进行演:

未分类

构建一个自由风格的软件项目,然后填写项目名称。

未分类

源码管理,这里可以根据自己的实际选择 Git 或者 SVN 服务器。先设置 Git 的源码路径:

然后设置免密凭证。如果是第一次需要通过“Add”添加。

未分类

添加凭证:

单击“add”按钮进行添加:

未分类

未分类

此处的私钥既是1.4章节所产生。

设置完成上面的步骤,直接按左下角保存,项目创建完成。

五、参数化项目构建

5.1 参数设置

建好的项目,相应修改构建参数等配置,直接通过“配置”进行修改:

未分类

选择实际需要用到的参数,比如发布的版本类型,Git 分支参数等。

未分类

1) 选择参数的设置:

未分类

设置打包的类型是 debug 或者 release。

未分类

打包的 App 针对的发布平台:

未分类

2) Git 分支选择:

想在构建的时候,自动获取 Git 仓库的分支并选择构建,可以设置如下:

未分类

未分类

3) gradle 脚本命令的配置:

未分类

选择“Invoke Gradle script”添加 gradle 命令脚本。

未分类

设置完这些参数保存,就可以退出到项目列表界面。

5.2 项目构建

进入项目开始构建,选择相应的参数。

未分类

构建成功的话,那么结果如下图:

未分类

构建完会在“Build History” 部分显示构建结果是成功还是失败并可以查看相应的构建日志,方便分析:

未分类

构建结果是红色代表构建失败,上图颜色表示构建成功。

构建状态:下图中分级符号概述了一个 Job 新近一次构建会产生的四种可能的状态。

  • Successful:完成构建且被认为是稳定的。
  • Unstable:完成构建,但被认为不稳定。
  • Failed:构建失败。
  • Disabled:构建已禁用。

未分类

在主界面则是通过构建稳定性评分等级进行表示。

未分类

构建稳定性:当一个 Job 中构建已完成并生成了一个未发布的目标构件,如果您准备评估此次构建的稳定性,Jenkins 会基于一些后处理器任务为构建发布一个稳健指数(从0-100 ),这些任务一般以插件的方式实现。它们可能包括单元测试(JUnit)、覆盖率(Cobertura)和静态代码分析(FindBugs)。分数越高,表明构建越稳定。下图中分级符号概述了稳定性的评分范围。任何构建作业的状态(总分100)低于80分就是不稳定的。

未分类

还有很多的参数配置,如触发器配置、邮箱配置,自动化发布等的参数很多,这里就不一一介绍,感兴趣的朋友可以上网或者留言交流。

jenkins的安装与配置

一、jenkins 是什么

Jenkins 是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。Jenkins是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,功能包括:

持续的软件版本发布/测试项目。
监控外部调用执行的工作。

二、安装 jenkins

jenkins 的安装有很多种,具体可以参照官方文档 https://jenkins.io/doc/book/installing/ ,我这里使用 war 包,放在 tomcat 容器里面启动。

1、安装jdk

请安装 jdk1.8或者更高的版本。

未分类

2、安装tomcat

tomcat我用的是7的版本。

未分类

3、安装jenkins

去官网下载我们的版本,http://mirrors.jenkins.io/war-stable/latest/jenkins.war 。

未分类

启动之后,我们看到在家目录下面生成一个 .jenkins 目录,我们的配置数据都是存放在这里的。

三、配置jenkins

1、初始化

第一次访问的时候会有一个重置密码界面,我们按照他的要求进行即可。

未分类

因为大家众所周知的原因,服务器被墙了,我们无法安装插件,跳过即可。

未分类

最后一步,我们设置管理员账户密码就可以了。

未分类

2、插件服务器

登录到系统里面,点击系统管理—>管理插件—>高级,把里面的升级地址改成如下地址。
http://ftp.tsukuba.wide.ad.jp/software/jenkins/updates/current/update-center.json

未分类

这样我们就可以在线安装插件了。

未分类

3、配置jdk

jdk1.8我们已经事先安装好了,路径是 /usr/java/default/。点击系统管理—>全局工具配置。

未分类

4、配置maven

去 maven 官网下载软件,直接解压在 /usr/local 路径下面,我下载的地址是 http://mirrors.shuosc.org/apache/maven/maven-3/3.5.2/binaries/apache-maven-3.5.2-bin.tar.gz 。

点击系统管理—>全局工具配置。

未分类

四、插件安装

1、安装 git plugin

首先我们需要在 jenkins 所在服务器上面安装 git 客户端,可以 yum 安装,也可以编译安装新版本。

未分类

静静的等待安装完成。

未分类

点击系统工具—>全局工具配置。

未分类

2、安装 maven 插件

目前我们创建项目还是没有 maven 的,因为我们还没有安装插件。

未分类

现在我们点击新建,就可以看到 maven 项目的构建啦。

未分类

3、配置邮件服务器

点击系统管理—>系统设置。

未分类

Jenkins 平台部署

持续集成这个词大家应该都不陌生,同时Jenkins 这个工具肯定也是非常耳熟了,但是对于以前做php运维(不需要进行代码编译)方面工作的朋友对JAVA等项目的编译可能就不了解了,而持续集成说的这么高大上,其实也就是为了把源代码从Git或者SVN仓库里面拖下来,使用一个工具(如Jenkins)通过配置文件把代码编译出来,如Java项目经常就编译打包为war包或者zip包等等,编译完成后再推送到对应的服务器上进行发布。这就是我理解的持续集成的功能。
  
下面简单记录下最最常用的持续集成工具—-Jenkins

  • 系统环境:CentOS Linux release 7.3.1611
  • JAVA版本:java version “1.8.0_121”
  • Tomcat : 8

以上这些基本环境就不多说了,嫌麻烦可以选择采用一键安装包 《 OneinStack 》 进行安装,当然弄完了最好根据需求调整下相应配置。

Jenkins 有多种安装方式,centos上可以采用rpm包安装,war包,docker等等 Jenkins 官方下载 ,本文采用tomcat部署war包方式。

出于安全考虑,个人部署的服务器基本都不会用root用户运行tomcat 等中间件服务(血的教训),所以调整下tomcat的启动用户。

一:新建普通用户启动tomcat

这里指定一个tomcat 跑Jenkins ,所以直接新建一个Jenkins用户。

[root@jenkins ~] useradd jenkins
[root@jenkins ~] chown jenkins.jenkins -R /usr/local/tomcat_jenkins
#如果用oneinstack一键安装的tomcat那么改动下/etc/init.d/tomcat 脚本中的TOMCAT_USER=jenkins 即可,如果自己安装的tomcat并未制作启动脚本,就需要使用su username -c 来启动:
[root@jenkins ~] su jenkins -c /usr/local/tomcat_jenkins/bin/startup.sh

如果直接用root用户运行的tomcat 就无需以上步骤了。

二:初始化Jenkins

  
由于采用war包部署,把war包放到tomcat的webapps目录下即可自动解压部署(autoDeploy=”true”),然后浏览器访问http://yourIPaddr:8080/jenkins/ 就会看到Jenkins初始化界面,要求在服务器上打开这个文件获取初始密码。

未分类  

进入系统设置的时候居然有提示“反向代理设置有误”和“Your container doesn’t use UTF-8 to decode URLs. ……”的提示,不知道是不是这个版本问题,反向代理那个直接放弃了,关于UTF-8这里我核实了tomcat配置文件中已经设置了URIEncoding=”UTF-8″ ,同时也并不影响中文的显示,就没有过多去查这个问题了。

未分类

三:基本插件管理

  
新装好的Jenkins 只有简单的功能,如Git库代码获取,框架构建这些功能都需要单独添加插件。
  
通过【系统管理】-【管理插件】-【可选插件】即可获取相应的功能插件,这里我只需要能够访问Git库,通过maven 打包Java代码,再使用ansible推送 几个功能,所以选择安装Ansible plugin ,Git plugin ,Maven Integration plugin 即可。

插件安装好后在新建项目页面就可以看到已经增加了maven项目。

未分类

使用Jenkins部署应用到Kubernetes

【编者的话】这篇文章基于去年5月进行的一次Kubernetes使用情况调查,阐述了使用Jenkins作为持续集成工具部署应用程序到Kubernetes的现状,对于大家如何进行CI/CD工具的选型有参考意义。

新的技术栈正不断交付Kubernetes开源容器编排引擎的内容。 本周我们将报告如何将应用程序实际部署到Kubernetes。 当在容器编排、持续交付流水线或配置管理工具之间进行选择时,我们2017年5月进行的Kubernetes调查的受访者经常表示他们使用编排框架来部署应用程序。 虽然有些人曾经把Kubernetes想象成可以做任何事情的瑞士军刀,但实际上他们对应用程序部署中的Kubernetes的角色有着更细致的了解。

当更直接地问到他们是否使用Jenkins将应用程序部署到Kubernetes时,45%的人表示赞成,另有36%的Kubernetes用户使用其它的持续部署(CD)流水线将应用程序部署到Kubernetes,其中GitLab CI和CircleCI是被提及最多的。请注意,调查问题的性质意味着这些信息不能用来决定市场份额,其他工具的整体采用率可能高于下图所示。

未分类

这就是说,Jenkins仍然是最常用的持续集成(CI)工具。 未来的研究将不会问是否使用Jenkins,而是会问在组织流水线中的核心地位。 在许多情况下,同一公司内的不同团队将使用竞争产品。 在其他情况下,Jenkins是更大工作流程中的一个小组件,另一个供应商的工具会是CD流水线图中的焦点。

深入挖掘一下,我们发现小公司(两到一百名员工)相对于平均情况使用Jenkins的可能性较小(38%比45%),可能是因为他们以前没有需要部署工作流的大型组织。 这与我们上周写到的一个趋势是一致的,即不同规模的团队倾向于使用不同的CI/CD工具。

受访者认为,应用程序的自动化部署是使用成熟的Kubernetes一个关键优势。 许多受访者描述了交付流水线如何与Kubernetes所带来的更大的组织变革相关联。 有人说:“在我们的早期阶段,改进开发人员的工作流程,使开发人员能够思考他们的代码是如何在生产环境中运行的,这是我们想要用Kubernetes实现的最重要的事情。”

我们知道有65%的生产环境用户在Kubernetes上运行应用程序开发工具。 在这方面,Kubernetes对于持续部署和提供“基础设施即代码”至关重要。

使用 Docker 搭建 Gitlab + Jenkins + SonarQube 的 PHP 持续集成环境

对于开源 PHP 项目,现在比较成熟的一套持续集成方案是使用 Github + TravisCI + StyleCI + Scrutinizer + coveralls,不过这套方案如果想要用于私有项目的话就抓狂了,个个要买套餐,其中很多还不便宜。而且对于公司内使用的项目来说,内部搭建的 Gitlab 方案更为常见,对于这种情况,我们可以使用 Gitlab + Jenkins + SonarQube 来进行代替。

安装 SonarQube

$ docker pull postgres

$ docker run --name db -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -d postgres

$ docker pull sonarqube

$ docker run --name sq --link db -e SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar -p 9000:9000 -d sonarqube

执行完毕上面的命令后通过浏览器进入 SonarQube,默认用户名和密码都是 admin,进去后会有一段引导,里面会让你生成一个 access token,这个后面的配置 Jenkins 时会用到。

如果没有记下来的话,可以点右上角的用户头像里面的 My Account > Security 标签中可以生成一个新的。

配置 Jenkins

Jenkins 需要在全局的 系统设置 里面添加 SonarQube Server,填下对应的访问地址和上一步获取的 access token 即可。服务器地址填写 localhost 可能会有问题,填 ip 会比较好些。

然后需要在 系统管理 的 Global Tool Configuration 菜单中配置 SonarQube Scanner 安装,这个直接选择自动安装就好了,十分方便。

这两步配好之后就到对应的项目配置中添加构建步骤,下拉选择 Execute SonarQube Scanner,然后对于 2.1 版本以上的 SonarQube Scanner 就只需要配置 Analysis properties 这一项就可以了,比较常用的参数包括 sonar.projectKey (用来确定 该项目在 SonarQube 中叫什么名字) 和 sonar.sources=(用来指定需要扫描的目录)。

配完之后选择构建即可,可以去当前构建的 Console Output 里面查看有没有报错,正常执行完成的话,在 SonarQube 项目面板中就可以看到一个新增的命名为配置的 sonar.projectKey 的 项目了。

注意点

  • SonarPHP 自定义检查规则需要用 java 来写扩展,比较新的版本内置了 psr2 的规则基本够用,内置的 Quality Profiles 是可以复制一个出来进行自定义的
  • Sonar 嗅探出的一些问题可能实际上并没有什么影响,比如变量名中含有 ‘pwd’ 等,如果原本使用方式确实合理则可适当忽略

GitLab+Jenkins+Rsync+PM2实现Node项目的持续集成与自动部署

前言

最原始的软件开发流程是,在本地搭建好环境,进行开发测试,然后去服务器上搭建环境,手动上传代码,运行测试,然后启动服务。实际上,近些年来出现了很多的工具,使得这些步骤可以自动化,大大降低人工出错的概率,提高生产效率。下面,我就把GitLab+Jenkins+Rsync+PM2实现的Node项目的持续集成以及自动部署的实验过程记录下来。

搭建环境

需要两台服务器作为演示,A主要进行代码管理、构建和分发,B主要运行实际应用。我这边系统使用的是Debian系的。

服务器A

GitLab

准备工作:

apt-get update
apt-get install curl openssh-server ca-certificates postfix

安装postfix的时候,选internet site,之后的 system mail name 填写你的服务器的IP地址。

准备好后开始安装:

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
apt-get install gitlab-ee

如果 apt 下载很慢可以手动下载 https://packages.gitlab.com/gitlab/gitlab-ee/packages/ubuntu/trusty/gitlab-ee_10.2.2-ee.0_amd64.deb 然后用 dpkg -i 的方式安装。装了这个过后 NGINX, Postgres, Redis 就都装好了。

配置:

GitLab默认会占用80、8080和9090端口,Jenkins默认也会使用8080端口,所以将GitLab的默认端口为60200、60201、60202(你可以随意定制)

vim /etc/gitlab/gitlab.rb 修改

external_url 'http://<你的服务器ip>:60200'
unicorn['port'] = 60201
prometheus['listen_address'] = 'localhost:60202'

注意不能有多余空格。gitlab-ctl reconfigure生效配置,gitlab-ctl start启动。
如果要想发邮件的话还要配置第三方邮件 vim /etc/gitlab/gitlab.rb

gitlab_rails['smtp_enable'] = true 
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "***#**"
gitlab_rails['smtp_password'] = "**************"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = :login 
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = "***#**"
user["git_user_email"] = "***#**"

然后生效重启,打开http://<你的服务器IP>:60200访问,

Jenkins

准备工作:

wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz"
tar xzvf jdk-8u151-linux-x64.tar.gz -C /usr/local/  
vim /etc/profile #(加入环境变量)
    export JAVA_HOME=/usr/local/jdk1.8.0_151
    export PATH=$JAVA_HOME/bin:$PATH

退出,source /etc/profile 生效,用 java -version 验证是否装好java。

开始安装:

curl -O http://mirrors.jenkins.io/war-stable/latest/jenkins.war 下载Jenkins,
nohup java -jar jenkins.war –httpPort=60203 & 后台启动并指定端口。
至此,Jenkins安装成功,可以用浏览器打开 http://<你的服务器ip>:60203
然后安装必要的插件(会提示你),依次点击 “系统管理” “管理插件”。
切换到“可选插件”,分别搜索“GitLab Plugin”和“Git Plugin”,然后点击“直接安装”。如果在“可选插件”里没有搜到,可能自带安装了

Node

apt-get update
apt-get install -y build-essential curl
curl -sL https://deb.nodesource.com/setup_8.x | bash 
apt-get install -y nodejs
node -v
v8.9.2
npm -v
5.5.1

Rsync

这个服务器主要使用Rsync来发布文件,所以不需要特殊配置,一般Linux都默认安装了,如果没有,则使用 apt-get install rsync。然后配置Rsync密码

echo "123" >> /etc/rsync.password
chmod -R 600 /etc/rsync.password

服务器B

Node

如A

PM2

npm install -g pm2
pm2 -v
2.8.0

Rsync

为了安全性不要直接使用ssh账号密码或者公钥私钥,而是构建Rsync服务。vim /etc/rsyncd.conf,修改配置,下面的配置只是一个示例,生产环境还要更安全的策略。

##rsyncd.conf start##
uid = root
gid = root
use chroot = yes
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = false
hosts allow = * 
hosts deny =10.0.8.9
auth users = backuser
secrets file = /etc/rsync.password
[webapp]
path = /var/webapp/

上面的的路径path不存在则需要创建 mkdir /var/webapp
echo “backuser:123” >> /etc/rsync.password 添加账号和密码,密码要与客户端(A)一直
chmod -R 600 /etc/rsync.password 修改权限
rsync –daemon 以守护进程方式来启动rsync服务
chkconfig rsync on将此服务设置成为开机自启动

应用开发

用express开发一个 hello world 作为演示,在本地工程目录

npm init #(按照提示输入参数)
npm install express --save  #(安装express)

然后创建app.js

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

node app.js 运行,然后http://localhost:3000/ 会得到 hello world

新建app.json

{
    "apps" : [
        {
            "name"        : "app",
            "script"      : "app.js",
            "log_date_format"  : "YYYY-MM-DD HH:mm:SS",
            "env": {
                "NODE_ENV": "production"
            },
            "watch" : [
                "app.js",
                "router",
                "util"
            ],
            "ignore_watch" : [
                "logs",
                "node_modules",
                "test"
            ]
        }
    ]
}

将代码上传至服务器B,然后 pm2 start app.json 运行 即可在浏览器访问 http://B-ip:3000 得到 hello world

持续集成和自动部署

配置 Gitlab

首次登陆的密码是会提示你去服务器找,用户是root,然后修改你的用户账号信息,添加你自己常用的电脑上的git公钥。
创建一个新项目 webapp ,创建好过后项目会显示该项目对应的用户信息(会提示你修改)

Git global setup

git config --global user.name "MageekChiu"
git config --global user.email "mageekchiu@mail.**.cn"

在本地项目目录下,新建 .gitignore 文件(window 要用 命令行 rename才可以)

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

node_modules/

然后执行

git init
git remote add origin git@A-ip:root/webapp.git
git add .
git commit -m "Initial commit"
git push -u origin master

即可提交服务器仓库,以后每次修改都要

git add .
git commit -m "修改备注"

配置 jenkins

首先配置GitLab插件:

打开GitLab,点击“setting”——“Account”,复制“Private token”,或者应该首先生成personal access token。
打开Jenkins,点击“系统管理”——“系统设置”,点击“配置”下拉框,点击“Gitlab”选项配置GitLab
Connection Name 随便,如 gitlab,“Git Host URL”填GitLab的访问地址,
然后Credentials点“Add”——“jenkins”,在弹出框里,“kind”选择“GitLab API Token”,将先前复制的“Private token”粘贴到“API token”输入框中,然后点击“Add”,添加后,Credentials选择刚刚新建的gitlab,
最后点击“test connection”,看到“Success”就成功了。然后点击页面底下的“apply”,再点击“save”

然后配置Git插件:

需要注意的是装Jenkins的机器上一定要装git: apt-get install git 这样Jenkins才能去 gitlab 拉取文件。
打开Jenkins,点击“系统管理”——“系统设置”,点击“配置”下拉框,选择“Git plugin”选项,设置Git插件的全局配置,填入上面的 global setting 如 global user.name等,然后点击“apply”——“save”

成访问Gitlab的ssh秘钥:

打开GitLab,点击右上角的“setting”—— SSH Keys,就可以进入到添加界面。
在jenkins所在服务器上生成密钥
ssh-keygen -t rsa -C “root@<你服务器的ip地址>” -b 4096
ssh-keygen -t rsa -C “root@” -b 4096
全部按 Enter 使用默认值,这会生成一对公钥和私钥。打开公钥复制到gitlab的添加界面,然后点击“add key”,并记住私钥的存放路径。

创建一个Jenkins Job:

直接点新建,“item name”可以随便起,然后点击“构建一个自由风格的软件项目”,点击“OK”,至此,创建一个Job成功了。然后配置这个job,选择“源码管理”,选择“Git”,然后去GitLab中复制项目地址,粘贴到“Repository URL”,然后点击“credentials”后面的“Add”按钮

在弹出页面里面:
● Kind 选择 SSH Username with private key
● Username 填 root
● PrivateKey 选择 From a file on jenkins master ,然后将服务器的 私钥的存放路径(/root/.ssh/id_rsa ) 粘贴进去
然后点击“Add”,在“credentials”里选择我们刚刚创建的认证方式。如果没报错,说明成功了,点击页面底部的“apply”。如果出错了,会在“Repository URL”和“Credentials”之间显示红色的错误信息。

选择 构建触发器:
选择 Build when a change is pushed to GitLab. 记住这个 GitLab CI Service URL ,点击高级
Secret token 那一行下面 点击 generate。记住这个token
选择 构建:
选择 execute shell

npm install 
WEB_SERVER_IP=B的ip
PROJECT=webapp/
rsync -arqz --delete-before $WORKSPACE/ $WEB_SERVER_IP::$PROJECT --exclude ".git" --password-file=/etc/rsync.password 

这一段代码的主要目的是构建,并分发代码,如果有多个应用服务器就要分发到多个服务器上。

配置gitab的webhook:

点击webapp 项目下面的setting的integrations 输入刚才的 GitLab CI Service URL 和 Secret Token
然后点击add webhook ,再测试一下选择 push events 如果显示Hook executed successfully: HTTP 200 即成功,然后在jenkins里面查看是有一次构建记录的。

这样jenkins就会在代码发生变化时自动拉取代码到本地,构建,然后用rsync分发给各个应用服务器,结合PM2的watch功能实现自动发现代码更新并重启的功能,达到自动部署的目的

最终效果测试

修改代码,把hello world改为hello gitlab+enkins然后 add、commit、push 。在A上面gitlab有提交记录,jenkins有构建记录,在B上面用 pm2 ls 发现项目是restart了,浏览器查看也变成hello gitlab+enkins 了。
尝试成功!
虽然这个配置比较麻烦,但是持续集成和自动部署的带来的好处是更大的:代码有版本管理,可以快速迭代、快速回滚,同时保持高质量、自动多机部署防止人工错误,每次构建都有记录,构建幂等……

后记

这个过程已经比较自动化了,但是还是有太多的环境搭建过程,比如webapp一般都会用到mysql、redis、MongoDB等等,一个更自动化的过程应该引入docker,这方面以后有机会再尝试。

启动jenkins时指定jvm参数

环境

java:1.7
jenkins:2.5
操作系统:win7
服务器:centos6
工具:CRT

场景

今天jenkins用着用着报了以下错误(从日志中查看):

javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-

INF/lib/jenkins-core-2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page', 

exception - java.lang.OutOfMemoryError: PermGen space
        at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103)
        at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
        at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
        at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
        at hudson.init.impl.InstallUncaughtExceptionHandler$1.reportException

(InstallUncaughtExceptionHandler.java:30)
        at org.kohsuke.stapler.compression.CompressionFilter.reportException(CompressionFilter.java:77)
        at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:55)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:499)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
        at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-INF/lib/jenkins-core-

2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page', exception - 

java.lang.OutOfMemoryError: PermGen space
        at org.apache.commons.jelly.impl.TagScript.handleException(TagScript.java:726)
        at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:281)
        at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
        at org.apache.commons.jelly.tags.core.ForEachTag.doTag(ForEachTag.java:150)
        at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
        at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98)
        at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
        at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98)
        at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
        at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
        at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
        at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
        at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
        at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95)
        at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63)
        at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53)
        at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:95)
        ... 29 more
Caused by: java.lang.IllegalArgumentException: Error setting property 'page', exception - 

java.lang.OutOfMemoryError: PermGen space
        at org.apache.commons.beanutils.ConvertingWrapDynaBean.set(ConvertingWrapDynaBean.java:74)
        at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:265)
        ... 44 more
Caused by: java.lang.OutOfMemoryError: PermGen space

十一月 29, 2017 10:45:57 上午 org.eclipse.jetty.util.log.JavaUtilLog warn
警告: Could not send response error 500: javax.servlet.ServletException: 

org.apache.commons.jelly.JellyTagException: jar:file:/home/jenkins/war/WEB-INF/lib/jenkins-core-

2.25.jar!/lib/layout/layout.jelly:83:72: <st:include> Error setting property 'page', exception - 

java.lang.OutOfMemoryError: PermGen space

可以很明显看出是内存溢出;

官网也给出了解决办法:

修改jvm参数

我们先来看看官方是怎么解释(为什么会内存溢出):

As your project grows, and you use new tools to either build or analyze your code, you will inevitably exceed the memory settings which your JVM provides by default. This is especially true on 64 bit JVM’s since they double the size of the reference pointer. This page aims to show you how to increase the memory available to your build process.

上面的意思是:

随着我们项目的增长,和使用新的工具去构建或分析代码,会不可避免的超过jvm提供的默认值。这在64位jvm中尤为明显,因为它们引用的指针大小是翻倍的(相对32位)。接下来将展示如何增加可用于构建过程的内存(通俗点说就是增加 jvm 可用的内存)。

Heap or Permgen

内存溢出分来两种;

官方介绍:

There are two OutOfMemoryErrors which people usually encounter. The first is related to heap space: java.lang.OutOfMemoryError: Heap space When you see this, you need to increase the maximum heap space. You can do this by adding the following to your JVM arguments -Xmx200m where you replace the number 200 with the new heap size in megabytes. 
The second is related to PermGen: java.lang.OutOfMemoryError: PermGen space. When you see this, you need to increase the maximum Permanent Generation space, which is used for things like class files and interned strings. You can do this by adding the following to your JVM arguments -XX:MaxPermSize=128m where you replace the number 128 with the new PermGen size in megabytes.

意思就是:

通常情况下,我们会遇到两种内存溢出的错误。第一种是关于堆溢出:java.lang.OutOfMemoryError: Heap space;当你看到这个错误时,你需要增加堆空间的最大值。你可以添加以下内容作为jvm的参数:-Xmx200m,数字200你可以使用新值替换。比如4096即:-Xmx4096m。
第二种是关于永久代的(java7以后版本会移除永久代):java.lang.OutOfMemoryError: PermGen space。当你看到这个错误时,你需要增加永久代空间的最大值,这个空间是被像 类文件和interned字符串所使用的。你可以添加以下内容作为jvm的参数:-XX:MaxPermSize=128m,数字128你可以使用新值替换。比如512即:-XX:MaxPermSize=512m。

我的改法

很明显我的问题是第二种,所以我需要使用-XX:MaxPermSize=128m这个参数:

我的改法是:

vim /etc/sysconfig/jenkins
# 找到 JENKINS_JAVA_OPTIONS
# JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
# 改为
JENKINS_JAVA_OPTIONS="-XX:MaxPermSize=512m -Djava.awt.headless=true"

保存好后,之后,在重启jenkins。但是呢我启动后,还是报内存溢出,连页面都打不开。看了下进程:

[root@master01 log]# ps -ef | grep jenkins
root       357 45410  0 11:06 pts/4    00:00:00 grep jenkins
root     22293     1  0 Nov13 ?        00:54:21 /usr/java/jdk1.7.0_51/bin/java -cp /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven32-agent-1.12-alpha-1.jar:/home/activemq/apache-maven-3.2.3/boot/plexus-classworlds-2.5.1.jar:/home/activemq/apache-maven-3.2.3/conf/logging jenkins.maven3.agent.Maven32Main /home/activemq/apache-maven-3.2.3 /var/cache/jenkins/war/WEB-INF/lib/remoting-2.62.jar /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven32-interceptor-1.12-alpha-1.jar /home/jenkins/dataspace/plugins/maven-plugin/WEB-INF/lib/maven3-interceptor-commons-1.12-alpha-1.jar 48531
root     24012     1  0 Nov21 ?        01:38:52 /usr/java/jdk1.7.0_51/bin/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/home/jenkins/dataspace -jar /home/jenkins/lib/jenkins.war --logfile=/home/jenkins/log/jenkins.log --webroot=/home/jenkins/war --daemon --httpPort=7080 --ajp13Port=-1 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20

这里我们看到进程id:22293,这个进程估计是我之前启动一个maven job依赖下来的,这个maven项目每次启动都把jenkins直接跑崩了!杀死这个进程后,重启jenkins就可以了

官方的改法

官方的改法都是在jenkins的配置页面中进行修改,我之所没这么做,是因为我jenkins连页面都打不开(因为内存溢出啦)。

maven类型项目

①全局配置:
如果你使用的是Maven2/3项目类型,你可以在jenkins全局配置中设置-Xmx or -XX:MaxPermSize。通过导航(Manage Jenkins -> Configure System),接着找到Maven Project Configuration,在Global MAVEN_OPTS这一栏中添加需要设置的jvm参数并点击保存。随后的Maven2/3 job构建将会使用新的设置。

②项目设置:
这个设置是针对每个job的。首先在job页面中点击configure按钮,接着找打Build部分并点击advanced,接着在MAVEN_OPTS这个选项中设置相关参数。

Freestyle projects with Maven Build Steps

如果你有一个自由式项目并使用Invoke Top Level Maven Targets构建步骤,你可以点击高级按钮,在JVM Options这一栏添加jvm参数。

另外,可以在jenkins全局配置,通过添加MAVEN_OPTS全局变量来影响所有自由风格maven的构建步骤。具体配置路径:先点击Manage Jenkins,接着Configure System,在Global properties这一栏中,勾选Environment Variables复选框,接着添加一个新的名为MAVEN_OPTS的环境变量,并设置一个合适的值:

未分类

Gradle build steps

这里同理上面,可以在系统设置中添加全局变量

Ant build steps

对于Ant 步骤,其没有全局环境变量,你必须在每个单独的构建步骤中设置Ant选项。在构建的设置中,找到Invoke Ant步骤,点击高级按钮,Java Options这一栏输入参数。

参考地址:
https://wiki.jenkins.io/display/JENKINS/Builds+failing+with+OutOfMemoryErrors

持续集成CI实施指南一–搭建Jenkins

一、 关于持续集成

1.1 什么是持续集成

持续集成, 简称CI(continuous integration).是一种软件开发实践,即团队开发成员经常集成他们的工作,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
传统瀑布模型(水平划分项目阶段):

未分类

敏捷开发与CI模型(垂直划分项目阶段):

未分类

1.2 为什么要持续集成

  • 保证质量:CI是敏捷开发重要的一步,其目的在于让产品快速迭代的同时,尽可能保持高质量
  • 减少风险:CI讲求开发、部署、测试100%通过,通过多次集成,便于检查错误
  • 较少重复过程:自动化的构建、部署与测试节省重复工作,让团队能集中精力去做更重要的事
  • 增强项目可见性:每一次集成不论成功或失败,都能获得数据和信息供团队分析与决策
  • 增强团队协作:团队成员能清楚知道每一次提交代码后产生的影响,成员之间需要更密切的沟通来保证集成成功

二、 搭建Jenkins

2.1 什么是jenkins

Jenkins是一款用Java编写的开源的持续集成工具,是目前使用范围最广的CI工具。他长这样:

未分类

2.2 Jenkins for Docker

上文也说到Jenkins使用Java编写,所以支持跨平台。详细的介绍和安装说明可以查看官网: https://jenkins.io/

我们这里用到另一种方式,Jenkins for Docker. 这种方式在使用上更为轻量,不用在服务器上安装JDK,甚至不需要去研究如何安装Jenkins. 另外通过编写Dockerfile,能定制出符合我们需求的Jenkins配置,同时能够方便的复用和迁移。

2.2.1 准备工作

  • 需要一台装有Docker的宿主机(必要)

  • 需要一些Docker的基础知识与常用命令(必要)

  • docker宿主机设置代理(非必要)

创建代理配置文件

mkdir -p /etc/systemd/system/docker.service.d
vi /etc/systemd/system/docker.service.d/http-proxy.conf

内容填写参考如下

[Service]
Environment="HTTP_PROXY=http://192.168.2.100:1080/" "HTTPS_PROXY=https://192.168.2.100:1080/" "NO_PROXY=localhost,127.0.0.1"

表示使用192.168.2.100:1080作为代理,且localhost不走代理

更新配置

systemctl daemon-reload

重启Docker

systemctl restart docker

2.2.2 拉取Jenkins for Docker

  • 宿主机执行命令拉取Jenkins的Docker Image
docker pull jenkins

这个镜像体积不小,约800M,由于受国内网络环境影响,下载可能很慢,如果需要给docker设置代理请参考2.2.1 “docker宿主机设置代理”

  • 查看Jenkins镜像
docker images

未分类

到这里已经可以使用jenkins了,但我们还需做一些定制,比如给Jenkins镜像安装Nodejs、dotnet Core SDK等

2.2.3 通过Dockerfile定制jenkins

  • 根据需要编写Dockerfile
MAINTAINER wurang
USER root
# 将 shell 替换为 bash
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# 设置中科大软件镜像源
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN sed -i 's|security.debian.org|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
# upgrade
RUN apt-get update && apt-get upgrade -y && apt-get install -y apt-utils sudo     
# 安装必要软件包
RUN apt-get install -y build-essential curl libunwind8 gettext apt-transport-https
# 安装dotnet core 2.0
RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg 
&& mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg 
&& sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/dotnetdev.list' 
&& apt-get update && apt-get install -y dotnet-sdk-2.0.0  
# 安装nodejs
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - && apt-get install -y nodejs
# 安装cnpm
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
# 清理缓存
RUN apt-get clean && apt-get autoclean
# 解决时区问题
RUN rm -f /etc/localtime && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
ENV JAVA_OPTS=-Duser.timezone=Asia/Shanghai 
USER jenkins
  • 生成定制镜像
docker build -t auto-jenkins .
  • 查看镜像
docker images

未分类

auto-jenkins即为通过Dockerfile生成的定制镜像

2.2.4 使用Jenkins for Docker

运行Jenkins容器

docker run --name myjenkins -p 8081:8080 -p 50000:50000 -v jenkins:/var/jenkins_home auto-jenkins
  • –name myjenkins 表示为运行的docker容器命名myjenkins

  • -p 8081:8080 将Jenkins容器的8080端口映射至宿主机的8081端口,必须映射容器的8080端口到宿主机,考虑到宿主机8080端口可能被占用,所以这里映射到了8081端口,记住这个端口将用于对Jenkins的访问

  • -p 50000:50000 将Jenkins容器的50000端口映射至宿主机的50000端口,必须映射容器的50000端口到宿主机

  • -v jenkins:/var/jenkins_home 将Jenkins容器的home目录作为卷挂载到宿主机 /var/lib/docker/volumes/jenkins 目录,jenkins容器的所有配置、工作信息都会存放在这里。也可以挂载到宿主机的其他目录,不过需要注意权限问题

  • auto-jenkins 表示从我们创建的名为auto-jenkins的镜像启动容器

  • 访问Jenkins

启动容器后,可以看到如下所示的信息,记住红框内的密钥信息

未分类

启动完成后就可以通过访问宿主机IP+容器8080的映射端口来访问Jenkins了,如通过上面的配置,我们可以访问 http://XXXX:8081

未分类

这里需要填入刚才记住的密钥,如果忘记了,可以在宿主机的挂载卷内找到

cat /var/lib/docker/volumes/jenkins/_data/secrets/initialAdminPassword

然后安装推荐插件

未分类

未分类

设置管理员账号

未分类

  • 开机自动运行容器

最后不要忘了给宿主机设置开机启动Jenkins容器,可添加下面的开机脚本命令

docker start myjenkins

2.2.4 如何复用与迁移

如果需要迁移整套jenkins或者在其他服务器复用,可以按照下面的步骤:

  • 新服务器安装Docker

  • 新服务器拉取Jenkins Image

  • 拷贝之前编写好的Dockerfile到新服务器,运行build脚本创建auto-jenkins镜像

  • 运行容器

  • 访问Jenkins

  • 拷贝旧服务器的挂载卷 /var/lib/docker/volumes/jenkins 到新服务器对应位置(迁移则需要这一步,复用不需要)

2.3 如何升级Jenkins

初次访问Jenkins for Docker,一般会遇到升级提示

未分类

升级步骤如下:

  • 右键”download”获取更新包地址

  • 进入jenkins容器

docker exec -it -u root myjenkins /bin/bash

执行命令

cd /usr/share/jenkins/ # 进入jenkins目录 
mkdir bak # 创建备份文件夹 
mv jenkins.war bak/jenkins.war.bak  # 备份war包
wget http://updates.jenkins-ci.org/download/war/2.73.2/jenkins.war # 下载更新包,地址为第一步获取的更新地址
  • 重启jenkins

访问jenkins_url/restart 如 “http://XXXX:8081/restart” 重启jenkins

docker中Jenkins容器启动失败

今天在docker中启动jenkins容器时,按照官方文档中的方法执行:

docker run -p 8080:8080 -p 50000:50000 -v /your/home:/var/jenkins_home jenkins

遇到了一个权限为题,报错为:

Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied

原因是Jenkins镜像内部使用的用户是jenkons,但是我们启动容器时的账号是root,导致没有权限操作内部目录,我们可以稍微改一下上面的命令:

docker run -p 8080:8080 -p 50000:50000 -v /your/home:/var/jenkins_home -u 0 jenkins

这样就启动成功了。

这命令的意思是覆盖容器中内置的帐号,该用外部传入,这里传入0代表的是root帐号Id。这样再启动的时候就应该没问题了。

Jenkins的使用(一)—安装

Jenkins是什么

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

功能

持续的软件版本发布/测试项目。
监控外部调用执行的工作。

在CentOS7.0中安装Jenkins

安装Jenkins最新版本

添加Jenkins的yum源到系统中,并安装

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
yum install jenkins

安装jenkins标准版本

添加Jenkins的标准版yum源到系统中,并安装

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
yum install jenkins

安装JAVA

java环境采用openjdk1.7版本以上

yum install java

Jenkins的启动停止

service jenkins start/stop/restart
chkconfig jenkins on

NOTE: 如果有如下错误信息,请确认JAVA是否安装

Starting jenkins (via systemctl): Job for jenkins.service failed. See ‘systemctl status jenkins.service’ and ‘journalctl -xn’ for details. 
[FAILED]

该安装包都做了哪些工作

  • Jenkins做为守护进程在后台启动,启动脚本路径 /etc/init.d/jenkins
  • 创建了‘jenkins’用户用来运行该服务,如果更改该用户为别的用户,则必须更改/var/log/jenkins, /var/lib/jenkins, and /var/cache/jenkins的授权
  • 日志文件路径/var/log/jenkins/jenkins.log
  • 启动时的配置参数文件/etc/sysconfig/jenkins
  • 默认监听端口 8080
  • Jenkins RPM Repository /etc/yum.repos.d/jenkins.repo

开启防火墙规则

firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload
firewall-cmd --list-all

禁用SELinux

setenforce 0
vi /etc/sysconfig/selinux 
SELINUX=disabled

访问URL

http://ServerIP:8080/