基于K8s构建Jenkins持续集成平台(部署流程)

您所在的位置:网站首页 jenkins分布式部署 基于K8s构建Jenkins持续集成平台(部署流程)

基于K8s构建Jenkins持续集成平台(部署流程)

#基于K8s构建Jenkins持续集成平台(部署流程)| 来源: 网络整理| 查看: 265

文章目录 一、传统Jenkins的Master-Slave方案的缺陷二、K8s+Docker+Jenkins持续集成架构1. 架构图2. 持续集成优点 三、K8S 集群部署1. 环境配置2. 安装kubelet、kubeadm、kubectl3.Master节点上进行配置4. 安装Calico5.Slave节点6. 验证部署结果 四、部署配置 NFS1. 安装NFS服务2. 创建共享目录3. 启动服务4. 查看NFS共享目录 五、K8S上安装Jenkins-Master1. 创建NFS client provisioner2. 安装 Jenkins-Master3. Jenkins控制台配置 六、Jenkins与Kubernetes整合1. 实现Jenkins与K8s整合2. 构建Jenkins-Slave自定义镜像3. Jenkins-slave流水线项目测试 七、基于kubernetes平台微服务的部署1. 拉取代码,创建镜像2. 配置eureka服务3.zuul4.admin5.gathering6.依次构建3个子服务6.1 zuul6.2 admin6.3 gathering 7. postman 测试数据库

一、传统Jenkins的Master-Slave方案的缺陷 Master节点发生单点故障时,整个流程都不可用了每个 Slave节点的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲资源分配不均衡,有的 Slave节点要运行的job出现排队等待,而有的Slave节点处于空闲状态资源浪费,每台 Slave节点可能是实体机或者VM,当Slave节点处于空闲状态时,也不会完全释放掉资源

可以引入Kubernates来解决

二、K8s+Docker+Jenkins持续集成架构 1. 架构图

在这里插入图片描述 在这里插入图片描述 大致工作流程:手动/自动构建 -> Jenkins 调度 K8S API ->动态生成 Jenkins Slave pod -> Slave pod 拉取 Git 代码/编译/打包镜像 ->推送到镜像仓库 Harbor -> Slave 工作完成,Pod 自动销毁 ->部署到测试或生产 Kubernetes平台。(完全自动化,无需人工干预)

2. 持续集成优点

服务高可用: 当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master 容器,并且将 Volume 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用。

动态伸缩,合理使用资源: 每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。

扩展性好: 当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。

三、K8S 集群部署 1. 环境配置 主机名称IP地址安装的软件Gitlab服务器192.168.74.11Gitlab-12.4.2harbor仓库服务器192.168.74.7Harbor1.9.2master192.168.74.4kube-apiserver、kube-controller-manager、kube- scheduler、docker、etcd、calico,NFSnode1192.168.74.5kubelet、kubeproxy、Docker18.06.1-cenode2192.168.74.6kubelet、kubeproxy、Docker18.06.1-ce

三台k8s服务器上操作 安装 Docker:

#环境配置 hostnamectl set-hostname master && su hostnamectl set-hostname node1 && su hostnamectl set-hostname node2 && su vim /etc/resolv.conf nameserver 114.114.114.114 #关闭防火墙,selinux,swap systemctl stop firewalld && systemctl disable firewalld setenforce 0 #永久关闭 vim /etc/selinux/config SELINUX=disabled swapoff -a #永久关闭需进入配置文件注释掉以下段 vim /etc/fstab .... /dev/mapper/cl-swap swap swap defaults 0 0 .... #安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像源 cd /etc/yum.repos.d/ yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装 docker-ce 社区版 yum install -y docker-ce systemctl start docker systemctl enable docker #配置镜像加速,官方网址可参考:https://help.aliyun.com/document_detail/60750.html mkdir -p /etc/docker #直接命令行输入以下内容: sudo tee /etc/docker/daemon.json "registry-mirrors": ["https://wrdun890.mirror.aliyuncs.com"], "insecure-registries": ["192.168.74.7:85"] } systemctl daemon-reload systemctl restart docker #网络优化 vim /etc/sysctl.conf net.ipv4.ip_forward=1 sysctl -p systemctl restart network systemctl restart docker docker version

配置基础环境

cat >> /etc/hosts //引用jenkins-slave的pod模块来构建Jenkins-Slave的pod node("jenkins-slave"){ stage('拉取代码'){ checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]]) } } }

构建时再开一个窗口观察,node1节点运作在这里插入图片描述 可以看到构建的时候,创建了slave节点,构建是由slave进行的; 而当项目构建完成以后,这个slave节点就消失了!

七、基于kubernetes平台微服务的部署 1. 拉取代码,创建镜像

