基于Jenkins+K8S构建DevOps自动化运维管理平台

目录

1.k8s助力DevOps在企业落地实践

[1.1 传统方式部署项目为什么发布慢,效率低?](#1.1 传统方式部署项目为什么发布慢,效率低?)

[1.2 上线一个功能,有多少时间被浪费了?](#1.2 上线一个功能,有多少时间被浪费了?)

[1.3 如何解决发布慢,效率低的问题呢?](#1.3 如何解决发布慢,效率低的问题呢?)

[1.5 什么是DevOps?](#1.5 什么是DevOps?)

[1.5.1 敏捷开发](#1.5.1 敏捷开发)

[1.5.2 持续集成(CI)](#1.5.2 持续集成(CI))

[1.5.3 持续交付](#1.5.3 持续交付)

[1.5.4 持续部署](#1.5.4 持续部署)

2.为什么大厂都在用DevOps?

[2.1 神州泰岳DevOps生态体系建设与实践-神州泰岳云资源运营事业部经理张凯分享](#2.1 神州泰岳DevOps生态体系建设与实践-神州泰岳云资源运营事业部经理张凯分享)

[2.2 DevOps在金融行业的应用-张安全分享](#2.2 DevOps在金融行业的应用-张安全分享)

[2.3 哪些企业在用DevOps?](#2.3 哪些企业在用DevOps?)

[2.4 DevOps在5G领域的的展望](#2.4 DevOps在5G领域的的展望)

3.K8S在DevOps中的核心作用

[3.1 自动化](#3.1 自动化)

[3.2 多集群管理](#3.2 多集群管理)

[3.3 多环境一致性](#3.3 多环境一致性)

[3.4 实时反馈和智能化报表](#3.4 实时反馈和智能化报表)

4.基于Jenkins+K8S+harbor+git等技术链助力DevOps在企业落地实践

[4.1 神州泰岳k8s+DevOps+微服务生态体系建设与实践](#4.1 神州泰岳k8s+DevOps+微服务生态体系建设与实践)

[4.2 百度:基于k8s构建亿级PV流量的DevOps平台](#4.2 百度:基于k8s构建亿级PV流量的DevOps平台)

[4.3 发布应用到测试环境](#4.3 发布应用到测试环境)

[4.5 整个DevOps流程图](#4.5 整个DevOps流程图)

5.基于Jenkins+k8s+Git+DockerHub等技术链构建企业级DevOps容器云平台

[5.1 安装Jenkins](#5.1 安装Jenkins)

[5.1.1 安装nfs服务,可以选择自己的任意一台机器,我选择的是k8s的控制节点xianchaomaster1](#5.1.1 安装nfs服务,可以选择自己的任意一台机器,我选择的是k8s的控制节点xianchaomaster1)

[5.1.2 在kubernetes中部署jenkins](#5.1.2 在kubernetes中部署jenkins)

[5.2 配置Jenkins](#5.2 配置Jenkins)

[5.2.1 获取管理员密码](#5.2.1 获取管理员密码)

[5.2.2 安装插件](#5.2.2 安装插件)

[5.3 测试jenkins的CI/CD](#5.3 测试jenkins的CI/CD)

[5.3.1 在Jenkins中安装kubernetes插件](#5.3.1 在Jenkins中安装kubernetes插件)

[5.3.2 配置jenkins连接到我们存在的k8s集群](#5.3.2 配置jenkins连接到我们存在的k8s集群)

[5.3.3 配置pod-template](#5.3.3 配置pod-template)

[5.3.4 添加自己的dockerhub凭据](#5.3.4 添加自己的dockerhub凭据)

[5.3.5 测试通过Jenkins部署应用发布到k8s开发环境、测试环境、生产环境](#5.3.5 测试通过Jenkins部署应用发布到k8s开发环境、测试环境、生产环境)

[6. 基于Jenkins+k8s+Git+harbor构建DevOps容器云平台](#6. 基于Jenkins+k8s+Git+harbor构建DevOps容器云平台)

Jenkins实现k8s应用按照指定版本回滚

[7. Jenkins Pipeline语法介绍](#7. Jenkins Pipeline语法介绍)

[7.1 Jenkins Pipeline介绍](#7.1 Jenkins Pipeline介绍)

[7.2 为什么用Jenkins Pipeline?](#7.2 为什么用Jenkins Pipeline?)

[7.3 Jenkins pipeline 入门](#7.3 Jenkins pipeline 入门)

[7.4 Pipeline 声明式语法Declarative](#7.4 Pipeline 声明式语法Declarative)

[7.4.1 environment](#7.4.1 environment)

[7.4.2 options](#7.4.2 options)

[7.4.3 parameters](#7.4.3 parameters)

[7.4.4 triggers](#7.4.4 triggers)

[7.4.5 tools](#7.4.5 tools)

[7.4.6 input](#7.4.6 input)

[7.4.7 when](#7.4.7 when)

[7.4.8 Parallel](#7.4.8 Parallel)

[7.5 Pipeline Scripted语法](#7.5 Pipeline Scripted语法)

1.流程控制

[2.Declarative pipeline和Scripted pipeline的比较](#2.Declarative pipeline和Scripted pipeline的比较)

8、jenkins+k8s+harbor实现DevOps

9、Jenkins接入Sonarqube

10、Jenkins+k8s+nexus+gitlab+harbor+sonarqube+springloud构建DevOps

[11.1 安装sonarqube](#11.1 安装sonarqube)

[11.2 Jenkins界面添加harbor凭据](#11.2 Jenkins界面添加harbor凭据)

[11.3 安装nexus](#11.3 安装nexus)

[11.4 安装gitlab](#11.4 安装gitlab)

[11.5 Jenkins+k8s+nexus+sonarqube+harbor+gitlab构建DevOps](#11.5 Jenkins+k8s+nexus+sonarqube+harbor+gitlab构建DevOps)


文档中的YAML文件配置直接复制粘贴可能存在格式错误,故实验中所需要的YAML文件以及本地包均打包至网盘

链接:https://pan.baidu.com/s/1x0J-1cIq-RN7Yyak6JZJ_Q

提取码:vqh5

1. k8s助力DevOps在企业落地实践

1 .1 传统方式部署项目为什么发布慢,效率低?

1 .2 上线一个功能,有多少时间被浪费了?

1 .3 如何解决发布慢,效率低的问题呢?

1 .5 什么是DevOps?

1.5.1 敏捷开发

提高开发效率,及时跟进用户需求,缩短开发周期。

敏捷开发包括编写代码和构建代码两个阶段,可以使用git或者svn来管理代码,用maven对代码进行构建

1.5.2 持续集成(CI)

持续集成强调开发人员提交了新代码之后,立刻自动的进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果,对可能出现的一些问题进行预警,以保障最终合并的代码没有问题。

常见的持续集成工具:

1. Jenkins

Jenkins是用Java语言编写的,是目前使用最多和最受欢迎的持续集成工具, 使用Jenkins,可以 自动监测到 git 或者svn 存储库 代码的更新,基于最新的代码进行构建 把构建好的源码或者镜像发布到生产环境。 Jenkins还有个非常好的功能 它可以在多台机器上进行分布式地构建和负载测试

2. TeamCity

3. Travis CI

4. Go CD

5. Bamboo

6. GitLab CI

7. Codeship

它的好处主要有 以下几点:

1)较早的发现错误: 每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,哪个环节出现问题都可以较早的发现

2 )快速 发现错误 每完成 一部分代码的 更新,就 会把代码 集成到主干 这样就 可以快速 发现错误 ,比较容易的定位错误

3)提升团队绩效: 持续集成中代码更新速度快,能及时发现小问题并进行修改,使团队能创造出更好的产品

4 )防止分支 过多的 偏离主干 经常 持续 集成, 会使分支代码经常向主干更新, 当单元测试失败或者出现bug,如果开发者需要在没有调试的情况下恢复仓库的代码到没有bug的状态,只有很小部分的代码会丢失

持续集成的目的 是提高代码质量,让产品快速的更新迭代 它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。

Martin Fowler说过,"持续集成并不能消除Bug,而是让它们非常容易发现和改正。"

互动: Martin Fowler 是谁?

马丁·福勒

马丁·福勒是一个软件开发方面的著作者和国际知名演说家,专注于面向对象分析与设计,统一建模语言,领域建模,以及敏捷软件开发方法,包括极限编程。

与持续集成相关的 还有 持续交付和持续部署。

1.5.3 持续交付

持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境」(production-like environments)中。交付给质量团队或者用户,以供评审 如果评审通过,代码就进入生产阶段。

如果所有的代码完成之后一起交付,会导致很多问题爆发出来,解决起来很麻烦,所以持续集成,也就是没更新一次代码,都向下交付一次,这样可以及时发现问题,及时解决,防止问题大量堆积。

1.5.4 持续部署

持续部署是指当交付的代码通过评审之后,自动部署到生产环境中。持续部署是持续交付的最高阶段。

Puppet,SaltStack和Ansible是这个阶段使用的流行工具。容器化工具在部署阶段也发挥着重要作用。 Docker和k8s是流行的工具,有助于在开发,测试和生产环境中实现一致性。 除此之外, k8s还可以实现自动扩容缩容等功能。

互动: 举个例子,形象说明持续集成、持续交付、持续部署之间的关系

2 .为什么大厂都在用DevOps?

2 .1 神州泰岳D evOps 生态体系建设与实践- 神州泰岳云资源运营事业部经理张凯分享

传统软件服务企业的痛点 ?

解决之道: DevOps

本图摘自:张乐 - DevOps 道法术器》

2 .2 DevOps在金融行业的应用-张安全分享

标准的敏捷开发流程:

2 .3 哪些企业在用DevOps?

2 .4 DevOps在5G领域的的展望

3 .K 8 S在D evOps 中的核心作用

D ocker和K 8 S的出现使DevOps变得更加普及,更加容易实现。在传统运维中我们服务时需要针对不同的环境去安装不同的版本,部署方式也杂、多。那么有了docker之后,一次构建、到处运行,我们只需要要构建一次镜像,那么只要有docker的主机,就可以基于镜像把应用跑起来。

互动: docker可以实现DevOps的这个思想,但是存在一个问题,什么问题呢?

在众多微服务中,我们每天可能需要去处理各种服务的崩溃,而服务间的依赖调用关系也及其复杂,这对我们解决问题带来了很大的复杂度。要很好的解决这个问题。我们就需要用到容器编排工具。

Kubernetes 的出现主宰了容器编排的市场,也进化了过去的运维方式,将开发与运维 联系的更加紧密。 而且让 DevOps 这一角色变得更加清晰 它是目前可用的很流行的容器解决方案之一。

3 .1 自动化

敏捷开发->持续集成->持续交付->持续部署

3 .2 多集群管理

可以根据客户需求对开发,测试,生产环境部署多套kubernetes集群,每个环境使用独立的物理资源,相互之间避免影响

3 .3 多环境一致性

K ubernetes是基于docker的容器编排工具, 因为容器的镜像是不可变的,所以镜像把 OS、业务代码、运行环境、程序库、目录结构都包含在内,镜像 保存在我们的私有仓库 只要用户从我们提供的私有仓库拉取镜像,就 能保证环境的一 致性

3 . 4 实时 反馈 和智能化报表

每次集成或交付,都会第一时间 将结果通过多途径的方式反馈给你,也可以定制适合企业专用的报表平台。

4 .基于Jenkins+K 8S+ harbor +git 等技术链助力Dev Ops 在企业落地实践

4 .1 神州泰岳k8s+DevOps+微服务生态体系建设与实践

开发代码->提交代码到代码仓库->Jenkins调k8s API->动态生成Jenkins Slave Pod->Slave Pod拉取git上的代码->编译代码->打包镜像->推送镜像到镜像仓库harbor或者docker hub->通过k8s编排服务发布到测试、生产平台-> Slave Pod工作完成之后自动删除>通过Ingress发布服务

4 .2 百度:基于k8s构建亿级PV流量的DevOps平台

功能图:

架构图:

4.3 发布应用到测试环境

4 . 4 发布应用到生产环境

4.5 整个DevOps流程图

5. 基于 Jenkins+k8s+Git+ DockerHub等技术链 构建企业级DevOps 容器云平台

K8s 版本:

[root@xianchaomaster1 ~]# kubectl get nodes

NAME STATUS ROLES AGE VERSION

xianchaomaster1 Ready control-plane,master 76d v1.23.1

xianchaonode1 Ready <none> 76d v1.23.1

jenkins版本:

最新版

5 .1 安装Jenkins

5 .1. 1 安装nfs服务, 可以 选择自己的任意一台机器,我选择 的是 k8s 的控制 节点 xianchaomaster 1

(1)在xianchaomaster1 和xianchaonode 1上安装nfs服务

注意: 如果已经安装过nfs,这个步骤可以忽略

[root@xianchaomaster1 ~]# yum install nfs-utils -y

[root@xianchaomaster1 ~]# systemctl start nfs

[root@xianchaomaster1 ~]# systemctl enable nfs

[root@xianchao node 1 ~]# yum install nfs-utils -y

[root@xianchao node 1 ~]# systemctl start nfs

[root@xianchao node 1 ~]# systemctl enable nfs

(2)在xianchaomaster1上创建一个nfs共享目录

[root@xianchaomaster1 ~]# mkdir /data/v2 -p

[root@xianchaomaster1 ~]# vim /etc/export s

/data/v1 *(rw,no_root_squash)

/data/v2 *(rw,no_root_squash)

#新增加一行 /data/v2 *

# 使配置文件生效

[root@xianchaomaster1 ~]# exportfs -arv

5 .1.2 kubernetes中部署jenkins

(1)创建名称空间

[root@xianchaomaster1 ~]# kubectl create namespace jenkins-k8s

(2)创建pv

#更新资源清单文件

[root@xianchaomaster1]# kubectl apply -f pv.yaml

#查看pv是否创建成功

[root@xianchaomaster1]# kubectl get pv

pv.yaml 文件内容如下:

apiVersion: v1

kind: PersistentVolume

metadata:

name: jenkins-k8s-pv

spec:

capacity:

storage: 10Gi

accessModes:

- ReadWriteMany

nfs:

server: 192.168.40.180

path: /data/v2

(3)创建pvc

#更新资源清单文件

[root@xianchaomaster1]# kubectl apply -f pvc.yaml

# 查看pvc是否创建成功

[root@xianchaomaster1]# kubectl get pvc -n jenkins-k8s

pvc.yaml 文件内容如下:

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

name: jenkins-k8s-pvc

namespace: jenkins-k8s

spec:

resources:

requests:

storage: 10Gi

accessModes:

- ReadWriteMany

(4)创建一个sa账号

[root@xianchaomaster1]# kubectl create sa jenkins-k8s-sa -n jenkins-k8s

(5)把上面的sa账号做rbac授权

[root@xianchaomaster1]# kubectl create clusterrolebinding jenkins-k8s-sa-cluster -n jenkins-k8s --clusterrole=cluster-admin --serviceaccount=jenkins-k8s:jenkins-k8s-sa

(6)通过deployment部署jenkins

[root@xianchaonode1 ~]# docker pull jenkins /jenkins:2.394

[root@xianchaonode1 ~]# docker save -o jenkins2.394 jenkins/jenkins:2.394

[root@xianchaonode1 ~]# ctr -n=k8s.io images import jenkins2.394

备注:jenkins安装的时候,每次镜像都要下载最新的,安装最新版jenkins,如何下载最新的镜像?

去dockerhub上按照我视频方式去获取

[root@xianchaonode1 ~]# docker load -i jenkins-slave-latest.tar.gz

[root@xianchaonode1 ~]# ctr -n=k8s.io images import jenkins-slave-latest.tar.gz

备注: jenkins-slave-latest.tar.gz 这个里面封装的镜像是 jenkins-slave-latest:v1 ,这个 jenkins-slave-latest:v1 镜像制作方法如下:

[root@xianchaomaster1]# cd /root/slave

[root@xianchaomaster1 slave]# cat dockerfile

FROM jenkins/jnlp-slave:4.13.3-1-jdk11

USER root

# 安装Docker

RUN apt-get update && apt-get install -y \

docker.io

# 将当前用户加入docker用户组

RUN usermod -aG docker jenkins

RUN curl -LO https://dl.k8s.io/release/stable.txt

RUN curl -LO https://dl.k8s.io/release/$(cat stable.txt)/bin/linux/amd64/kubectl

RUN chmod +x kubectl

RUN mv kubectl /usr/local/bin/

ENV DOCKER_HOST unix:///var/run/docker.sock

[root@xianchaomaster1 slave]# docker build -t=jenkins-slave-latest:v1 .

[root@xianchaomaster1 slave]# docker save -o jenkins-slave-latest.tar.gz jenkins-slave-latest:v1

#更新资源清单文件

[root@xianchaomaster1]# kubectl apply -f jenkins-deployment.yaml

#查看jenkins是否创建成功

[root@xianchaomaster1 jenkins]# kubectl get pods -n jenkins-k8s

NAME READY STATUS RESTARTS AGE

jenkins-74b4c59549-g5j9t 0/1 CrashLoopBackOff 3 67s

#看到jenkins -74b4c59549-g5j9t CrashLoopBackOff 状态,查看日志:

[root@xianchaomaster1]# kubectl logs jenkins-74b4c59549-g5j9t -n jenkins-k8s

日志信息显示:

touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied

Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

#报错显示没有权限操作 /var/jenkins_home/copy_reference_file.log 文件,解决办法如下:

[root@xianchaomaster1]# kubectl delete -f jenkins-deployment.yaml

[root@xianchaomaster1]# chown -R 1000.1000 /data/v2

[root@xianchaomaster1]# kubectl apply -f jenkins-deployment.yaml

# 查看pod是否创建成功 :

[root@xianchaomaster1]# kubectl get pods -n jenkins-k8s

显示如下,说明部署成功了:

NAME READY STATUS RESTARTS AGE

jenkins-74b4c59549-6xpnk 1 /1 Running 0 66

jenkins-deployment.yaml 文件内容如下:

kind: Deployment

apiVersion: apps/v1

metadata:

name: jenkins

namespace: jenkins-k8s

spec:

replicas: 1

selector:

matchLabels:

app: jenkins

template:

metadata:

labels:

app: jenkins

spec:

serviceAccount: jenkins-k8s-sa

containers:

- name: jenkins

image: jenkins/jenkins:2.394

imagePullPolicy: IfNotPresent

ports:

- containerPort: 8080

name: web

protocol: TCP

- containerPort: 50000

name: agent

protocol: TCP

resources:

limits:

cpu: 1000m

memory: 1Gi

requests:

cpu: 500m

memory: 512Mi

livenessProbe:

httpGet:

path: /login

port: 8080

initialDelaySeconds: 60

timeoutSeconds: 5

failureThreshold: 12

readinessProbe:

httpGet:

path: /login

port: 8080

initialDelaySeconds: 60

timeoutSeconds: 5

failureThreshold: 12

volumeMounts:

- name: jenkins-volume

subPath: jenkins-home

mountPath: /var/jenkins_home

volumes:

- name: jenkins-volume

persistentVolumeClaim:

claimName: jenkins-k8s-pvc

(7)把jenkins前端加上service,提供外部网络访问

#更新资源清单文件

[root@xianchaomaster1]# kubectl apply -f jenkins-service.yaml

# 查看service是否创建成功

[root@xianchaomaster1]# kubectl get svc -n jenkins-k8s

#通过上面可以看到service的8 080 端口在物理机映射的端口是3 0002

jenkins-service.yaml 文件内容如下:

apiVersion: v1

kind: Service

metadata:

name: jenkins-service

namespace: jenkins-k8s

labels:

app: jenkins

spec:

selector:

app: jenkins

type: NodePort

ports:

- name: web

port: 8080

targetPort: web

nodePort: 30002

- name: agent

port: 50000

targetPort: agent

5 .2 配置Jenkins

在浏览器访问jenkins的web界面:

++++http://192.168.++++ ++++4++++ ++++0.++++ ++++1++++ ++++80:30002/login?from=%2F++++

5 .2.1 获取管理员密码

在nfs服务端,也就是我们的 master 1节点获取密码:

[root@xianchaomaster1 ~]# cat /data/v2/jenkins-home/secrets/initialAdminPassword

把上面获取到的密码拷贝到上面管理员密码下的方框里

点击继续,出现如下界面

5 . 2.2 安装插件

安装推荐的插件

插件安装好之后显示如下

5.2.3 创建第一个管理员用户

用户名和密码都设置成admin,线上环境需要设置成复杂的密码

修改好之后点击保存并完成,出现如下界面

点击保存并完成,出现如下界面

点击保存并完成,出现如下界面

点击开始使用Jenkins

5 .3 测试jenkins的CI/CD

5 .3.1 在Jenkins中安装kubernetes插件

(1)在jenkins中安装k8s插件

Manage Jnekins------> 插件管理 ------>可选插件------>搜索kubernetes------>出现如下

选中kubernetes之后------>点击下面的直接安装------>安装之后选择重新启动jenkins---> http://192.168.40. 1 80:3000 2 /restart-->重启之后登陆jenkins ,插件即可生效

(2)安装blueocean插件

Manage Jnekins------> 插件管理 ------>可选插件------>搜索 blueocean ------>出现如下

选中 BlueOcean 之后------>点击下面的直接安装------>安装之后选择重新启动jenkins---> http://192.168.40. 1 80:3000 2 /restart-->重启之后登陆jenkins ,插件即可生效

5 .3.2 配置jenkins连接到我们存在的k8s集群

(1) 访问 http://192.168.40.180:30002/configureClouds/

新增一个云,在下拉菜单中选择kubernets并添加

(2)填写云kubernetes配置内容

名称: kubernetes

K ubernetes地址:

https://192.168.40.180:6443

(3)测试jenkins和k8s是否可以通信

K ubernetes名称空间: jenkins-k8s-sa

点击连接测试,如果显示 Connected to Kubernetes v1.23.1 ,说明测试成功,Jenkins可以和k8s进行 通信

Jenkins地址:

http://jenkins-service.jenkins-k8s.svc.cluster.local:8080

5.3.3 配置pod-template

(1)配置pod template

添加Pod模板

点击Pod Template details

点击容器列表下的添加容器

名称:jnlp

Docker镜像:jenkins -slave-latest:v1

给上面的pod template添加卷

/var/run/docker.sock

/var/run/docker.sock

/root/.kube

/home/jenkins/.kube

[root@xianchaomaster1 ~]# scp -r /root/.kube/ xianchaonode1:/root/

在Service Account处输入jenkins-k8s-sa,这个sa就是我们最开始安装jenkins时的sa

上面配置好之后, Apply (应用 ) ------> Save (保存 )

5.3.4 添加自己的dockerhub凭据

首页------> 系统管理 à Manage Credentials (管理 凭据 ------>点击Stores scoped to Jenkins 下的第一行jenkins 后的全局 ,显示如下

点击添加凭据,出现如下------>

username: xianchao

password:1989*****

ID:dockerhub

描述:随意 写一段描述即可

上面改好之后选择确定即可

5.3.5 测试通过Jenkins部署 应用发布到k 8s 开发环境、测试环境、生产环境

开发提交代码到代码仓库 gitlab - à jenkins检测到代码更新- à 调用k 8s api在 k8s 中创建jenkins slave pod:

J enkins slave pod拉取代码- -- à 通过maven 把拉取的代码进行 构建 war包 或者jar包- --> 上传代码到 Sonarqube ,进行 静态代码扫描- --> 基于war包 构建docker image-->把镜像上传到harbor镜像仓库--> 基于镜像 部署应用到开发环境-->部署应用到测试环境--->部署应用到生产环境

#下面在Pipeline Script输入的脚本内容在课件里面,大家可以找到

jenkins-pipeline-script.txt 文件,复制里面内容到 P ipeline Script

在k 8s 的控制节点创建名称空间:

[root@xianchaomaster1 ~]# kubectl create ns de v lopment

[root@xianchaomaster1 ~]# kubectl create ns production

[root@xianchaomaster1 ~]# kubectl create ns qatest

回到首页:

开始创建一个 新任务------>

输入一个任务名称 jenkins-variable-test-deploy------>

流水线------>

确定------>

在Pipeline script处输入如下内容

node('testhan') {

stage('Clone') {

echo "1.Clone Stage"

git url: "https://github.com/luckylucky421/jenkins-sample.git"

script {

build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()

}

}

stage('Test') {

echo "2.Test Stage"

}

stage('Build') {

echo "3.Build Docker Image Stage"

sh "docker build -t xianchao/jenkins-demo:${build_tag} ."

}

stage('Push') {

echo "4.Push Docker Image Stage"

withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {

sh "docker login -u ${dockerHubUser} -p ${dockerHubPassword}"

sh "docker push xianchao/jenkins-demo:${build_tag}"

}

}

stage('Deploy to dev') {

echo "5. Deploy DEV"

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev.yaml"

// sh "bash running-devlopment.sh"

sh "kubectl apply -f k8s-dev.yaml --validate=false"

}

stage('Promote to qa') {

def userInput = input(

id: 'userInput',

message: 'Promote to qa?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa.yaml"

// sh "bash running-qa.sh"

sh "kubectl apply -f k8s-qa.yaml --validate=false"

sh "sleep 6"

sh "kubectl get pods -n qa test "

} else {

//exit

}

}

stage('Promote to pro') {

def userInput = input(

id: 'userInput',

message: 'Promote to pro?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod.yaml"

// sh "bash running-production.sh"

sh "cat k8s-prod.yaml"

sh "kubectl apply -f k8s-prod.yaml --record --validate=false"

}

}

}

应用------>保存------>立即构建, 在# 1 的Console Output可看到构建过程:

# 在Console Output如果看到如下:

点击Input requested

点击继续

#上面可以看到已经把应用部署到dev环境了

#点击Input requested

点击继续

#通过上面可以看到把应用部署到了pro环境了

#验证是否在devlopment和production名称空间下有应用

[root@xianchaomaster1 ~]# kubectl get pods -n production

NAME READY STATUS RESTARTS AGE

jenkins-demo-784885d9c9-w6zlt 1/1 Running 0 60s

[root@xianchaomaster1 ~]# kubectl get pods -n devlopment

NAME READY STATUS RESTARTS AGE

jenkins-demo-784885d9c9-9wkcx 1/1 Running 0 5m38s

[root@xianchaomaster1 ~]# kubectl get pods -n qatest

NAME READY STATUS RESTARTS AGE

jenkins-demo-784885d9c9-wshpj 1/1 Running 0 3m56s

#通过上面可以看到jenkins对接k 8s ,可以把应用发布到k 8s 集群的开发、测试、生产环境了。

6. 基于Jenkins+ k8s+ Git + harbor构建DevOps容器云平台

需要有一台harbor服务,我的harbor安装在了1 92 . 168.40.182 机器上

1.添加凭据

首页------> 系统管理 à 管理 凭据------>点击Stores scoped to Jenkins 下的第一行jenkins,显示如下

点击这个全局凭据,出现如下------>

点击左侧的添加凭据,出现如下------>

username: admin

password: Harbor 12345

ID:docker harbor

描述:随意

上面改好之后选择确定即可

2 . 编写jenkins pipeline

因为镜像要上传到h arbor 私有镜像仓库,所以需要在harbor上创建一个项目,项目名称是jenkins - demo,如下所示:

上面项目创建成功之后,执行如下步骤:

#下面在Pipeline Script输入的脚本内容在课件里面,大家可以找到

jenkins-pipeline- harbor -script.txt 文件,复制里面内容到 P ipeline Script

新建一个任务------>输入一个任务名称处输入jenkins- harbor ------>流水线------>确定------>在Pipeline script处输入如下内容

node('testhan') {

stage('Clone') {

echo "1.Clone Stage"

git url: "https://github.com/luckylucky421/jenkins-sample.git"

script {

build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()

}

}

stage('Test') {

echo "2.Test Stage"

}

stage('Build') {

echo "3.Build Docker Image Stage"

sh "docker build -t 192.168.40.182/jenkins-demo/jenkins-demo:${build_tag} ."

}

stage('Push') {

echo "4.Push Docker Image Stage"

withCredentials([usernamePassword(credentialsId: 'dockerharbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {

sh "docker login 192.168.40.182 -u ${dockerHubUser} -p ${dockerHubPassword}"

sh "docker push 192.168.40.182/jenkins-demo/jenkins-demo:${build_tag}"

}

}

stage('Deploy to dev') {

echo "5. Deploy DEV"

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev-harbor.yaml"

// sh "bash running-devlopment.sh"

sh "kubectl apply -f k8s-dev-harbor.yaml --validate=false"

}

stage('Promote to qa') {

def userInput = input(

id: 'userInput',

message: 'Promote to qa?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa-harbor.yaml"

// sh "bash running-qa.sh"

sh "kubectl apply -f k8s-qa-harbor.yaml --validate=false"

sh "sleep 6"

sh "kubectl get pods -n qatest"

} else {

//exit

}

}

stage('Promote to pro') {

def userInput = input(

id: 'userInput',

message: 'Promote to pro?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod-harbor.yaml"

// sh "bash running-production.sh"

sh "cat k8s-prod-harbor.yaml"

sh "kubectl apply -f k8s-prod-harbor.yaml --record --validate=false"

}

}

}

应用------>保存------>立即构建即可,打开blue ocean会看到如下流程,可以手动点击确认

Jenkins实现k 8s 应用按照指定版本回滚

回到首页:

新建一个任务------>输入一个任务名称处输入jenkins-variable-test-deploy- rollout ------>流水线------>确定------>在Pipeline script处输入如下内容

node('testhan') {

stage('git clone') {

git url: "https://github.com/luckylucky421/jenkins-rollout"

sh "ls -al"

sh "pwd"

}

stage('select env') {

def envInput = input(

id: 'envInput',

message: 'Choose a deploy environment',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "dev lopment \nqa test \npro duction ",

name: 'Env'

]

]

)

echo "This is a deploy step to ${envInput}"

sh "sed -i 's/<namespace>/${envInput}/' getVersion.sh"

sh "sed -i 's/<namespace>/${envInput}/' rollout.sh"

sh "bash getVersion.sh"

// env.WORKSPACE = pwd()

// def version = readFile "${env.WORKSPACE}/version.csv"

// println version

}

stage('select version') {

env.WORKSPACE = pwd()

def version = readFile "${env.WORKSPACE}/version.csv"

println version

def userInput = input(id: 'userInput',

message: '选择回滚版本',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "$version\n",

name: 'Version'

]

]

)

sh "sed -i 's/<version>/${userInput}/' rollout.sh"

}

stage('rollout deploy') {

sh "bash rollout.sh"

}

}

点击应用- > 保存-立即构建

7 . Jenkins Pipeline语法 介绍

7 .1 Jenkins Pipeline介绍

Jenkins pipeline (流水线) 是一套运行于jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化。它把 持续提交流水线 (Continuous Delivery Pipeline) 的任务 集成到Jenkins

pipeline 是jenkins2.X 最核心的特性, 帮助jenkins 实现从CI到C D 与DevOps的转变

持续提交流水线(Continuous Delivery Pipeline)会经历一个复杂的过程: 从版本控制、向用户和客户提交软件,软件的每次变更(提交代码到仓库)到软件发布(Release)。这个过程包括以一种可靠并可重复的方式构建软件,以及通过多个测试和部署阶段来开发构建好的软件(称为Build)。

总结:

1.Jenkins Pipeline是一组插件,让Jenkins可以实现持续交付管道的落地和实施。
2.持续交付管道(CD Pipeline)是将软件从版本控制阶段到交付给用户或客户的完
整过程的自动化表现。
3.软件的每一次更改(提交到源代码管理系统)都要经过一个复杂的过程才能被发布。

7 .2 为什么用Jenkins Pipeline?

本质上,Jenkins 是一个自动化引擎,它支持许多自动模式。 Pipeline向Jenkins中添加了一组强大的工具, 支持简单的CI到全面的CD pipeline。通过对一系列的相关任务进行建模, 用户可以利用pipeline的很多特性:

1 代码:Pipeline以代码的形式实现,使团队能够编辑,审查和迭代其CD流程。
2 可持续性:Jenkins重启或者中断后都不会影响Pipeline Job。
3 停顿:Pipeline可以选择停止并等待人工输入或批准,然后再继续Pipeline运行。
4 多功能:Pipeline支持现实复杂 CD要求,包括循环和并行执行工作的能力。
5 可扩展:Pipeline插件支持其DSL的自定义扩展以及与其他插件集成的多个选项。

DSL 是什么?

DSL 其实是 Domain Specific Language 的缩写,中文翻译为领域特定语言(下简称 DSL);而与 DSL相对的就是GPL,这里的GPL并不是我们知道的开源许可证,而是 General Purpose Language的简称,即通用编程语言,也就是我们非常熟悉的 Objective-C、Java、Python 以及 C 语言等等。

7.3 J enkins pipeline 入门

pipeline脚本是 groovy 语言实现的

无需专门学习 groovy

pipeline支持两种语法

-Declarative 声明式

-Scripted pipeline 脚本式

声明式pipeline 语法:

官网:

https://www.jenkins.io/doc/book/pipeline/syntax/

声明式语法包括以下核心流程:

1.pipeline : 声明其内容为一个声明式的pipeline脚本
2.agent: 执行节点(job运行的slave或者master节点)
3.stages: 阶段集合,包裹所有的阶段(例如:打包,部署等各个阶段)
4.stage: 阶段,被stages包裹,一个stages可以有多个stage
5.steps: 步骤,为每个阶段的最小执行单元,被stage包裹
6.post: 执行构建后的操作,根据构建结果来执行对应的操作

根据上面 流程 创建一个简单的pipeline

pipeline {

agent any

stages{

stage(" This is first stage "){

steps(" This is first step "){

echo " I am xianchao "

}

}

}

post{

always{

echo " The process is ending "

}

}

}

P ipeline:

作用域:应用于全局最外层,表明该脚本为声明式pipeline
是否必须:必须

a gent

作用域:可用在全局与stage内

agent表明此pipeline 在哪个节点上执行
是否必须:是
参数:any,none, label, node,docker,dockerfile

agent any

#运行在任意的可用节点上

agent none

#全局不指定运行节点,由各自stage来决定

agent { label 'master' }

#运行在指定标签的机器上,具体标签名称由agent配置决定

agent {

node {

label 'my-defined-label'

customWorkspace ' xxxxxxx '

}

}

#node{ label 'master'} agent { label 'master' } 一样,但是node 可以扩展节点信息 允许额外的选项 (比如 customWorkspace )。

agent { docker 'python' }

#使用指定 的容器运行流水线

如:

agent {

docker {

image 'maven:3-alpine'

label 'my-defined-label'

args '-v /tmp:/tmp'

}

}

# 定义此参数时,执行Pipeline或stage时会动态 的在具有 label 'my-defined-label' 标签的node提供 docker节点去 执行 Pipelines。 docker还可以接受一个args,直接传递给docker run调用。

agent {

// Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/

dockerfile {

filename 'Dockerfile.build'

dir 'build'

label 'my-defined-label'

additionalBuildArgs '--build-arg version=1.0.2'

}

}

7.4 Pipeline 声明式语法 Declarative

7.4.1 environment

environment指令指定一系列键值对,这些键值对将被定义为所有step或stage-specific step的环境变量,具体取决于environment指令在Pipeline中的位置。该指令支持一种特殊的方法credentials(),可以通过其在Jenkins环境中的标识符来访问预定义的凭据。对于类型为"Secret Text"的凭据,该 credentials()方法将确保指定的环境变量包含Secret Text内容;对于"标准用户名和密码"类型的凭证,指定的环境变量将被设置为username:password并且将自动定义两个附加的环境变量: MYVARNAME_USR MYVARNAME_PSW**。**

pipeline {

agent any

environment {

CC = 'clang'

}

stages {

stage('Example') {

steps {

sh 'printenv'

}

}

}

}

7.4.2 options

options指令允许在Pipeline本身内配置Pipeline专用选项。Pipeline本身提供了许多选项,例如buildDiscarder,但它们也可能由插件提供,例如 timestamps。

可用选项

buildDiscarder pipeline保持构建的最大个数。用于保存Pipeline最近几次运行的数据 例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
disableConcurrentBuilds 不允许并行执行Pipeline,可用于防止同时访问共享资源等。例如:options { disableConcurrentBuilds() }
skipDefaultCheckout 跳过默认设置的代码check out。例如:options { skipDefaultCheckout() }
skipStagesAfterUnstable 一旦构建状态进入了"Unstable"状态,就跳过此stage。例如:options { skipStagesAfterUnstable() }
timeout 设置Pipeline运行的超时时间 超过超时时间,job会自动被终止 例如:options { timeout(time: 1, unit: 'HOURS') }
retry 失败后,重试整个Pipeline的次数。例如:options { retry(3) }
timestamps 预定义由Pipeline生成的所有控制台输出时间。例如:options { timestamps() }

pipeline {

agent any

options {

timeout(time: 1, unit: 'HOURS')

}

stages {

stage('Example') {

steps {

echo 'Hello World'

}

}

}

}

7.4.3 parameters

parameters指令提供用户在触发Pipeline时的参数列表。这些参数值通过该params对象可用于Pipeline stage中 ,具体用法如下

作用域:被最外层pipeline所包裹,并且只能出现一次,参数可被全局使用

好处:使用parameters好处是能够使参数也变成code,达到pipeline as code,pipeline中设置的参数会自动在job构建的时候生成,形成参数化构建

可用参数
string
A parameter of a string type, for example: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
booleanParam
A boolean parameter, for example: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
**  目前只支持[booleanParam, choice, credentials, file, text, password, run, string]这几种参数类型,其他高级参数化类型还需等待社区支持。**

pipeline{

agent any

parameters {

string(name: 'xianchao', defaultValue: 'my name is xianchao', description: 'My name is xiancaho')

booleanParam(name: 'luckylucky421302', defaultValue: true, description: 'This is my wechat')

}

stages{

stage("stage1"){

steps{

echo "$xianchao"

echo "$luckylucky421302"

}

}

}

}

开始构建

控制台输出观察构建结果:

7.4.4 triggers

triggers指令定义了Pipeline自动化触发的方式。目前有 三个 可用的触发器:cron和pollSCM upstream。

用域:被pipeline包裹,在符合条件下自动触发pipeline

cron
**  接受一个cron风格的字符串来定义Pipeline触发的** 时间 间隔,例如:

triggers { cron('H 4/* 0 0 1-5') }
pollSCM

**  接受一个cron风格的字符串来定义Jenkins检查SCM源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发。例如:triggers { pollSCM('H 4/* 0 0 1-5') }**

pipeline {

agent any

triggers {

cron('H 4/* 0 0 1-5')

}

stages {

stage('Example') {

steps {

echo 'Hello World'

}

}

}

}

7.4.5 tools

通过tools可自动安装工具,并放置环境变量到PATH。如果agent none,这将被忽略。

Supported Tools(Global Tool Configuration)
maven
jdk
gradle

pipeline {

agent any

tools {

#工具名称必须在Jenkins 管理Jenkins → 全局工具配置中预配置。

maven 'apache-maven-3.0.1'

}

stages {

stage('Example') {

steps {

sh 'mvn --version'

}

}

}

}

# The tool name must be pre-configured in Jenkins under Manage Jenkins**→**Global Tool Configuration

7.4.6 input

stage 的 input 指令允许你使用 input step提示输入。 在应用了 options 后,进入 stage 的 agent 或评估 when 条件前,stage 将暂停。 如果 input 被批准, stage 将会继续。 作为 input 提交的一部分的任何参数都将在环境中用于其他 stage

配置项

message

必需的。 这将在用户提交 input 时呈现给用户。

id

input 的可选标识符, 默认为 stage 名称。

ok

`input`表单上的"ok" 按钮的可选文本。

submitter

可选的以逗号分隔的用户列表或允许提交 input 的外部组名。默认允许任何用户。

submitterParameter

环境变量的可选名称。如果存在,用 submitter 名称设置。

parameters

提示提交者提供的一个可选的参数列表。

pipeline {

agent any

stages {

stage('Example') {

input {

message "Should we continue?"

ok "Yes, we should."

submitter " xianchao , lucky "

parameters {

string(name: 'PERSON', defaultValue: ' xianchao ', description: 'Who should I say hello to?')

}

}

steps {

echo "Hello, ${PERSON}, nice to meet you."

}

}

}

}

7.4.7 when

when指令允许Pipeline根据给定的条件确定是否执行该阶段。该when指令必须至少包含一个条件。如果when指令包含多个条件,则所有子条件必须为stage执行返回true。这与子条件嵌套在一个allOf条件中相同(见下面的例子)。
更复杂的条件结构可使用嵌套条件建:not,allOf或anyOf。嵌套条件可以嵌套到任意深度。

内置条件

branch
**    当正在构建的分支与给出的分支模式匹配时执行,例如:when { branch 'master' }。请注意,这仅适用于多分支Pipeline。**
environment
**    当指定的环境变量设置为给定值时执行,例如: when { environment name: 'DEPLOY_TO', value: 'production' }**
expression
**    当指定的Groovy表达式求值为true时执行,例如: when { expression { return params.DEBUG_BUILD } }**
not
**    当嵌套条件为false时执行。必须包含一个条件。例如:when { not { branch 'master' } }**
allOf
**    当所有嵌套条件都为真时执行。必须至少包含一个条件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }**
anyOf
**    当至少一个嵌套条件为真时执行。必须至少包含一个条件。例如:when { anyOf { branch 'master'; branch 'staging' } }**

pipeline {

agent any

stages {

stage('Example Build') {

steps {

echo 'Hello World'

}

}

stage('Example Deploy') {

when {

allOf {

branch 'production'

environment name: 'DEPLOY_TO', value: 'production'

}

}

steps {

echo 'Deploying'

}

}

}

}

7.4.8 Parallel

Declarative Pipeline近期新增了对并行嵌套stage的支持,对耗时长,相互不存在依赖的stage可以使用此方式提升运行效率。除了parallel stage,单个parallel里的多个step也可以使用并行的方式运行。

pipeline {

agent any

stages {

stage('Non-Parallel Stage') {

steps {

echo 'This stage will be executed first.'

}

}

stage('Parallel Stage') {

when {

branch 'master'

}

parallel {

stage('Branch A') {

agent {

label "for-branch-a"

}

steps {

echo "On Branch A"

}

}

stage('Branch B') {

agent {

label "for-branch-b"

}

steps {

echo "On Branch B"

}

}

}

}

}

}

7.5 Pipeline Scripted语法

Groovy脚本不一定适合所有使用者,因此jenkins创建了Declarative pipeline,为编写Jenkins管道提供了一种更简单、更有主见的语法。但是由于脚本化的pipeline是基于groovy的一种DSL语言,所以与Declarative pipeline相比为jenkins用户提供了更巨大的灵活性和可扩展性。

1.流程控制

pipeline脚本同其它脚本语言一样,从上至下顺序执行,它的流程控制取决于Groovy表达式,如if/else条件语句,举例如下:

node {

stage('Example') {

if (env.BRANCH_NAME == 'master') {

echo 'I only execute on the master branch'

} else {

echo 'I execute elsewhere'

}

}

}

2.Declarative pipeline和Scripted pipeline的比较

共同点:
**  两者都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的** stage ,两者都可以利用共享库扩展。
区别:
**  两者不同之处在于语法和灵活性。Declarative pipeline对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。但是Scripted pipeline更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。**

8 、jenkins+ k8s+ harbor实现DevOps

1.添加凭据

首页------> 系统管理 à 管理 凭据------>点击Stores scoped to Jenkins 下的第一行jenkins,显示如下

点击这个全局凭据,出现如下------>

点击左侧的添加凭据,出现如下------>

username: admin

password: Harbor 12345

ID:docker harbor

描述:随意

上面改好之后选择确定即可

2 . 编写jenkins pipeline

因为镜像要上传到h arbor 私有镜像仓库,所以需要在harbor上创建一个项目,项目名称是jenkins - demo,如下所示:

上面项目创建成功之后,执行如下步骤:

新建一个任务------>输入一个任务名称处输入jenkins- harbor ------>流水线------>确定------>在Pipeline script处输入如下内容

node('testhan') {

stage('Clone') {

echo "1.Clone Stage"

git url: "https://github.com/luckylucky421/jenkins-sample.git"

script {

build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()

}

}

stage('Test') {

echo "2.Test Stage"

}

stage('Build') {

echo "3.Build Docker Image Stage"

sh "docker build -t 192.168.40.132/jenkins-demo/jenkins-demo:${build_tag} ."

}

stage('Push') {

echo "4.Push Docker Image Stage"

withCredentials([usernamePassword(credentialsId: 'dockerharbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {

sh "docker login 192.168.40.132 -u ${dockerHubUser} -p ${dockerHubPassword}"

sh "docker push 192.168.40.132/jenkins-demo/jenkins-demo:${build_tag}"

}

}

stage('Deploy to dev') {

echo "5. Deploy DEV"

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev-harbor.yaml"

// sh "bash running-devlopment.sh"

sh "kubectl apply -f k8s-dev-harbor.yaml --validate=false"

}

stage('Promote to qa') {

def userInput = input(

id: 'userInput',

message: 'Promote to qa?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa-harbor.yaml"

// sh "bash running-qa.sh"

sh "kubectl apply -f k8s-qa-harbor.yaml --validate=false"

sh "sleep 6"

sh "kubectl get pods -n qatest"

} else {

//exit

}

}

stage('Promote to pro') {

def userInput = input(

id: 'userInput',

message: 'Promote to pro?',

parameters: [

[

$class: 'ChoiceParameterDefinition',

choices: "YES\nNO",

name: 'Env'

]

]

)

echo "This is a deploy step to ${userInput}"

if (userInput == "YES") {

sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod-harbor.yaml"

sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod-harbor.yaml"

// sh "bash running-production.sh"

sh "cat k8s-prod-harbor.yaml"

sh "kubectl apply -f k8s-prod-harbor.yaml --record --validate=false"

}

}

}

应用------>保存------>立即构建即可,打开blue ocean会看到如下流程,可以手动点击确认

9 J enkins接入Sonarqube

1 . 在1 92 . 168.40.180 上安装sonarqube:

docker run -d --name postgres10 -p 5432:5432 -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=123456 postgres

docker run -d --name sonarqube7.9 -p 9000:9000 --link postgres10 -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres10:5432/sonar -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=123456 -v sonarqube_conf:/opt/sonarqube/conf -v sonarqube_extensions:/opt/sonarqube/extensions -v sonarqube_logs:/opt/sonarqube/logs -v sonarqube_data:/opt/sonarqube/data sonarqube

在jenkins中安装sonarqube插件:

系统管理 - >插件管理 -> 可选插件:搜索sonar,找到Sonarqube Scanner

选择Sonarqube Scanner直接安装,安装之后重启jenkins即可

在sonarqube的web界面创建一个token:

选择Generate出现如下:

把copy后面的一串token记录下来:

2b91be9d40a28385d8b2f61b0fc0a52efd5abf97

回到k 8s 的master 1 节点:

cd /root/microservic-test

mvn sonar:sonar -Dsonar.host.url=http://192.168.40.181:9000 -Dsonar.login=2b91be9d40a28385d8b2f61b0fc0a52efd5abf97

这样就可以把代码上传到sonarqube了

10 、Jenkins +k8s+nexus+ gitlab + harbor+ sonarqube+ springloud构建DevOps

11.1 安装sonarqube

在192.168.40.131上操作:

docker run -d --name postgres10 -p 5432:5432 -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=123456 postgres

docker run -d --name sonarqube7.9 -p 9000:9000 --link postgres10 -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres10:5432/sonar -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=123456 -v sonarqube_conf:/opt/sonarqube/conf -v sonarqube_extensions:/opt/sonarqube/extensions -v sonarqube_logs:/opt/sonarqube/logs -v sonarqube_data:/opt/sonarqube/data sonarqube

在jenkins中安装sonarqube插件:

系统管理->插件管理->可选插件:搜索sonar,找到Sonarqube Scanner - > 选择Sonarqube Scanner直接安装

安装之后重启jenkins即可

在sonarqube的web界面创建一个token:

选择Generate出现如下:

把copy后面的一串token记录下来:

2b91be9d40a28385d8b2f61b0fc0a52efd5abf97

回到k8s的 控制 节点:

cd /root/microservic-test

mvn sonar:sonar -Dsonar.host.url=http://192.168.40.131:9000 -Dsonar.login=2b91be9d40a28385d8b2f61b0fc0a52efd5abf97

这样就可以把代码上传到sonarqube了

注意:开发写的代码目前不支持这个版本的sonarqube,所以这个上传到sonarqube是有问题的,会报错版本不支持,结果大家可以不用看,会用就可以

11.2 Jenkins界面添加harbor凭据

需要自己找机器安装好harbor,harbor机器ip:1 92.168.40.132

1.添加凭据

首页------> 系统管理 à 管理 凭据------>点击Stores scoped to Jenkins 下的第一行jenkins,显示如下

点击这个全局凭据,出现如下------>

点击左侧的添加凭据,出现如下------>

username: admin

password: Harbor 12345

ID:docker harbor

描述:随意

上面改好之后选择确定即可

11.3 安装nexus

概念:

Nexus服务器是一个代码包管理的服务器,可以理解 Nexus 服务器是一个巨大的 Library 仓库。Nexus 可以支持管理的工具包括 Maven , npm 等,对于 JAVA 开发来说,只要用到 Maven 管理就可以了。

Nexus服务器作用:因为传统的中央仓库在国外,其地理位置比较远,下载速度比较缓慢。因此,当公司开发人员数量越来越多时,如果不架设一台自己的Nexus服务器,会产生大量的流量阻塞带宽,并且在出现一些不可抗原因(光缆被挖断)导致无法连接到中央仓库时,开发就会因为无法下载相关依赖包而进度停滞。因此在本地环境部署一台私有的Nexus服务器来缓存所有依赖包,并且将公司内部开发的私有包也部署上去,方便其他开发人员下载,是非常有必要的。因为 Nexus 有权限控制,因此外部人员是无法得到公司内部开发的项目包的。

下面将介绍如何将自己的maven构件发布到nexus私服 上呢?

在192.168.40.133上安装:

docker run -d -p 8081:8081 -p 8082:8082 -p 8083:8083 -v /etc/localtime:/etc/localtime --name nexus3 sonatype/nexus3

在日志中,会看到一条消息: Started Sonatype Nexus OSS 3.20.1-01 这意味着Nexus Repository Manager可以使用了。现在转到浏览器并打开

http://your-ip-addr:8081

第一步:

1、在 pom.xml 文件中声明发布的宿主仓库和 release 版本发布的仓库。

<!-- 发布构件到Nexus -->

<distributionManagement>

<repository>

<id>releases</id>

<name>nexus-releases</name>

<url>http://192.168.40.133:8081/repository/maven-releases/\</url>

</repository>

<snapshotRepository>

<id>snapshots</id>

<name>nexus-snapshots</name>

<url>http://192.168.40.133:8081/repository/maven-snapshots/\</url>

</snapshotRepository>

</distributionManagement>

第二步:在 settings.xml 文件中配置
由于用 Maven 分发构件到远程仓库需要认证,须要在~/.m2/settings.xml或者中加入验证信息:

<servers>

<server>

<id>public</id>

<username> admin </username>

<password>123456</password>

</server>

<server>

<id>releases</id>

<username> admin </username>

<password>123456</password>

</server>

<server>

<id>snapshots</id>

<username> admin </username>

<password>123456</password>

</server>

</servers>

注意: settings.xml 中 server 元素下 id 的值必须与 POM 中 repository 或 snapshotRepository 下 id 的值完全一致 。

11.4 安装gitlab

在192.168.40.135上安装

docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce gitlab/gitlab - ce

改配置:

cat /home/gitlab/config/gitlab.rb

增加如下三行:

external_url 'http://192.168.40.135'

gitlab_rails['gitlab_ssh_host'] = '192.168.40.135'

gitlab_rails['gitlab_shell_ssh_port'] = 222

重启docker:

docker restart gitlab

登录192.168.40.135即可登录:

第一次登录注册账号密码之后,报错如下:

Your account is pending approval from your GitLab administrator and hence bl

可通过如下方法实现:

[root@xianchaomaster1 ~]# docker exec -it gitlab sh

irb(main):004:0> u=User.where(id:1).first

=> #<User id:1 @root>

irb(main):005:0> u.password='12345678'

=> "12345678"

irb(main):006:0> u.password_confirmation='12345678'

=> "12345678"

irb(main):007:0> u.save!

=> true

再次登录192.168.40.135

用户名是root

密码是 12345678

# -d:后台运行

# -p:将容器内部端口向外映射

# --name:命名容器名称

# -v:将容器内数据文件夹或者日志、配置等文件夹挂载到宿主机指定目录

在Jenkins安装git插件

系统管理-插件管理-可选插件-搜索git安装即可

在Jenkins上添加gitlab凭据

J enkins - 凭据-全局凭据

在gitlab上新建项目:

创建密钥对:

[root@localhost ~]# ssh-keygen -t rsa

#一路回车

上传密钥:

[root@localhost ~]# cat ~/.ssh/id_rsa.pub # 查看公钥

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8KZUe+PJykjZzJherolD+vXsw8/aL3OMyX/x1HF6Rz73dNZFCERQxA6t/9ahRrya8iY7IIloLjzi5iX666mzYI3fAEq1Ga3Dz2MWqEeWZGdbNKvL9lf0qTy0aLBIRe2fnQwrkrP2YakiqzDRpyjQgr05VkrnF5bVLX2HCHuC2GXwnHUAuJEkjb1f9vmII7YP0BmYDMOMpricQ1LeFnQ9cc2ZvPw6212yiXOrbhrbiMtjCYTPoRA8EIfmRAPcNcVl4GT3fZxAVocDk70rA/tEWCgu+zzFFH+aWhaIXMdkC70FEWLD28AxLWwwKj22KA9ezqp0eoxofzU3tSCIymVU9 ++++root@localhost.localdomain++++

提交本地代码到gitlab :

[root@localhost ~]# yum install git -y

[root@localhost ~]# unzip microservic-test.zip

[root@localhost ~]# cd microservic-test

[root@localhost microservic-test]# git init # 建仓

[root@localhost microservic-test]# git add * # 把当前文件夹所有代码提交

[root@localhost microservic-test]# git commit -m "add microservic-test" # 代码提交到缓冲区

[root@localhost microservic-test]# git remote add origin http://192.168.40.135/root/microservic-test.git

# 代码提交到远程仓库

[root@localhost microservic-test]# git push -u origin master

#最后一步push推送过去,push的时候,会让你输入账号和密码,这里的用户名和密码就是gitlab上注册的用户了

回到gitlab首页,可以看到,已经有项目了:

11.5 Jenkins +k8s+nexus+sonarqube+harbor+gitlab 构建DevOps

jenkins-jnlp-v2.tar.gz 这个压缩包封装的镜像带有mvn命令

[root@xianchaonode1 ~]# docker load -i jenkins-jnlp-v2.tar.gz

http://192.168.40.180:30002/configureClouds/,把 Container Template镜像改成jenkins-jnlp-v2.tar.gz 压缩包解压之后的镜像 xianchao/jenkins-jnlp:v2

修改gitlab上portal .yaml 文件:

把image镜像变成: 192.168.40.132/microservice/jenkins-demo:v1

注意:m icroservice 需要在harbor里提前创建这个仓库

打开Jenkins,新建流水线,流水线名字是 mvn-gitlab-harbor-springcloud

在Pipeline Script处输入如下内容:

node('testhan') {

stage('Clone') {

echo "1.Clone Stage"

git credentialsId: 'gitlab', url: 'http://192.168.40.135/root/microservic-test.git '

script {

build_tag = sh(returnStdout: true, script: 'git rev-parse --shortHEAD').trim()

}

}

stage('Test') {

echo "2.Test Stage"

}

stage('mvn') {

sh "mvn clean package -D maven.test.skip=true"

}

stage('Build') {

echo "3.Build Docker Image Stage"

sh "cd /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service"

sh "docker build --tag 192.168.40.132/microservice/jenkins-demo:v1 /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service/"

}

stage('Push') {

echo "4.Push Docker Image Stage"

withCredentials([usernamePassword(credentialsId: 'dockerharbor',passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {

sh "docker login 192.168.40.132 -u ${dockerHubUser} -p ${dockerHubPassword}"

sh "docker push 192.168.40.132/microservice/jenkins-demo:v1"

}

}

stage('Promoteto pro') {

sh "kubectl apply -f /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/k8s/portal.yaml"

}

}

立即构建即可

注意事项:

url: http://192.168.40.135/root/microservic-test.git

相关推荐
dessler4 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
zhy295634 分钟前
【DOCKER】基于DOCKER的服务之DUFS
运维·docker·容器·dufs
无为之士9 分钟前
Linux自动备份Mysql数据库
linux·数据库·mysql
秋名山小桃子19 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉1213819 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
岑梓铭26 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
努力学习的小廉26 分钟前
深入了解Linux —— make和makefile自动化构建工具
linux·服务器·自动化
MZWeiei30 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
7yewh1 小时前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
Arenaschi1 小时前
在Tomcat中部署应用时,如何通过域名访问而不加端口号
运维·服务器