Jenkins集成Kubernetess

文章目录

1、Kubernetes介绍

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着,管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提升工具以及人性化方面,让用户能够方便的部署自己的应用。

Kubernetes主要能帮助我们完成:

服务发现和负载均衡

  • Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

存储编排

  • Kubernetes 允许你自动挂载你选择的存储系统,比如本地存储,类似Docker的数据卷。

自动部署和回滚

  • 你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。Kubernetes 会自动帮你根据情况部署创建新容器,并删除现有容器给新容器提供资源。

自动完成装箱计算

  • Kubernetes 允许你设置每个容器的资源,比如CPU和内存。

自我修复

  • Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的容器,并运行状况检查的容器。

秘钥与配置管理

  • Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

2、Kubernetes架构

Kubernetes 搭建需要至少两个节点,一个Master负责管理,一个Slave搭建在工作服务器上负责分配。

kubernetes架构

从图中可以看到各个组件的基本功能

组件 功能
API Server 作为K8s通讯的核心组件,K8s内部交互以及接收发送指令的组件。
controller-manager 作为K8s的核心组件,主要做资源调度,根据集群情况分配资源
etcd 一个key-value的数据库,存储存储集群的状态信息
scheduler 负责调度每个工作节点
cloud-controller-manager 负责调度其他云服务产品
kubelet 管理Pods上面的容器。
kube-proxy 负责处理其他Slave或客户端的请求。
Pod 可以理解为就是运行的容器

3、Jenkins集成Kubernetes

集成K8s后的DevOps流程

1_准备部署的yaml文件

准备ingressservicedeployment控制器等资源,nginx-ingress需要额外安装

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: test
  name: pipeline
  labels:
    app: pipeline
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pipeline
  template:
    metadata:
      labels:
        app: pipeline    
    spec:
      containers:
      - name: pipeline
        image: 192.168.150.117:80/repo/pipeline:v4.0.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
      imagePullSecrets:
      - name: my-harbor-secret  # 引用后面创建的 secret 名称
---
apiVersion: v1
kind: Service
metadata:
  namespace: test
  labels:
    app: pipeline
  name: pipeline  
spec:
  selector:
    app: pipeline
  ports:
  - port: 8081
    targetPort: 8080
  type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: test
  name: pipeline
spec:
  ingressClassName: nginx
  rules:
  - host: www.pipeline.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pipeline
            port:
              number: 8081

2_Harbor私服配置

在尝试用Kubernetes的yaml文件启动pipeline服务时,会出现Kubernetes无法拉取镜像的问题,这里需要在Kubernetes所在的Linux中配置Harbor服务信息,并且保证Kubernetes可以拉取Harbor上的镜像

设置Master和Worker的私服地址信息,别忘了重启docker加载配置变更

设置Harbor私服地址

在 Kubernetes 上设置私服密文信息,将登录凭证添加到 Kubernetes 中,以便从私有 Harbor 仓库拉取镜像

shell 复制代码
kubectl create secret docker-registry my-harbor-secret \
  --docker-server=192.168.150.117:80 \
  --docker-username=admin \
  --docker-password=Harbor12345 \
  --docker-email=your-email@example.com \
  -n test # 注意要在同一命名空间下

创建完 secret 后,还需要将其引用到 Pod 配置文件中,告诉 Kubernetes 在拉取镜像时使用这个凭证,上面yaml文件中已经提前添加了。

按照docker正常登录远程仓库进行测试,效果如下

测试效果

3_测试使用效果

执行kubectl命令,基于yaml启动服务,并且基于部署后服务的提示信息以及Ingress的设置,直接访问

创建pipeline应用后访问测试(需要配置hosts)

4_Jenkins远程调用

pipeline.yaml配置到Gitlab中

配置yml文件

配置Jenkins的目标服务器,使用Publish over SSH插件将yaml文件传输到K8s的Master节点上

