在Google Kubernetes集群创建分布式Jenkins(一)

因为项目需要,在GKE的集群上需要创建一个CICD的环境,记录一下安装部署一个分布式Jenkins集群的过程。

分布式Jenkins由一个主服务器和多个Agent组成,Agent可以执行主服务器分派的任务。如下图所示:

如上图,Jenkins Agent可以运行不同的操作系统,执行主服务器分派的编译打包或测试等任务。

在Jenkins的官网上介绍了在K8S上安装的几种方式,包括了Helm, operator等。但是我直接用Helm最新版的Jenkins安装始终遇到问题,日志报错信息是Google的OAUTH插件编译有问题,如果用旧版本的可以安装成功,但是我不想用旧的版本,而新版本的问题暂时没找到解决的思路,另外Helm安装的values配置过于繁杂。我考虑用最传统的Yaml manifest的方式来部署这个Jenkins。

创建Jenkin主服务器

首先是创建namespace的manifest,配置如下:

apiVersion: v1
kind: Namespace
metadata:name: "jenkins"labels:name: "jenkins"

定义Storage class的manifest

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: storage-jenkins
provisioner: kubernetes.io/gce-pd
parameters:type: pd-standardfstype: ext4
volumeBindingMode: WaitForFirstConsumer

定义PVC,保存Jenkins的相关数据

kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: jenkins-pvc namespace: jenkins
spec:accessModes:- ReadWriteOncestorageClassName: "storage-jenkins" resources:requests:storage: 30Gi 

然后就是创建一个deployment,部署Jenkins pod,注意在containers的env里面增加了一个环境变量,定义了jenkins uri的前缀,然后在probe的path里也相应的加了/jenkins前缀。

apiVersion: apps/v1
kind: Deployment
metadata:name: jenkinsnamespace: jenkins
spec:selector:matchLabels:app: jenkinsreplicas: 1template:metadata:labels:app: jenkinsspec:volumes:- name: pvc-jenkins persistentVolumeClaim:claimName: jenkins-pvc containers:- name: jenkinsimage: "jenkins/jenkins:lts"securityContext:runAsUser: 0volumeMounts:- mountPath: "/var/jenkins_home/"name: pvc-jenkinsenv:- name: JENKINS_OPTSvalue: --prefix=/jenkins ports:- containerPort: 8080- containerPort: 50000 resources:limits:cpu: "2"memory: "4Gi"requests:cpu: "1"memory: "2Gi"livenessProbe:httpGet:path: "/jenkins/login"port: 8080initialDelaySeconds: 90periodSeconds: 10timeoutSeconds: 5failureThreshold: 5readinessProbe:httpGet:path: "/jenkins/login"port: 8080initialDelaySeconds: 60periodSeconds: 10timeoutSeconds: 5failureThreshold: 3

创建一个service来暴露Jenkins的地址和端口,注意这里加了GCP的neg注解,使得可以使用ingress来暴露,另外指定了jenkins agent和jenkis master之间通讯的接口50000

apiVersion: v1
kind: Service
metadata:name: jenkins-svcnamespace: jenkinsannotations:cloud.google.com/neg: '{"ingress": true}'labels:app: jenkins
spec:ports:- name: jenkinsportport: 8080targetPort: 8080- name: slaveconnectorsport: 50000targetPort: 50000selector:app: jenkins

再创建一个ingress,使得可以从公网访问

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: jenkins-ingressnamespace: jenkins
spec:rules:- http:paths:- path: /jenkinspathType: Prefixbackend:service:name: jenkins-svcport:number: 8080

最后创建一个kustomization.yaml,把以上部分组合起来

resources:- namespace.yaml- storage-class.yaml- pvc.yaml- deployment.yaml- service.yaml- ingress.yaml

然后运行命令kubectl apply -k kustomization_dir/即可部署。等待ingress创建完成后,在gcp console的网页上找到相应的地址,在浏览器上访问即可进入jenkins的配置页面。如果不能访问,我们需要检查一下Firewall是否没有放通。

初次访问配置页面,需要输入admin password,这个可以从Jenkins pod的日志查到。

kubectl logs <jenkins_pod_name> -n jenkins

