基于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

相关推荐
嚯——哈哈15 分钟前
从入门到精通:解析如何使用亚马逊云服务器(AWS EC2)
运维·服务器·aws
编程修仙1 小时前
Collections工具类
linux·windows·python
芝麻团坚果1 小时前
对subprocess启动的子进程使用VSCode python debugger
linux·ide·python·subprocess·vscode debugger
Elastic 中国社区官方博客1 小时前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
写点什么啦1 小时前
[debug]不同的window连接ubuntu的vscode后无法正常加载kernel
linux·vscode·ubuntu·debug
wellnw1 小时前
[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案
linux·ubuntu
不爱学习的YY酱1 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
DC_BLOG1 小时前
Linux-Nginx虚拟主机
linux·运维·nginx
坐公交也用券1 小时前
使用Python3实现Gitee码云自动化发布
运维·gitee·自动化
一名路过的小码农1 小时前
ceph 18.2.4二次开发,docker镜像制作
ceph·docker·容器