基于Jenkins+Kubernetes+GitLab+Harbor构建CICD平台

1. 实验环境 

1.1 k8s环境

1)Kubernetes 集群版本是 1.20.6

2)k8s控制节点:

IP:192.168.140.130

主机名:k8s-master 

配置:4C6G

3)k8s工作节点

节点1:

IP:192.168.140.131

主机名:k8s-node1 

配置:4C7.5G

节点2:

IP:192.168.140.132

主机名:k8s-node2

配置:4C11G

1.2  GitLab 环境

地址:http://192.168.140.132:8001/

代码仓库地址: http://192.168.140.132:8001/root/jenkins-sample.git

代码下载链接:https://pan.baidu.com/s/1xbW-zUf23tu0YSV-5c1dew?pwd=lmzf 
提取码:lmzf

GitLab安装过程参考:Yum一键安装GitLab_yum gitlab-CSDN博客

1.3 Harbor环境

IP:192.168.140.132

1.4  Jenkins环境

版本:Jenkins 2.394

对应的jnlp软件下载地址如下:

链接:https://pan.baidu.com/s/1bNYiZCHWT099eOEdhDmJ3Q?pwd=lmzf 
提取码:lmzf

备注:docker  load   -i   jenkins-slave-latest.tar.gz 镜像即为jenkins-slave-latest:v1

2. 安装环境

2.1 安装 nfs 服务

1)三个节点分别安装nfs服务,k8s-master作为服务端

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

[root@k8s-master ~]#  systemctl enable  nfs  --now

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

[root@k8s-node1 ~]#  systemctl enable  nfs  --now

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

[root@k8s-node2 ~]#  systemctl enable  nfs  --now

2)k8s-master上创建共享目录

[root@k8s-master ~]#  mkdir /data/v2 -p
[root@k8s-master ~]#  vim /etc/export

/data/v2 192.168.140.0/24(rw,no_root_squash)

[root@k8s-master ~]#   exportfs -arv
[root@k8s-master ~]#   systemctl restart nfs

2.2 在 kubernetes 中部署 jenkins

1)创建名称空间

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

2)创建 pv

[root@k8s-master ~]#   kubectl apply -f pv.yaml

# pv.yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-k8s-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteMany
  nfs:
    server: 192.168.140.130
    path: /data/v2

3)创建pvc

[root@k8s-master ~]#   kubectl apply -f pvc.yaml

# pvc.yaml文件
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: jenkins-k8s-pvc
  namespace: jenkins-k8s
spec:
  resources:
    requests:
      storage: 10Gi
  accessModes:
  - ReadWriteMany

4)查看 pvc 是否创建成功

[root@k8s-master ~]#  kubectl get pvc -n jenkins-k8

[root@k8s-master ~]# kubectl get pvc -n jenkins-k8s
NAME              STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
jenkins-k8s-pvc   Bound    jenkins-k8s-pv   10Gi       RWX                           8h

5)创建一个 sa 账号

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

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

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

7)Jenkins文件夹授权

[root@k8s-master ~]# chown -R 1000.1000 /data/v2

8)deployment 部署 jenkins

[root@k8s-master ~]# kubectl apply -f jenkins-deployment.yaml 
# 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
      nodeName: k8s-node1

备注:

a. image:  jenkins/jenkins:2.394 通过在k8s-node1节点直接下载获取

[root@k8s-node1 ~]# docker   pull   jenkins/jenkins:2.394

 b. nodeName: k8s-node1: 本文指定部署在node1j节点

9)查看 jenkins 是否创建成功,如下所示表明创建成功

[root@k8s-master ~]#  kubectl get pods -n jenkins-k8s
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-5558b49ff5-dqhz5   1/1     Running   2          9h

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

[root@k8s-master ~]#  kubectl apply -f jenkins-service.yaml
# 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

2.3 配置 Jenkins

1)浏览器访问Jenkins页面:http://192.168.140.132:30002/

2)获取管理员密码

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

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

点击继续,出现如下界面

3)安装推荐的插件

插件安装好之后显示需要创建用户

4)创建管理员用户

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

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

2.4 测试Jenkins的CICD

1)在 Jenkins 中安装 kubernetes 和blueocean插件

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

选中 kubernetes 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins--->
http://192.168.40.180:30002/restart-->重启之后登陆 jenkins,插件即可生效
备注:blueocean插件安装流程和安装kubernetes插件一致

2)配置 jenkins 连接到我们存在的 k8s 集群