之后我们可以安装建议的插件,然后创建一个Jenkins的用户

安装Jenkins动态Agent

有了主服务器之后,我们就可以配置动态Agent了。以下是Jenkins创建动态Agent的流程图

  1. 当触发Jenkins任务的时候,Jenkins kubernetes插件会给K8S服务器发起一个API调用,创建一个Agent pod.
  2. 这个Jenkins agent pod会运行在K8S上来运行Jenkins任务,当任务完成时会自动中止。
  3. 当Jenkins agent pod启动时,会读取环境变量配置并和Jenkins主服务器通过JNLP的方式沟通。

安装Jenkins kubernetes插件

在Jenkins的Manage Jenkins页面,选择Plugin,搜索Kubernetes并安装。安装完成后重启Jenkins

1. 连接Kubernetes

在Jenkins的Manage Jenkins->Clouds->New Cloud,类型选择Kubernetes.

然后在配置项里面,Kubernetes url和Kubernetes server certificate key都不用输入,因为我们的Jenkins master server是在同一个Kubernetes里面。Namespace输入jenkins。然后赋予jenkins这个namespace下的default用户cluster-admin的role。如以下命令:

kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=jenkins:default

点击Test Connection,如果正常就会显示连接成功。

2. 配置Jenkins URL

输入Jenkins service的internal DNS的名称,因为我们之前定义了jenkins前缀,所以URL是http://jenkins-svc.jenkins.svc.cluster.local:8080/jenkins

3. 创建Pod和Container template

Pod label key设置为jenkins,value设置为slave。Pod template name输入jenkins-slave,namespace输入Jenkins,labels输入slave。Containers里面先不加container template,Jenkins默认是用Jenkins/inbound-agent这个镜像

然后需要Add volume detail,因为我们的Jenkins agent是docker in docker,所以需要选择Host path volume,然后把kubernetes节点的docker daemon socket mount到Jenkins agent pod. 在Host path和mount path分别输入/var/run/docker.sock

4. 配置Service Account

因为Jenkins agent pod需要权限来调用GCP的服务,例如推送image到repository等。需要创建一个service account来给agent使用。

首先在K8S的jenkins namespace创建一个service account

kubectl create serviceaccount jenkins-sa --namespace jenkins

在GCP IAM里面创建一个service account

gcloud iam service-accounts create jenkins-sa --project=PROJECT_ID

给这个service account赋予需要的role,可以用以下命令

gcloud projects add-iam-policy-binding PROJECT_ID --member "serviceAccount:jenkins-sa@PROJECT_ID.iam.gserviceaccount.com" --role "ROLE_NAME"

把这两个service account绑定起来,使得K8S的service account可以模仿GCP的service account

gcloud iam service-accounts add-iam-policy-binding jenkins-
sa@PROJECT_ID.iam.gserviceaccount.com --role roles/iam.workloadIdentityUser --member
"serviceAccount:PROJECT_ID.svc.id.goog[jenkins/jenkins-sa]"

Annotate K8S的service account,加上email地址

kubectl annotate serviceaccount jenkins-sa --namespace jenkins
iam.gke.io/gcp-service-account=jenkins-sa@PROJECT_ID-
v1.iam.gserviceaccount.com

最后还要把Run as user id设为0,使得jenkins agent pod以root用户来运行,以避免权限问题。最后Save即可完成配置。

5. 设置Agent连接端口

回到Manage jenkins的manage globle security里面,在Agent的设置下选择指定端口,填入50000

运行Jenkins CICD pipeline

现在可以构建一个CICD pipeline了。下图是构建CICD的一个流程图

这里面包括了几个步骤

  1. 往Git仓库提交代码,通过hook触发jenkins任务
  2. Jenkins启动agent pod,运行打包任务
  3. 把打包的镜像推送到registry
  4. 更新部署的manifest,更新镜像的标签
  5. 把应用部署到GKE

我这里将扩展一下这些步骤,增加Jenkin和Github webhook的集成,使得用户提交PR的时候自动触发UT检查,然后当用户执行merge操作的时候来触发打包任务。这部分的内容比较多,我将在下一篇博客中记录具体的操作过程。