创建流水线项目 在这里插入图片描述

创建NFS共享目录,让所有Jenkins-Slave构建指向NFS的Maven的共享仓库目录

vim /etc/exports #添加内容: /opt/nfs/jenkins *(rw,no_root_squash) /opt/nfs/maven *(rw,no_root_squash) systemctl restart nfs

编写构建Pipeline 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

tensquare_eureka_server@10086,tensquare_zuul@10020,tensquare_admin_service@9001,tensquare_gathering@9002 注册中心,服务网关,认证中心,活动微服务

上述所有逗号都要用英文

继续添加字符串参数

在这里插入图片描述 在这里插入图片描述 配置harbor凭证 在这里插入图片描述 脚本文件

def git_address = "http://192.168.8.18:82/gl/tensquare_back.git" def git_auth = "da4091ce-712f-42fa-a3a8-d8aad6a166c1" //构建版本的名称 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.8.20:85" //Harbor的项目名称 def harbor_project_name = "tensquare" //Harbor的凭证 def harbor_auth = "c77a32ac-33a1-4855-947c-b0c4d788c555" podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [ containerTemplate( name: 'jnlp', image: "192.168.8.20:85/library/jenkins-slave-maven:latest" ), containerTemplate( name: 'docker', image: "docker:stable", ttyEnabled: true, command: 'cat' ), ], volumes: [ hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'), nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress: '192.168.8.12' , serverPath: '/opt/nfs/maven'), ], ) { node("jenkins-slave"){ // 第一步 stage('pull code'){ checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]]) } // 第二步 stage('make public sub project'){ //编译并安装公共工程 sh "mvn -f tensquare_common clean install" } // 第三步 stage('make image'){ //把选择的项目信息转为数组 def selectedProjects = "${project_name}".split(',') for(int i=0;i //给镜像打标签 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登录Harbor,并上传镜像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登录 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上传镜像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //删除本地镜像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" } } } } }

在构建过程会发现无法创建仓库目录,是因为NFS共享目录权限不足,需更改权限

mkdir -p /opt/nfs/maven chmod -R 777 /opt/nfs/maven #Docker命令执行权限问题(node节点) chmod 777 /var/run/docker.sock

进行构建测试 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

这是第一次下载maven组件,所以时间会有些长

2. 配置eureka服务

安装插件Kubernetes Continuous Deploy

在这里插入图片描述 添加k8s凭证

[root@master ~]# cd .kube/ [root@master .kube]# ls cache config http-cache [root@master .kube]# cat config

在这里插入图片描述 在这里插入图片描述 复制id

在这里插入图片描述 编写pipeline脚本

def git_address = "http://192.168.74.11:82/web_demo/tensquare_back.git" def git_auth = "2736b833-5457-4aa1-bb97-6d353bb5977d" //构建版本的名称 def tag = "latest" //Harbor私服地址 def harbor_url = "192.168.74.7:85" //Harbor的项目名称 def harbor_project_name = "tensquare" //Harbor的凭证 def harbor_auth = "4b806397-44dd-42c9-8a4c-38d298c1f86b" //k8s的凭证 def k8s_auth="a74bad1a-3efb-4143-8816-a4f5a0a3cf3b" //定义k8s-barbor的凭证 def secret_name="registry-auth-secret" podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [ containerTemplate( name: 'jnlp', image: "192.168.74.7:85/library/jenkins-slave-maven:latest" ), containerTemplate( name: 'docker', image: "docker:stable", ttyEnabled: true, command: 'cat' ), ], volumes: [ hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'), nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress: '192.168.74.4' , serverPath: '/opt/nfs/maven'), ], ) { node("jenkins-slave"){ // 第一步 stage('pull code'){ checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]]) } // 第二步 stage('make public sub project'){ //编译并安装公共工程 sh "mvn -f tensquare_common clean install" } // 第三步 stage('make image'){ //把选择的项目信息转为数组 def selectedProjects = "${project_name}".split(',') for(int i=0;i //给镜像打标签 sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}" //登录Harbor,并上传镜像 withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { //登录 sh "docker login -u ${username} -p ${password} ${harbor_url}" //上传镜像 sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}" } //删除本地镜像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}" } def deploy_image_name = "${harbor_url}/${harbor_project_name}/${imageName}" //部署到K8S sh """ sed -i 's#\$IMAGE_NAME#${deploy_image_name}#' ${currentProjectName}/deploy.yml sed -i 's#\$SECRET_NAME#${secret_name}#' ${currentProjectName}/deploy.yml """ kubernetesDeploy configs: "${currentProjectName}/deploy.yml", kubeconfigId: "${k8s_auth}" } } } }

eureka目录下创建deploy.yml文件