访问地址 http://192.168.140.130:30002/configureClouds/,新增一个云,在下拉菜单中选择 kubernets 并添加

3)填写kubenetes信息

kubenetes地址:https://192.168.140.130:6443

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

点击连接测试,如果显示 Connection test successful 或者Connected to Kubernetes v1.20.6,说明测试成功, Jenkins 可以和 k8s 进行通信。

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

配置 k8s 集群的时候 jenkins 地址需要写上面域名的形式,配置之后执行如下:应用------>保存

5)配置pod template

访问地址 http://192.168.140.130:30002/configureClouds/,

 按照如下配置:

6)在上面的 pod template 下添加容器

添加容器------>Container Template------>按如下配置

备注:Docker镜像jenkins-slave-latest:v1为 docker  load   -i   jenkins-slave-latest.tar.gz获取,jenkins-slave-latest.tar.gz需要上传到工作节点。

7)在每一个 pod template 右下脚都有一个高级,点击高级,出现如下

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

8)给上面的 pod template 添加卷

添加卷------>选择 Host Path Volume

/var/run/docker.sock
/var/run/docker.sock
/root/.kube
/home/jenkins/.kube

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

9)添加docker harbor凭证

首页------>系统管理→Manage Credentials(管理凭据) 

用户名:admin

密码:Harbor12345

ID:dockerharbor

2.5  Jenkins 部署应用发布到 k8s 开发环境、测试环境

1)在 k8s-master 的控制节点创建名称空间:

[root@ks-master ~]# kubectl create ns devlopment
[root@ks-master ~]# kubectl create ns qatest
[root@ks-master ~]# kubectl create ns production

 2) jenkins创建任务

pipeline文件

node('lmzf') {
    stage('Clone') {
        echo "1.Clone Stage"
        git url: "http://192.168.140.132:8001/root/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.140.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.140.132 -u ${dockerHubUser} -p ${dockerHubPassword}"
            sh "docker push 192.168.140.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"
        }
    }
}

3)立即构建--->点击左下角进度条---->Console Output

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/672482.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

day-37 最大正方形

思路 动态规划&#xff0c;这题主要得弄明白状态转换方程&#xff0c;dp[i][j]表示以&#xff08;i,j&#xff09;为右下角的最大正方形 解题方法 1.首先将第一行和第一列初始化&#xff0c;当对应位置的matrix为’0’时&#xff0c;dp数组对应位置也为零&#xff0c;否则为1 …