现在我将建立一个简单的任务,测试一下我们配置的Jenkins是否能正常工作。

在主页面选择新建任务,然后选择pipeline,然后在pipeline script里面输入以下内容

pipeline {agent{kubernetes{label 'slave'}}environment {ZONE = "us-central1"PROJECT_ID = "curious-athlete-401708"}stages{      stage("test"){steps{script{sh 'echo "testing"'}}}}
}

运行这个任务,我们可以看到页面会显示自动创建一个jenkins-slave-xxxx的pod,然后在这个pod上运行我们的pipeline。运行结束之后我们可以查看Job的console log,可以看到成功执行了pipeline里面定义的echo testing

可见我们已经成功配置了一个Kubernetes上的分布式jenkins环境。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始搭建微服务(一)

构建项目父工程 添加公共核心模块 安装nacos 安装nacos nacos 文档地址&#xff1a; https://nacos.io/zh-cn/docs/what-is-nacos.html 本文使用版本2.2.2 下载地址&#xff1a;https://github.com/alibaba/nacos/archive/refs/tags/2.2.2.zip 使用nacos 我们下载是源代码 解…

20.8 OpenSSL 套接字SSL传输文件

有了上面的基础那么传输文件的实现就变得简单了&#xff0c;在传输时通常我们需要打开文件&#xff0c;并每次读入1024个字节的数据包&#xff0c;通过SSL加密传输即可&#xff0c;此处的文件传输功能在原生套接字章节中也进行过详细讲解&#xff0c;此处我们还是使用原来的密钥…

【Verilog 教程】7.3 Verilog 串行 FIR 滤波器设计

串行 FIR 滤波器设计 设计说明 设计参数不变&#xff0c;与并行 FIR 滤波器参数一致。即&#xff0c;输入频率为 7.5 MHz 和 250 KHz 的正弦波混合信号&#xff0c;经过 FIR 滤波器后&#xff0c;高频信号 7.5MHz 被滤除&#xff0c;只保留 250KMHz 的信号。 输入频率&#x…

VMware安装CentOS最小化开发环境导引

目录 一、概要 二、介绍 三、下载 四、安装 4.1 创建虚拟机 4.2 安装CentOS 五、配置网卡 六、配置本地安装源 七、安装软件 7.1 gcc/g 7.2 C的atomic库 7.3 java 7.4 Cmake 7.5 MariaDB客户端&#xff08;兼容mysql&#xff09; 八、用户配置文件.bash_profile…

[开源]企业级在线办公系统,基于实时音视频完成在线视频会议功能

一、开源项目简介 企业级在线办公系统 本项目使用了SpringBootMybatisSpringMVC框架&#xff0c;技术功能点应用了WebSocket、Redis、Activiti7工作流引擎&#xff0c; 基于TRTC腾讯实时音视频完成在线视频会议功能。 二、开源协议 使用GPL-3.0开源协议 三、界面展示 部分…

什么是单片机?它是如何工作的?

一.单片机是什么&#xff1f; 家用电器包含各种各样的集成电路板。 在集成电路板上最重要的就是单片机&#xff08;单片微型计算机&#xff09;。它是一种集成电路芯片。 二.单片机的组成 2.1 CPU CPU的主要功能是运算和控制。2.2 ROM 1.是什么&#xff1f; ROM的全称是Re…

Redis03-过期策略和淘汰策略

目录 Redis数据过期策略 Redis数据淘汰策略 Redis数据过期策略 Redis使用一种基于过期策略来处理键的过期和自动失效。这种策略可以确保不再需要的数据被自动删除&#xff0c;以释放内存并避免数据过期后仍然在缓存中存留。 Redis的过期删除策略主要有两种&#xff1a; 惰性…

【SpringSecuirty6.x】自动登录和注销登录

关于网站的安全设计,通常是有一些矛盾点的。我们在作为某些系统开发者的同时,也在充当着另外一些系统的用户,一些感同身受的东西可以带来很多思考。 5.1、为什么需要自动登录 当我们在某个网站上注册账号时,网站会对我们设置的登录密码提出要求。例如,有的网站要求使用固…

