0


jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介

k8s助力Devops在企业落地实践

传统方式部署项目为什么发布慢,效率低?

在这里插入图片描述

上线一个功能,有多少时间被浪费了?

在这里插入图片描述

如何解决发布慢,效率低的问题呢?

在这里插入图片描述

在这里插入图片描述

什么是Devops?

在这里插入图片描述

在这里插入图片描述

敏捷开发

提高开发效率,及时跟进用户需求,缩短开发周期。

敏捷开发包括编写代码和构建代码两个阶段,可以使用git或者svn来管理代码,用maven对代码进行构建。

持续集成(CI)

持续集成强调开发人员提交了新代码之后,立刻自动的进行构建、(单元)测试。根据测试结果,可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果,对可能出现的一些问题进行预警,以保障最终合并的代码没有问题。

常见的持续集成工具:

  • Jenkins- Jenkins是用Java语言编写的,是目前使用最多和最受欢迎的持续集成工具,使用Jenkins,可以自动监测到git或者svn存储库代码的更新,基于最新的代码进行构建,把构建好的源码或者镜像发布到生产环境。Jenkins还有个非常好的功能:它可以在多台机器上进行分布式地构建和负载测试
  • TeamCity
  • Travis CI
  • Go CD
  • Bamboo
  • GitLab CI
  • Codeship

在这里插入图片描述

它的好处主要有以下几点:

  • 较早的发现错误:每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,哪个环节出现问题都可以较早的发现
  • 快速的发现错误:每完成一部分代码的更新,就会把代码集成到主干中,这样就可以快速的发现错误,比较容易的定位错误
  • 提升团队绩效:持续集成中代码更新速度快,能及时发现小问题并进行修改,使团队能创造出更好的产品
  • 防止分支过多的偏离主干:经常持续集成,会使分支代码经常向主干更新,当单元测试失败或者出现bug,如果开发者需要在没有调试的情况下恢复仓库的代码到没有bug的状态,只有很小部分的代码会丢失

持续集成的目的是提高代码质量,让产品快速的更新迭代。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。

Martin Fowler说过:“持续集成并不能消除bug,而是让它们非常容易发现和纠正。”

持续交付

持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的“类生产环境”中。交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。

如果所有的代码完成之后一起交付,会导致很多问题爆发出来,解决起来很麻烦,所以持续集成,也就是每更新一次代码,都向下交付一次,这样可以及时发现问题,及时解决,防止问题大量堆积。

持续部署

持续部署是指当交付的代码通过评审之后,自动部署到生产环境中。持续部署是持续交付的最高阶段。

在这里插入图片描述

k8s在Devops中的核心作用

docker和k8s的出现使devops变得更加普及,更加容易实现。在传统运维中我们服务时需要针对不同的环境去安装不同的版本,部署方式也杂、多。那么有了docker之后,一次构建、到处运行,只需要构建一次镜像,那么只要有docker的主机,就可以基于镜像把应用跑起来。

在至多微服务中,每天可能需要去处理各种服务的崩溃,而服务间的依赖调用关系也极其复杂,这队解决问题带来了很大的复杂度。要很好的解决这个问题,就需要用到容器编排工具。

kubernetes的出现主宰了容器编排的市场,也进化了过去的运维方式,将开发与运维联系的更加紧密。而且让devops这一角色变得更加清晰,它是目前可用的很流行的容器解决方案之一。

自动化

敏捷开发---->持续集成---->持续交付---->持续部署

多集群管理

可以根据客户需求对开发,测试,生产环境部署多套kubernetes集群,每个环境使用独立的物理资源,相互之间避免影响。

多环境一致性

kubernetes是基于docker的容器编排工具,因为容器的镜像是不可变的,所以镜像把OS、业务代码、运行环境、程序库、目录结构都包含在内,镜像保存在我们的私有仓库,只要用户从我们提供的私有仓库拉取镜像,就能保证环境的一致性。

实时反馈和智能化报表

每次集成或交付,都会第一时间将结果通过多途径的方式反馈给你,也可以定制适合企业专用的报表平台。

前情提要:

  • 我的节点以及k8s版本

在这里插入图片描述

  • 主从的ip:
    ipwentaomaster1192.168.184.10wentaonode1192.168.184.20
    在这里插入图片描述

在这里插入图片描述

安装nfs存储

  1. #安装nfs并设置开机自启动,主从都需要安装[root@wentaomaster1 ~]#yum install -y nfs-utils[root@wentaomaster1 ~]#systemctl enable nfs --now[root@wentaonode1 ~]#yum install -y nfs-utils[root@wentaonode1 ~]#systemctl enable nfs --now