设置目标服务器,远程工作目录需提前创建

生成流水线语法

生成向k8s传递pipeline.yaml文件的流水线语法

修改Jenkinsfile,重新设置流水线任务脚本,并测试效果

传递yml文件脚本

设置Jenkins无密码登录k8s-master,需要将Jenkins中公钥信息复制到k8s-master节点的~/.ssh/authorized_keys中,保证远程连接无密码

shell 复制代码
# 进入到Jenkins容器内部
[root@jenkins ~]# docker exec -it jenkins bash
# 切换到 ~/.ssh目录下
jenkins@f90f9fee0c32:~/.ssh$ cd ~/.ssh
# 查看是否有密钥对,如果没有则需要生成一个
jenkins@f90f9fee0c32:~/.ssh$ ls
id_rsa	id_rsa.pub  known_hosts
# 查看公钥并复制下来
jenkins@f90f9fee0c32:~/.ssh$ cat id_rsa.pub
ssh-rsa A*g2Q== jenkins@f90f9fee0c32 # 密钥略
# 在k8s-master节点上添加复制的公钥,如果没有这个文件需要先创建
[root@master ~]# touch ~/.ssh/authorized_keys
[root@master ~]# vi ~/.ssh/authorized_keys
jenkins@f90f9fee0c32:~/.ssh$ cat id_rsa.pub # 密钥略

查看配置后的执行结果

远程执行命令无需密码

设置执行kubectl的脚本到Jenkinsfile

设置Jenkinsfile

执行查看效果

执行流水线

可以查看到yaml文件是有变化的, 这样k8s就会重新加载,查看效果(版本很顺滑的从v4->v6)

效果

Ps:这种方式更适应于CD操作,将项目将基于某个版本部署到指定的目标服务器


4、基于GitLab的WebHooks

这里要实现自动化的一个CI操作,也就是开发人员Push代码到Git仓库后,Jenkins会自动的构建项目,将最新的提交点代码构建并进行打包部署,这里区别去上述的CD操作,CD操作需要基于某个版本进行部署,而这里每次都是将最新的提交点集成到主干上并测试(需要用到Gitlab Plugin)。


1_WebHooks通知

开启Jenkins的自动构建

构建触发器

经发现某些 GitLab 的 Webhook 配置可能会对 URL 的格式进行校验,拒绝使用裸露的 IP 地址作为 URL

shell 复制代码
# 可以设置域名解析(非必要)
echo "192.168.150.121 www.jenkins.com" >> /etc/hosts

需要做一些先前的准备工作,关闭Jenkins的Gitlab认证,开启Gitlab的本地网络请求

关闭Jenkins的Gitlab认证

设置Gitlab的Webhooks

设置Gitlab的Webhooks

再次测试Gitlab

再次测试

2_修改配置

更改前的配置,需要替换使用的${tag}

json 复制代码
pipeline {

    agent any

    environment{
        harbor_url = '192.168.150.117:80'
        harbor_project_name = 'repo'
        harbor_user = 'DevOps'
        harbor_passwd = 'Harbor12345'

    }

    stages {
        stage('拉取Git仓库代码') {
            steps {
                checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.150.120:8929/root/mytest.git']])
            }
        }

        stage('通过maven构建项目') {
            steps {
                sh '~/maven/bin/mvn clean package -Dmaven.test.skip=true'
            }
        }

        stage('通过SonarQube做代码质量检测') {
            steps {
                sh '~/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=squ_4a4ffa98d84eb96347798ab3ceb7cb4dd05edec2'
            }
        }

        stage('通过Docker制作自定义镜像') {
            steps {
                sh '''mv ./target/*.jar ./docker/
                docker build -t ${JOB_NAME}:${tag} ./docker/'''
            }
        }

        stage('将自定义镜像推送到Harbor'){
            steps {
                sh '''docker login -u ${harbor_user} -p ${harbor_passwd} ${harbor_url}
                docker tag ${JOB_NAME}:${tag} ${harbor_url}/${harbor_project_name}/${JOB_NAME}:${tag}
                docker push ${harbor_url}/${harbor_project_name}/${JOB_NAME}:${tag}'''
            }
        }

        stage('将yaml文件传到k8s-master上') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

        stage('远程执行k8s-master的kubectl命令'){
            steps {
                sh 'ssh root@192.168.150.104 kubectl apply -f /usr/local/k8s/pipeline.yaml'
            }
        }
        
    }

    post {
        success {
            dingtalk (
                robot: 'Jenkins-DingDing',
                type:'MARKDOWN',
                title: "success: ${JOB_NAME}",
                text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
            )
        }
        failure {
            dingtalk (
                robot: 'Jenkins-DingDing',
                type:'MARKDOWN',
                title: "fail: ${JOB_NAME}",
                text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
            )
        }
    }
}