在这里插入图片描述

--- apiVersion: v1 kind: Service metadata: name: eureka labels: app: eureka spec: type: NodePort ports: - port: 10086 name: eureka targetPort: 10086 selector: app: eureka --- apiVersion: apps/v1 kind: StatefulSet metadata: name: eureka spec: serviceName: "eureka" replicas: 2 selector: matchLabels: app: eureka template: metadata: labels: app: eureka spec: imagePullSecrets: - name: $SECRET_NAME containers: - name: eureka image: $IMAGE_NAME ports: - containerPort: 10086 env: - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: EUREKA_SERVER value: "http://eureka-0.eureka:10086/eureka/,http://eureka- 1.eureka:10086/eureka/" - name: EUREKA_INSTANCE_HOSTNAME value: ${MY_POD_NAME}.eureka podManagementPolicy: "Parallel"

更改application.yml配置文件

server: port: ${PORT:10086} spring: application: name: eureka eureka: server: # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms) eviction-interval-timer-in-ms: 5000 enable-self-preservation: false use-read-only-response-cache: false client: # eureka client间隔多久去拉取服务注册信息 默认30s registry-fetch-interval-seconds: 5 serviceUrl: defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/} instance: # 心跳间隔时间,即发送一次心跳之后,多久在发起下一次(缺省为30s) lease-renewal-interval-in-seconds: 5 # 在收到一次心跳之后,等待下一次心跳的空档时间,大于心跳间隔即可,即服务续约到期时间(缺省为90s) lease-expiration-duration-in-seconds: 10 instance-id: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.l ong(1000000,9999999)} hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}

提交修改的配置文件和yml文件

在这里插入图片描述 在这里插入图片描述 k8s访问harbor需要密钥权限

docker login -u tom -p Abcd1234 192.168.74.7:85 kubectl create secret docker-registry registry-auth-secret --docker-server=192.168.74.7:85 --docker-username=tom --docker-password=Abcd1234 -- [email protected] kubectl get secrets kubectl get pods kubectl get service

在这里插入图片描述 可以使用kubectl get pods查看是否构建成功 在这里插入图片描述

在这里插入图片描述

访问两个node节点的30708端口

在这里插入图片描述

把其余三个子服务的yml配置文件修改

3.zuul

修改 application.yml 中的 eureka 地址

http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/

在这里插入图片描述

创建配置文件deploy.yml如下(其他项目名字和端口进行修改即可)

--- apiVersion: v1 kind: Service metadata: name: zuul labels: app: zuul spec: type: NodePort ports: - port: 10020 name: zuul targetPort: 10020 selector: app: zuul --- apiVersion: apps/v1 kind: StatefulSet metadata: name: zuul spec: serviceName: "zuul" replicas: 2 selector: matchLabels: app: zuul template: metadata: labels: app: zuul spec: imagePullSecrets: - name: $SECRET_NAME containers: - name: zuul image: $IMAGE_NAME ports: - containerPort: 10020 podManagementPolicy: "Parallel" 4.admin

修改application.yml配置文件

http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/

deploy.yml

--- apiVersion: v1 kind: Service metadata: name: admin labels: app: admin spec: type: NodePort ports: - port: 9001 name: admin targetPort: 9001 selector: app: admin --- apiVersion: apps/v1 kind: StatefulSet metadata: name: admin spec: serviceName: "admin" replicas: 2 selector: matchLabels: app: admin template: metadata: labels: app: admin spec: imagePullSecrets: - name: $SECRET_NAME containers: - name: admin image: $IMAGE_NAME ports: - containerPort: 9001 podManagementPolicy: "Parallel" 5.gathering

修改application.yml配置文件

http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/

deploy.yml

--- apiVersion: v1 kind: Service metadata: name: gathering labels: app: gathering spec: type: NodePort ports: - port: 9002 name: gathering targetPort: 9002 selector: app: gathering --- apiVersion: apps/v1 kind: StatefulSet metadata: name: gathering spec: serviceName: "gathering" replicas: 2 selector: matchLabels: app: gathering template: metadata: labels: app: gathering spec: imagePullSecrets: - name: $SECRET_NAME containers: - name: gathering image: $IMAGE_NAME ports: - containerPort: 9002 podManagementPolicy: "Parallel"

完成后全部提交gitlab仓库

6.依次构建3个子服务 6.1 zuul

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

6.2 admin

在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

6.3 gathering

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

7. postman 测试数据库

因为各个微服务的 application.yml 中 mysql 数据库的地址为 192.168.74.8,我们还用以前实验的那台机器中的数据库

在这里插入图片描述

现在的生产服务器地址为 k8s 节点的地址,访问端口为映射的端口 在这里插入图片描述 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3