在这里插入图片描述

  1. #配置nfs存储目录,仅在master节点配置[root@wentaomaster1 ~]# vim /etc/exports
  2. /data/v2 *(rw,no_root_squash)#使nfs配置生效[root@wentaomaster1 ~]# exportfs -arv

在这里插入图片描述

创建数据存储挂载

  • 创建项目所用的名称空间
  1. [root@wentaomaster1 jenkins-k8s]# kubectl create namespace jenkins-k8s
  2. namespace/jenkins-k8s created
  • 创建存储用的pv
  1. [root@wentaomaster1 jenkins-k8s]# cat pv.yaml
  2. apiVersion: v1
  3. kind: PersistentVolume
  4. metadata:
  5. name: jenkins-k8s-pv
  6. spec:
  7. capacity:
  8. storage: 10Gi
  9. accessModes:
  10. - ReadWriteMany
  11. nfs:
  12. server: 192.168.184.10
  13. path: /data/v2
  1. [root@wentaomaster1 ~]# kubectl apply -f pv.yaml

在这里插入图片描述

  • 创建pvc
  1. [root@wentaomaster1 jenkins-k8s]# cat pvc.yaml
  2. kind: PersistentVolumeClaim
  3. apiVersion: v1
  4. metadata:
  5. name: jenkins-k8s-pvc
  6. namespace: jenkins-k8s
  7. spec:
  8. resources:
  9. requests:
  10. storage: 10Gi
  11. accessModes:
  12. - ReadWriteMany
  1. [root@wentaomaster1 ~]# kubectl apply -f pvc.yaml

在这里插入图片描述

创建serviceaccount并RBAC授权

  • 创建一个服务账号sa并对其授权
  1. [root@wentaomaster1 ~]# kubectl create sa jenkins-k8s-sa -n jenkins-k8s#对sa服务账号授予系统角色cluster-admin的权限【RBAC】[root@wentaomaster1 ~]# kubectl create clusterrolebinding jenkins-k8s-sa-cluster -n jenkins-k8s --clusterrole=cluster-admin --serviceaccount=jenkins-k8s:jenkins-k8s-sa

在这里插入图片描述

准备项目需要的镜像

  • 工作节点上,从dockerhub上拉取jenkins镜像(我用的2.418)
  1. #用于安装jenkins用[root@wentaonode1 ~]# docker pull jenkins/jenkins:2.418

在这里插入图片描述

  • 创建一个dockerfile构建镜像jenkins-slave-latest:v1
  1. [root@wentaomaster1 slave]# cat dockerfile
  2. FROM jenkins/jnlp-slave:4.13.3-1-jdk11
  3. USER root
  4. # 安装Docker
  5. RUN apt-get update &&apt-getinstall-y\
  6. docker.io
  7. # 将当前用户加入docker用户组
  8. RUN usermod-aGdocker jenkins
  9. RUN curl-LO https://dl.k8s.io/release/stable.txt
  10. RUN curl-LO https://dl.k8s.io/release/$(cat stable.txt)/bin/linux/amd64/kubectl
  11. RUN chmod +x kubectl
  12. RUN mv kubectl /usr/local/bin/
  13. ENV DOCKER_HOST unix:///var/run/docker.sock
  14. #k8s中装好jenkins后,是有主从的,构建jenkins时候会在集群里再创建一个jenkins从,我用jenkins-slave-latest这个镜像来构建jenkins从[root@wentaomaster1 slave]# docker build -t=jenkins-slave-latest:v1 .

在这里插入图片描述

安装jenkins

  • 给nfs的数据目录/data/v2做下权限
  1. [root@wentaomaster1 ~]# chown -R 1000.1000 /data/v2

