赞
踩
Jenkins 是一个开源的持续集成(Continuous Integration)工具,它可以帮助开发团队自动化构建、测试和部署应用程序。以下是使用 Jenkins 进行持续集成的一般步骤:
Jenkins官网: http://jenkins-ci.org/
yum -y install policycoreutils policycoreutils-python openssh-server openssh-clients postfix
systemctl enable sshd && sudo systemctl start sshd
systemctl enable postfix && systemctl start postfix
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-14.6.0-ce.0.el7.x86_64.rpm --no-check-certificate
rpm -i gitlab-ce-14.6.0-ce.0.el7.x86_64.rpm
vim /etc/gitlab/gitlab.rb
# 修改gitlab访问地址和端口,默认为80,我们改为82
external_url 'http://192.168.1.22:82'
nginx['listen_port'] = 82
gitlab-ctl reconfigure
gitlab-ctl restart
--重载配置后控制台会打印如下信息
Username: root 管理员账号
Password: You didn't opt-in to print initial root password to STDOUT.
Password stored to /etc/gitlab/initial_root_password. 初始密码所在文件
--拿到初始密码
cat /etc/gitlab/initial_root_password
Password: 7UgjZYA9VYEbGzp83FZdAbw/7RwxZuy7rGpIKQ08H9w=
firewall-cmd --zone=public --add-port=82/tcp --permanent
firewall-cmd --reload
访问gitlab:http://192.168.1.22:82/
输入管理员账号root,密码7UgjZYA9VYEbGzp83FZdAbw/7RwxZuy7rGpIKQ08H9w=,登录即可。
修改管理员账号密码
默认的管理员账号密码24小时后会失效,需要自己重置。
访问:http://192.168.1.22:82/admin/users/root/edit 页面修改账号root的密码。
创建好用户后为新增的用户设置密码:
Gitlab用户在组里面有5种不同权限:
Guest:可以创建issue、发表评论,不能读写版本库。
Reporter:可以克隆代码,不能提交,QA、PM可以赋予这个权限。
Developer:可以克隆代码、开发、提交、push,普通开发可以赋予这个权限。
Maintainer:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心开发可以赋予这个权限。
Owner:可以设置项目访问权限 - Visibility Level、删除项目、迁移项目、管理组成员,开发组组长可以赋予这个权限。
Jenkins需要依赖JDK,所以先安装JDK1.8。
tar -zxvf jdk-8u171-linux-x64.tar.gz -C /opt/install/
# /opt/install/jdk1.8.0_171/bin/java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
yum -y install epel-release
yum -y install daemonize
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.319.1-1.1.noarch.rpm
rpm -ivh jenkins-2.319.1-1.1.noarch.rpm
vim /etc/sysconfig/jenkins
# jdk目录
JENKINS_JAVA_CMD=/opt/install/jdk1.8.0_171/bin/java
#jenkins用户
JENKINS_USER="root"
#jenkins端口
JENKINS_PORT="8888"
# systemctl start jenkins
# systemctl status jenkins
● jenkins.service - LSB: Jenkins Automation Server
Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
Active: active (running) since Thu 2022-01-06 16:33:56 CST; 31s ago
firewall-cmd --zone=public --add-port=8888/tcp --permanent
firewall-cmd --reload
# cat /var/lib/jenkins/secrets/initialAdminPassword
d59cfa55bd8f4e39ac91ef1aa26effa3
添加第一个管理员账号
Jenkins准备就绪了
Jenkins本身不提供很多功能,我们可以通过使用插件来满足我们的使用。例如从Gitlab拉取代码,使用Maven构建项目等功能需要依靠插件完成。接下来演示如何下载插件。
jenkins插件默认下载地址:https://updates.jenkins-ci.org/download/plugins
jenkins插件默认存储目录:/var/lib/jenkins/plugins
cd /var/lib/jenkins/updates
sed -i 's/http:\/\/updates.jenkinsci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
(3)点击Advanced,把Update Site改为国内插件下载地址。
默认地址:https://updates.jenkins.io/update-center.json
国内插件下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
(4)Sumbit后,浏览器访问 http://192.168.1.25:8888/restart 重启Jenkins。
(2)重启后就看到Jenkins汉化了!(PS:但可能部分菜单汉化会失败)。
我们可以利用 Role-based Authorization Strategy 插件来管理Jenkins用户权限。
baseRole:该角色为全局角色。这个角色需要绑定Overall(全部)下面的Read权限,是为了给所有用户绑
定最基本的Jenkins访问权限。注意:如果不给后续用户绑定这个角色,会报错误:用户名 is
missing the Overall/Read permission。
role1:该角色为项目角色。使用正则表达式绑定 itcast.,意思是只能操作itcast开头的项目。
role2:该角色也为项目角色。绑定 itheima.,意思是只能操作itheima开头的项目。
lisi 用户分别绑定baseRole和role1角色。
wangwu 用户分别绑定baseRole和role2角色。
(2)lisi账号只能看到项目itcast01。
(3)wangwu账号只能看到项目itheima01。
凭据可以用来存储需要密文保护的数据库密码、Gitlab密码信息、Docker私有仓库密码等,以便Jenkins可以和这些第三方的应用进行交互。
接下来以使用Git工具到Gitlab拉取项目源码为例,演示Jenkins如何管理Gitlab的凭证。
Jenkins上安装 Git 插件
在Jenkins机器上安装 Git 工具
# yum install git -y
# git --version
git version 1.8.3.1
(2)立即构建。
(3)构建完成后查看 控制台输出。
(4)到 Jenkins 机器上查看,发现已经从Gitlab成功拉取了代码到Jenkins中。
# cd /var/lib/jenkins/workspace/test01
# ll
total 20
-rw-r--r--. 1 root root 2636 Dec 14 22:05 email.html
-rw-r--r--. 1 root root 1374 Dec 14 22:05 Jenkinsfile
-rw-r--r--. 1 root root 625 Dec 14 22:05 pom.xml
-rw-r--r--. 1 root root 579 Dec 14 22:05 sonar-project.properties
drwxr-xr-x. 3 root root 17 Dec 14 22:05 src
-rw-r--r--. 1 root root 1499 Dec 14 22:05 web_demo.iml
SSH免密登录示意图
# ssh-keygen -t rsa
# cd /root/.ssh/
# ll
-rw-------. 1 root root 1675 Dec 15 10:52 id_rsa 私钥
-rw-r--r--. 1 root root 394 Dec 15 10:52 id_rsa.pub 公钥
把公钥放在Gitlab中
以root账户登录 Gitlab -> 点击头像 -> Settings -> SSH Keys。把文件id_rsa.pub的内容粘贴进去。
在Jenkins中添加私钥为凭证
系统管理 -> Manage Credentials。
测试凭证是否可用
(1)新建任务 -> 输入一个任务名称 -> 源码管理。
(2)立即构建。
(3)构建完成后查看 控制台输出。
(4)到 Jenkins 机器上查看,发现已经从Gitlab成功拉取了代码到Jenkins中。
# cd /var/lib/jenkins/workspace/test02
# ll
total 20
-rw-r--r--. 1 root root 2636 Dec 15 10:57 email.html
-rw-r--r--. 1 root root 1374 Dec 15 10:57 Jenkinsfile
-rw-r--r--. 1 root root 625 Dec 15 10:57 pom.xml
-rw-r--r--. 1 root root 579 Dec 15 10:57 sonar-project.properties
drwxr-xr-x. 3 root root 17 Dec 15 10:57 src
-rw-r--r--. 1 root root 1499 Dec 15 10:57 web_demo.iml
在Jenkins集成服务器上,我们需要安装Maven来编译和打包项目。
wget https://dlcdn.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz tar -xzf apache-maven-3.8.4-bin.tar.gz -C /opt/install cd /opt/install/apache-maven-3.8.4/ # pwd /opt/install/apache-maven-3.8.4 --配置环境变量 # vim /etc/profile export JAVA_HOME=/opt/install/jdk1.8.0_171 export PATH=$PATH:$JAVA_HOME/bin export MAVEN_HOME=/opt/install/apache-maven-3.8.4 export PATH=$PATH:$MAVEN_HOME/bin # source /etc/profile # mvn -v Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537) Maven home: /opt/install/apache-maven-3.8.4 Java version: 1.8.0_171, vendor: Oracle Corporation, runtime: /opt/install/jdk1.8.0_171/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "3.10.0-1160.49.1.el7.x86_64", arch: "amd64", family: "unix" --修改本地仓库目录为/opt/install/apache-maven-3.8.4/repo # vim /opt/install/apache-maven-3.8.4/conf/settings.xml <localRepository>/opt/install/apache-maven-3.8.4/repo</localRepository>
(2)系统管理 -> 全局工具配置 -> Maven -> 新增Maven。
添加Jenkins全局变量
系统管理 -> 系统配置 -> 全局属性 -> 环境变量。
测试Maven是否配置成功
在Jenkins上随便找之前好的一个任务,比如 test02。
再次构建,控制台看到把项目打成 war,代码Maven配置成功。
大致流程说明:
1)开发人员每天把代码提交到Gitlab代码仓库。
2)Jenkins从Gitlab中拉取项目源码,编译并打成jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库。
3)Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器。
4)最后,用户可以访问到容器。
yum list installed | grep docker
yum -y remove docker的包名称
--删除docker的所有镜像和容器
rm -rf /var/lib/docker
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 18.06.3.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.2.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.03.1.ce-1.el7.centos docker-ce-stable
yum install docker-ce-18.06.3.ce
# docker -v
Docker version 18.06.3-ce, build d7080c1
# systemctl start docker
# systemctl enable docker
# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running)
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"]
}
# systemctl restart docker
# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running)
下面演示利用Dockerfile制作一个Eureka注册中心的镜像。
# vim Dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} /target/tensquare-eureka-server-1.0-SNAPSHOT.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/target/tensquare-eureka-server-1.0-SNAPSHOT.jar"]
docker build --build-arg JAR_FILE=tensquare-eureka-server-1.0-SNAPSHOT.jar -t tensquare-eureka-server:v1.0 .
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tensquare-eureka-server v1.0 70b977ee0289 35 seconds ago 150MB
docker run -i --name=tensquare-eureka-server -p 10086:10086 tensquare-eureka-server:v1.0
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# docker-compose -version
docker-compose version 1.21.2, build a133471
wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz
tar -xzf harbor-offline-installer-v2.4.1.tgz -C /opt/install
cd /opt/install/harbor/
cp harbor.yml.tmpl harbor.yml
# vim harbor.yml
hostname: 192.168.1.29
port: 85
--将https的都注释掉
#https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
./prepare
./install.sh
--启动。 ps. 如果下面的命令启动失败则用该命令 docker-compose -f /opt/install/harbor/harbor.yml up -d 启动
docker-compose up -d
--停止
docker-compose stop
--重启
docker-compose restart
Harbor的项目分为公开和私有的:
公开项目:所有用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
私有项目:只有授权用户才可以访问,通常存放项目本身的镜像。
创建用户harborZhangsan/harborZhang3
给私有项目分配用户
角色 | 权限说明 |
---|---|
访客 | 对于指定项目拥有只读权限 |
开发人员 | 对于指定项目拥有读写权限 |
维护人员 | 对于指定项目拥有读写权限,创建 Webhooks |
项目管理员 | 除了读写权限,同时拥有用户管理/镜像扫描等管理权限 |
1. 在production-server机器上完成下面步骤 (1) 把Harbor地址加入到Docker信任列表 # vim /etc/docker/daemon.json { "registry-mirrors":[ "https://zydiol88.mirror.aliyuncs.com" ], "insecure-registries":[ "192.168.1.29:85" --这个是harbor地址 ] } (2) 重启docker systemctl restart docker (3) 登录Harbor docker login -u harbor账号 -p harbor密码 192.168.1.29:85 (4) 给需要上传到Harbor的镜像打标签 --查看当前机器有哪些镜像 # docker images REPOSITORY TAG IMAGE ID CREATED SIZE tensquare-eureka-server v1.0 b82ccd24a80b About an hour ago 150MB --给 tensquare-eureka-server 镜像打标签 docker tag tensquare-eureka-server:v1.0 192.168.1.29:85/tensquare/tensquare-eureka-server:v1.0 (5) 推送镜像到Harbor docker push 192.168.1.29:85/tensquare/tensquare-eureka-server:v1.0
下面演示从Harbor上下载镜像。
(1) 安装Docker,并启动Docker (2) 把Harbor地址加入到Docker信任列表 # vim /etc/docker/daemon.json { "registry-mirrors":[ "https://zydiol88.mirror.aliyuncs.com" ], "insecure-registries":[ "192.168.1.29:85" --这个是harbor地址 ] } (3) 重启docker systemctl restart docker (4) 登录Harbor docker login -u harbor账号 -p harbor密码 192.168.1.29:85
docker pull 192.168.1.29:85/tensquare/tensquare-eureka-server@sha256:f8e52604958377d7934d3f211d0537df2fbd41a085e7f48673f963ce03b82a54
或者如下拉取:
docker pull 192.168.1.29:85/tensquare/tensquare-eureka-server:v1.0
(1) 安装必要环境 yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel (2) 解压并安装 tar -zxvf nginx-1.20.2.tar.gz -C /opt/install/ cd /opt/install/nginx-1.20.2 ./configure make make install --采用默认的配置安装,则启动命令在/usr/local/nginx/sbin # cd /usr/local/nginx/sbin # ./nginx -v nginx version: nginx/1.20.2 --启动 # ./nginx --停止 # ./nginx -s stop --退出 # ./nginx -s quit --重启 # ./nginx -s reload --查看是否启动了 # ps -ef | grep nginx root 11112 1 0 23:30 ? 00:00:00 nginx: master process ./nginx nobody 11113 11112 0 23:30 ? 00:00:00 nginx: worker process root 11115 8395 0 23:30 pts/0 00:00:00 grep --color=auto nginx
在Jenkins创建流水线项目tensquare-parent
指定Jenkinsfile脚本位置
添加项目参数project_name
添加分支参数
生成Harbor凭证脚本代码
withCredentials([usernamePassword(credentialsId: '0d458918-e2ea-4b51-8250-91c3731be288', passwordVariable: 'password', usernameVariable: 'username')]) {
// some block
}
--在jenkins机器执行下面命令,将公钥复制到 192.168.1.30(production-server)
ssh-copy-id 192.168.1.30
(2)系统管理 -> 系统配置 -> Publish over SSH。
sshPublisher(publishers: [sshPublisherDesc(configName: 'production-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
//gitlab凭证ID def git_auth = "e4e02eb6-f6bb-4040-b842-c1423c397493" //gitlab的url地址 def git_url = "git@gitlab.master.com:itheima_group/tensquare-parent.git" //镜像的版本号 def tag = "latest" //Harbor的url地址 def harbor_url = "reg.myharbor.com:85" //harbor镜像库项目名称 def harbor_project_name = "tensquare" //Harbor的登录凭证ID def harbor_auth = "0d458918-e2ea-4b51-8250-91c3731be288" node { stage('拉取代码') { checkout([$class : 'GitSCM', branches: [[name: '*/${branch}']] , doGenerateSubmoduleConfigurations: false , extensions : [] , submoduleCfg : [] , userRemoteConfigs : [ [credentialsId: "${git_auth}", url: "${git_url}"] ]]) } stage('代码审查') { //定义当前Jenkins的SonarQubeScanner工具 def scannerHome = tool 'sonarqube-scanner' //引用当前JenkinsSonarQube环境 withSonarQubeEnv('sonarqube-8.9.6.50800') { sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """ } } stage('编译/构建镜像') { //定义镜像名称 def imageName = "${project_name}:${tag}" //编译,安装公共工程 sh "mvn -f tensquare-common clean install" //编译,构建本地镜像 sh "mvn -f ${project_name} clean package dockerfile:build" //给镜像打标签 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登录harbor并上传镜像 withCredentials([ usernamePassword(credentialsId: "${harbor_auth}" , passwordVariable: 'password' , usernameVariable: 'username')]) { //登录Harbor sh "docker login -u ${username} -p ${password} ${harbor_url}" //推送镜像到Harbor sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //上传完成后删除本地镜像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" } stage('部署服务') { sshPublisher( publishers: [ sshPublisherDesc( configName: 'production-server' , transfers: [ sshTransfer( cleanRemote: false , excludes: '' , execCommand: "/opt/jenkins_shell/tensquare/deploy.sh $harbor_url $harbor_project_name $project_name $tag $port" , execTimeout: 120000 , flatten: false , makeEmptyDirs: false , noDefaultExcludes: false , patternSeparator: '[, ]+' , remoteDirectory: '' , remoteDirectorySDF: false , removePrefix: '' , sourceFiles: '' )] , usePromotionTimestamp: false , useWorkspaceInPromotion: false , verbose: false) ]) } }
#!/bin/sh #接收外部参数 harbor_url=$1 harbor_project_name=$2 project_name=$3 tag=$4 port=$5 imageName=$harbor_url/$harbor_project_name/$project_name:$tag echo "$imageName" #查询容器是否存在,存在则删除 containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'` if [ "$containerId" != "" ] ; then #停掉容器 docker stop $containerId #删除容器 docker rm $containerId echo "成功删除容器" fi #查询镜像是否存在,存在则删除 imageId=`docker images | grep -w $project_name | awk '{print $3}'` if [ "$imageId" != "" ] ; then #删除镜像 docker rmi -f $imageId echo "成功删除镜像"JAR_FILE fi # 登录Harbor私服 docker login -u harborZhangsan -p harborZhang3 $harbor_url # 下载镜像 docker pull $imageName # 启动容器 docker run -di -p $port:$port $imageName echo "容器启动成功"
(2)给该脚本执行权限。
chmod +x deploy.sh
3.为每个微服务项目编写各自的sonar-project.properties文件
下面是微服务项目 tensquare-eureka-server 的一个例子,记得到Harbor上创建对应的项目哦。
# must be unique in a given SonarQube instance sonar.projectKey=tensquare-eureka-server # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. sonar.projectName=tensquare-eureka-server sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # This property is optional if sonar.modules is set. sonar.sources=. sonar.exclusions=**/test/**,**/target/** sonar.java.binaries=. sonar.java.source=1.8 sonar.java.target=1.8 #sonar.java.libraries=**/target/classes/** # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8
4.为每个微服务项目编写各自的Dockerfile文件
(1)每个微服务项目的pom.xml添加如下插件。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <repository>${project.artifactId}</repository> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
(2)tensquare-eureka-server 微服务的Dockerfile文件示例。
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086 --注意每个微服务项目的端口都不一样
ENTRYPOINT ["java","-jar","/app.jar"]
生产部署服务器 production-server 已经安装了Nginx
2. Jenkins上安装NodeJS插件
3. Jenkins配置NodeJS服务器
Manage Jenkins(系统管理) -> Global Tool Configuration(全局工具配置) -> NodeJS。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。