上位机图像处理和嵌入式模块部署(f407 mcu中fatfs中间件使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们已经实现了spi norflash的驱动&#xff0c;理论上这已经可以实现数据的持久化保存了。为什么还需要一个文件系统呢&#xff1f;主要原因还…

HTML静态网页成品作业(HTML+CSS)——家乡常德介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

【Qt 学习笔记】Qt窗口 | 对话框 | Qt对话框的分类及介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | 对话框 | 模态对话框 文章编号&#xff1a;Qt 学习笔记 / 51…

API开发秘籍:揭秘Swagger与Spring REST Docs的文档自动化神技

在这个数字化时代&#xff0c;如何让你的业务像外卖一样快速送达顾客手中&#xff1f;本文将带你走进Spring Boot的世界&#xff0c;学习如何利用RESTful API构建一个高效、直观的“外卖帝国”。从基础的REST架构风格&#xff0c;到Spring MVC的魔力&#xff0c;再到Swagger和S…

解决kettle界面右上角的connect消失——且使用admin登录不上Kettle资源库

一、问题描述 1.1、Kettle界面右上角的connect消失了 当我们配置Kettle界面的资源库(Other Repositories)内容后,Kettle界面右上角的connect消失了;如下图所示: 1.2、使用默认的账户【admin】和密码【admin】登录不上kettle资源库 当我们切换到我们配置的数据库使用超管账…

排序-希尔排序

介绍 希尔排序属于那种没有了解过的直接看代码一脸懵逼的&#xff0c; 所以同学们尽量不要直接看代码&#xff0c;仔细阅读本篇博客内容。 插入排序本来算是一个低效排序&#xff0c; 一次只可以挪动一个数据&#xff0c; 但是&#xff0c;它的强来了&#xff01;&#xff01…

513.找树左下角的值

给定一个二叉树&#xff0c;在树的最后一行找到最左边的值。 示例 1: 示例 2: 思路&#xff1a; 深度最大的叶子结点一定是最后一行。 优先左边搜索&#xff0c;记录深度最大的叶子节点&#xff0c;此时就是树的最后一行最左边的值 代码&#xff1a; class Solution:def fi…

272 基于matlab的形态滤波和局域值分解(LMD)的齿轮故障诊断

基于matlab的形态滤波和局域值分解&#xff08;LMD&#xff09;的齿轮故障诊断&#xff0c;GUI交互界面。通过形态滤波对一维信号进行降噪处理&#xff0c;并通过LMD局部均值分解提取故障信号&#xff0c;最后提取处故障频率。程序已调通&#xff0c;可直接运行。 272 形态滤波…

红外听力教学考试系统-红外语音听力广播在大学英语四六级听力考试中应用

红外听力教学考试系统-红外语音听力广播在大学英语四六级听力考试中的应用 由北京海特伟业科技有限公司任洪卓发布于2024年6月1日 红外语音听力广播&#xff08;即红外听力教学考试系统&#xff09;在英语四六级听力考试的应用正日益凸显出其重要性和优越性。在当前的高等教育…

排序-插入排序与选择排序

插入排序 基本思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 打扑克牌整理手牌用的就是插入排序的思想 代码实现 void InsertSort(int* a, int n) { assert(a); …

中间件模版引擎

文章目录 中间件1.自定义中间件1&#xff09;全局2&#xff09;局部中间件 2.内置中间件(静态资源目录&#xff09; Art-template1.模板语法1&#xff09;输出2&#xff09;原文输出3&#xff09;条件判断4&#xff09;循环5&#xff09;子模版6&#xff09;模版继承7&#xff…

2024四川三支一扶“考生信息表”照着填❗

2024四川三支一扶“考生信息表”照着填❗ ☑️四川三支一扶开始报名&#xff0c;大家要按照提示如实、准确、完整填写《高校毕业生“三支一扶”计划招募考生信息表》哦~ ☑️不知道怎么填写的宝子们&#xff0c;可以参考图1。 ☑️毕业证书编号如实填写&#xff0c;若是应届生&…

vue3 todolist 简单例子

vue3 简单的TodList 地址&#xff1a; https://gitee.com/cheng_yong_xu/vue3-composition-api-todo-app-my 效果 step-1 初始化项项目 我们不采用vue cli 搭建项目 直接将上图文件夹&#xff0c;复制到vscode编辑器&#xff0c;清空App.vue的内容 安装包 # 安装包 npm…

JVM双亲委派模型

在之前的JVM类加载器篇中说过&#xff0c;各个类加载器都有自己加载的范围&#xff0c;比如引导类加载器只加载Java核心库中的class如String&#xff0c;那如果用户自己建一个包名和类名与String相同的类&#xff0c;会不会被引导类加载器加载。可以通过如下代码测试&#xff0…

每周统计-20240531

用于测试程序的稳定性&#xff1a; 龙虎榜&#xff1a; 成交额&#xff1a; 封成比&#xff1a; 收盘前放量&#xff1a; 开盘抢筹&#xff1a; 封单额&#xff1a;

堆排序-java

这次主要讲了堆排序和堆的基本构造&#xff0c;下一期会详细讲述堆的各种基本操作。 文章目录 前言 一、堆排序 1.题目描述 2.堆 二、算法思路 1.堆的存储 2. 结点下移down 3.结点上移up 4.堆的基本操作 5.堆的初始化 三、代码如下 1.代码如下&#xff1a; 2.读入数据&#xff…

24年护网工具,今年想参加护网的同学要会用

24年护网工具集 吉祥学安全知识星球&#x1f517;http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247483727&idx1&sndb05d8c1115a4539716eddd9fde4e5c9&chksmc0e47813f793f105017fb8551c9b996dc7782987e19efb166ab665f44ca6d900210e6c4c0281&scene21…

2024拼多多 最新理论+实战干货,从入门到精通全链路多角度学习-7节课

基于最新规则理论结合实际的干货 课程内容&#xff1a; 01 2024年多多防比价新规则破局理论课与实操课.mp4 02 24年多多强付费第二节课基础内功.mp4 03 24年多多强付费第三节课直通车实操 .mp4 04 24年多多强付费第一节课市场定价格段,mp4 05 24年多多自然流第一节课市场…

Java+SVNCloud+Mysql课程设计

文章目录 1、主要内容2、所需准备3、与sql访问的中间类&#xff1a;SqlMessage4、窗口界面5、main方法 1、主要内容 课程设计&#xff0c;主要通过Javas wing创建窗口&#xff0c;jdbc连接云端mysql数据库进行基本操作&#xff0c;支持随机生成数据并用动态展示数据结果。 先…