使用deployment控制器创建jenkins pod

  1. [root@wentaomaster1 ~]# cat jenkins-deploy.yaml
  2. kind: Deployment
  3. apiVersion: apps/v1
  4. metadata:
  5. name: jenkins
  6. namespace: jenkins-k8s
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. app: jenkins
  12. template:
  13. metadata:
  14. labels:
  15. app: jenkins
  16. spec:
  17. serviceAccount: jenkins-k8s-sa
  18. containers:
  19. - name: jenkins
  20. image: docker.io/jenkins/jenkins:2.418
  21. imagePullPolicy: IfNotPresent
  22. ports:
  23. - containerPort: 8080
  24. name: web
  25. protocol: TCP
  26. - containerPort: 50000
  27. name: agent
  28. protocol: TCP
  29. resources:
  30. limits:
  31. cpu: 2000m
  32. memory: 2Gi
  33. requests:
  34. cpu: 500m
  35. memory: 512Mi
  36. livenessProbe:
  37. httpGet:
  38. path: /login
  39. port: 8080
  40. initialDelaySeconds: 60
  41. timeoutSeconds: 5
  42. failureThreshold: 12
  43. readinessProbe:
  44. httpGet:
  45. path: /login
  46. port: 8080
  47. initialDelaySeconds: 60
  48. timeoutSeconds: 5
  49. failureThreshold: 12
  50. volumeMounts:
  51. - name: jenkins-volume
  52. subPath: jenkins-home
  53. mountPath: /var/jenkins_home
  54. volumes:
  55. - name: jenkins-volume
  56. persistentVolumeClaim:
  57. claimName: jenkins-k8s-pvc
  1. [root@wentaomaster1 ~]# kubectl apply -f jenkins-deploy.yaml

在这里插入图片描述

给jenkins pod前端加上service,对外部提供网络访问

  1. [root@wentaomaster1 ~]# cat jenkins-service.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: jenkins-service
  6. namespace: jenkins-k8s
  7. labels:
  8. app: jenkins
  9. spec:
  10. selector:
  11. app: jenkins
  12. type: NodePort
  13. ports:
  14. - name: web
  15. port: 8080
  16. targetPort: web
  17. nodePort: 30002
  18. - name: agent
  19. port: 50000
  20. targetPort: agent
  1. [root@wentaomaster1 ~]# kubectl apply -f jenkins-service.yaml#通过kubectl get svc -n 看到对外提供的端口是30002

在这里插入图片描述

登录jenkins web页面

  • 浏览器网址栏输入192.168.184.10:30002

在这里插入图片描述

  • 可以看到提示为:初始密码在跑jenkins的pod里面的/var/jenkins_home/secrets/initialAdminPassword文件中

在这里插入图片描述

  • 将密码复制后,点击继续

在这里插入图片描述

  • 选择“安装推荐的插件”

在这里插入图片描述

  • 安装完成之后,创建管理员用户

在这里插入图片描述

  • 实例配置不改,用默认url

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 更新kubernetes插件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 点击安装后,下滑到最下面,勾选安装后重启

在这里插入图片描述

  • 安装完成后,再安装jenkins自动化部署的ui界面Blue Ocean

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 输入之前设置的用户、密码,选择保持登录状态

在这里插入图片描述

在这里插入图片描述

jenkins对接kubernetes自动生成jenkins从节点

  • 新增一个云kubernetes

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 填写云kubernetes配置内容 - 名称:kubernetes- kubernetes地址:https://192.168.184.10:6443 - 6443是kubernetes apiserver的端口- kubernetes命名空间:jenkins-k8s

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Jenkins UI界面配置访问Dockerhub凭据

  • 添加dockerhub凭据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

jenkins+k8s自动化发布项目

在这里插入图片描述

  • 准备好各个环境的命名空间
  1. #创建开发、生产、测试的命名空间[root@wentaomaster1 ~]# kubectl create ns devlopment[root@wentaomaster1 ~]# kubectl create ns production[root@wentaomaster1 ~]# kubectl create ns qatest

在这里插入图片描述

  • 创建流水线自动化发布任务,左侧栏点击新建任务

在这里插入图片描述