修改Jenkinsfile实现基于最新提交点实现持续集成效果,将之前引用${tag}的全部去掉

基于最新提交点实现持续集成

修改pipeline.yml,更改镜像版本

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: test
  name: pipeline
  labels:
    app: pipeline
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pipeline
  template:
    metadata:
      labels:
        app: pipeline    
    spec:
      containers:
      - name: pipeline
        image: 192.168.150.117:80/repo/pipeline:latest	# 这里
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
# 省略其他内容............

每次文件的提交和修改都会触发Jenkins的自动构建

查看执行结果

3_滚动更新

将代码的版本从v6.0.0更改为latest

修改代码版本

查看代码修改后的执行结果发现版本并没有发生变化

日志和网页中的结果都告诉我们代码修改后没有任何改变

因为pipeline.yaml没有改变时,每次不会重新加载,这样会导致Pod中的容器不会动态更新,这里需要使用kubectl rollout restart命令滚动更新

设置Jenkinsfle

到这里自动化 CI 就完成了,不仅仅是Gitlab,Github、Gitee也是一样的,只不过需要安装不同的插件


5、总结

在本文中,详细介绍了如何将 Jenkins 与 Kubernetes 集成,以实现自动化的 CI/CD 流程部署。

通过这种集成,可以充分发挥 Kubernetes 的弹性扩展能力与容器化优势,以及 Jenkins 强大的任务管理和插件支持能力。

Jenkins 与 Kubernetes 的集成适用于需要频繁交付、高并发构建任务的团队,特别是在微服务架构或云原生开发环境中。

通过本文的实践步骤,希望您可以快速实现 Jenkins 与 Kubernetes 的高效集成,为 DevOps 流程的优化打下坚实基础。


相关推荐
大霞上仙4 分钟前
jenkins入门2
运维·jenkins
小屁不止是运维8 分钟前
麒麟操作系统服务架构保姆级教程(八)数据库拆分静态业务拆分和负载均衡
运维·服务器·数据库·架构·负载均衡
wq54wq20 分钟前
优化现金流:CRM回款自动化的关键步骤
大数据·运维·人工智能·自动化
Linux运维老纪1 小时前
Nginx常用配置之详解(Detailed Explanation of Common Nginx Configurations)
计算机网络·nginx·微服务·云原生·架构·云计算·运维开发
A charmer1 小时前
告别编程困惑:GDB、冯诺依曼、操作系统速通指南
linux·运维·服务器
檀越剑指大厂1 小时前
【Linux系列】x86 和 AMD 的区别
linux·运维·服务器
激进的猴哥2 小时前
day26-lvm逻辑卷管理
linux·运维
刘某的Cloud2 小时前
cut-命令详解
linux·运维·系统
迷茫运维路2 小时前
graylog+sidecar通过docker-compose部署并采集SSH登录日志
运维·docker·ssh·graylog·pipelines
m0_619731192 小时前
以太网协议和LWIP协议详解
运维·服务器