VS编译器中创建新源文件,自动添加----#define _CRT_SECURE_NO_WARNINGS 1

每次创建新的源文件时都需要添加比较麻烦&#xff0c;我们让每次创建时自动添加&#xff0c;步骤如下&#xff1a; 1、右键编译器--->属性--->目标&#xff08;存放的是编译器的文件位置我们找到文件的位置&#xff09; 2、如下步骤找到“newc file.cpp”文件&#xff0…

如何使用Ruby 多线程爬取数据

现在比较主流的爬虫应该是用python&#xff0c;之前也写了很多关于python的文章。今天在这里我们主要说说ruby。我觉得ruby也是ok的&#xff0c;我试试看写了一个爬虫的小程序&#xff0c;并作出相应的解析。 Ruby中实现网页抓取&#xff0c;一般用的是mechanize&#xff0c;使…

Linux安装配置awscli命令行接口工具及其从aws上传下载数据

官网技术文档有全面介绍&#xff1a;安装或更新 AWS CLI 的最新版本 - AWS Command Line Interface在系统上安装 AWS CLI。https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/getting-started-install.html#getting-started-install-instructionsawscli常用命令参考&…

深度学习之基于Tensorflow卷积神经网络花卉识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习是一种机器学习方法&#xff0c;它通过模拟人脑神经网络的结构和功能来实现对数据的自动分析和学习。卷积神…

ClickHouse 学习之基础入门(一)

第 1 章 ClickHouse 入 门 ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库&#xff08;DBMS&#xff09;&#xff0c;使用 C 语言编写&#xff0c;主要用于在线分析处理查询&#xff08;OLAP&#xff09;&#xff0c;能够使用 SQL 查询实时生成分析数据报告。 …

Linux环境基础开发工具使用(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、Linux项目自动化构建工具-make/Makefile1、背景2、实例代码3、依赖关系4、依赖方法5、原理…

【Head First 设计模式】-- 策略模式

一、背景 Head First 设计模式第一章设计模式入门–策略模式 二、工具箱的工具&#xff08;本章&#xff09; 1、OO基础 封装 继承 多态 抽象 2、OO原则 封装变化 面向接口编程&#xff0c;而非面向实现编程 组合优于继承 3、OO模式 策略模式&#xff0c;所谓策略模式就是定义…

spring-boot中实现分片上传文件

一、上传文件基本实现 1、前端效果图展示&#xff0c;这里使用element-ui plus来展示样式效果 2、基础代码如下 <template><div><el-uploadref"uploadRef"class"upload-demo":limit"1":on-change"handleExceed":auto-…

【算法】单调栈 每日温度 接雨水

文章目录 例题739. 每日温度42. 接雨水 相关练习1475. 商品折扣后的最终价格901. 股票价格跨度1019. 链表中的下一个更大节点84. 柱状图中最大的矩形 单调栈【基础算法精讲 26】 例题 739. 每日温度 https://leetcode.cn/problems/daily-temperatures/description/ 提示&a…

Git 的基本操作 ——命令行

Git 的工作流程 详解如下&#xff1a; 本地仓库&#xff1a;是在开发人员自己电脑上的Git仓库,存放我们的代码(.git 隐藏文件夹就是我们的本地仓库) 远程仓库&#xff1a;是在远程服务器上的Git仓库,存放代码(可以是github.com或者gitee.com 上的仓库,或者自己该公司的服务器…

php去除字符串两边空格空字符串换行方法

在PHP中&#xff0c;可以使用以下几种方法去除字符串两边的空格、空字符串和换行符&#xff1a; 使用trim()函数去除字符串两边的空格和空字符串&#xff0c;例如&#xff1a; $str " Hello World! "; $trimmed trim($str); echo $trimmed; 使用preg_replace(…

Angular-07:组件生命周期

三个阶段&#xff1a; ① 挂载阶段1.1 constructor1.2 ngOnInit ② 更新阶段2.1 ngOnChanges2.2 ngAfterViewInit2.3 ngAfterContentInit2.4 ngDoCheck ③ 卸载阶段3.1 onOnDestroy ④ 在组件中添加所有方法并打印 该表按照执行顺序编写 编号函数名实现名说明1constructorcons…