在这里插入图片描述

  1. node('testtan') {
  2. stage('Clone') {
  3. echo "1.Clone Stage"
  4. git url: "https://github.com/twttwttwt/jenkins-sample/"
  5. script {
  6. build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
  7. }
  8. }
  9. stage('Test') {
  10. echo "2.Test Stage"
  11. }
  12. stage('Build') {
  13. echo "3.Build Docker Image Stage"
  14. sh "docker build -t twttwt/jenkins-demo:${build_tag} ."
  15. }
  16. stage('Push') {
  17. echo "4.Push Docker Image Stage"
  18. withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
  19. sh "docker login -u ${dockerHubUser} -p ${dockerHubPassword}"
  20. sh "docker push twttwt/jenkins-demo:${build_tag}"
  21. }
  22. }
  23. stage('Deploy to dev') {
  24. echo "5. Deploy DEV"
  25. sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev.yaml"
  26. sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev.yaml"
  27. // sh "bash running-devlopment.sh"
  28. sh "kubectl apply -f k8s-dev.yaml --validate=false"
  29. }
  30. stage('Promote to qa') {
  31. def userInput = input(
  32. id: 'userInput',
  33. message: 'Promote to qa?',
  34. parameters: [
  35. [
  36. $class: 'ChoiceParameterDefinition',
  37. choices: "YES\nNO",
  38. name: 'Env'
  39. ]
  40. ]
  41. )
  42. echo "This is a deploy step to ${userInput}"
  43. if (userInput == "YES") {
  44. sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa.yaml"
  45. sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa.yaml"
  46. // sh "bash running-qa.sh"
  47. sh "kubectl apply -f k8s-qa.yaml --validate=false"
  48. sh "sleep 6"
  49. sh "kubectl get pods -n qatest"
  50. } else {
  51. //exit
  52. }
  53. }
  54. stage('Promote to pro') {
  55. def userInput = input(
  56. id: 'userInput',
  57. message: 'Promote to pro?',
  58. parameters: [
  59. [
  60. $class: 'ChoiceParameterDefinition',
  61. choices: "YES\nNO",
  62. name: 'Env'
  63. ]
  64. ]
  65. )
  66. echo "This is a deploy step to ${userInput}"
  67. if (userInput == "YES") {
  68. sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod.yaml"
  69. sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod.yaml"
  70. // sh "bash running-production.sh"
  71. sh "cat k8s-prod.yaml"
  72. sh "kubectl apply -f k8s-prod.yaml --record --validate=false"
  73. }
  74. }
  75. }

在这里插入图片描述

  • 点击保存后回到dashboard,可以看到已经多出来了一条任务,点击构建

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. [root@wentaomaster1 ~]# kubectl get pod -n production[root@wentaomaster1 ~]# kubectl get pod -n devlopment[root@wentaomaster1 ~]# kubectl get pod -n qatest

在这里插入图片描述

#通过上面可以看到jenkins对接k8s,可以把应用发布到k8s集群的开发、测试、生产环境了。

  • 访问github中index配置的web页面

在这里插入图片描述

devops自动化版本更新

  • 修改上图web页面的index文件

在这里插入图片描述

  • 此时访问web页面,暂时没有改动

在这里插入图片描述

  • 回到dashboard,重新执行一次pipeline文件

在这里插入图片描述

在这里插入图片描述

  • 可以看到,已成功更新

在这里插入图片描述

Devops自动化版本回滚

  • 新建任务

在这里插入图片描述

在这里插入图片描述

  1. node('testtan') {
  2. stage('git clone') {
  3. git url: "https://github.com/twttwttwt/jenkins-rollout"
  4. sh "ls -al"
  5. sh "pwd"
  6. }
  7. stage('select env') {
  8. def envInput = input(
  9. id: 'envInput',
  10. message: 'Choose a deploy environment',
  11. parameters: [
  12. [
  13. $class: 'ChoiceParameterDefinition',
  14. choices: "devlopment\nqatest\nproduction",
  15. name: 'Env'
  16. ]
  17. ]
  18. )
  19. echo "This is a deploy step to ${envInput}"
  20. sh "sed -i 's/<namespace>/${envInput}/' getVersion.sh"
  21. sh "sed -i 's/<namespace>/${envInput}/' rollout.sh"
  22. sh "bash getVersion.sh"
  23. // env.WORKSPACE = pwd()
  24. // def version = readFile "${env.WORKSPACE}/version.csv"
  25. // println version
  26. }
  27. stage('select version') {
  28. env.WORKSPACE = pwd()
  29. def version = readFile "${env.WORKSPACE}/version.csv"
  30. println version
  31. def userInput = input(id: 'userInput',
  32. message: '选择回滚版本',
  33. parameters: [
  34. [
  35. $class: 'ChoiceParameterDefinition',
  36. choices: "$version\n",
  37. name: 'Version'
  38. ]
  39. ]
  40. )
  41. sh "sed -i 's/<version>/${userInput}/' rollout.sh"
  42. }
  43. stage('rollout deploy') {
  44. sh "bash rollout.sh"
  45. }
  46. }
  • 保存后回到首页

在这里插入图片描述

在这里插入图片描述


本文转载自: https://blog.csdn.net/m0_68409964/article/details/136327506
版权归原作者 气势如虹_ 所有, 如有侵权,请联系我们删除。

“jenkins+kubernetes+git+dockerhub构建devops云平台”的评论:

还没有评论