赞
踩
传统的主机方式部署的 Jenkins 集群在复杂场景中会经常碰到如下问题,如:
基于k8s编排和Docker容器技术,可以很好的解决上面问题。Jenkins Master 和 Jenkins Slave 以 Docker Container 形式运行在 Kubernetes 集群的 Node 上,Master 运行在其中一个节点,Slave 运行在各个节点上,并且它不是一直处于运行状态,它会按照需求动态的创建并自动删除。最终的方式和传统的是一样的,也是基于jenkins-agent.jar,通过jnlp进行通信,只不过jenkins 的 kubernetes-plugin 插件帮我们把这些操作做完了。通过这样的方式,在需要 Build 的时候创建 Slave Pod 动态伸缩,而且pod可以基于模板定制环境,Build结束后就销毁,合理利用计算资源。
网上很多,可以通过helm或者自己定制配置文件。
Pipeline相关,文档语法:
https://www.jenkins.io/zh/doc/book/pipeline/syntax/
Kubernetes Plugin,主要用于创建Slave Pod 并分配给Slave相关流水线工作内容,相关文档:
https://github.com/jenkinsci/kubernetes-plugin
https://www.jenkins.io/doc/pipeline/steps/kubernetes/
Kubernetes Continuous Deploy Plugin,主要用于容器内发布k8s相关资源,相关文档:
https://www.jenkins.io/doc/pipeline/steps/kubernetes-cd/#kubernetesdeploy-deploy-to-kubernetes
插件安装完毕后,点击 “系统管理” —> “系统设置” —> “Cloud” 进入云集群配置页面 选择 Kubernetes
填写kubernetes 和 Jenkins 配置
需要注意一点:在使用的时候Pipeline的Pod启动的时候会有Node-Selectors: kubernetes.io/os=linux,所以需要在集群node上面添加kubernetes.io/os=linux的label
参数化配置
配置的参数可以在pipeline script 中使用 ${params.key} 来使用,如上面就是 ${params.APP_NAME}
流水线脚本,可以参考上面提供的插件文档
def label = "test-pipline" def HARBOR_HOST = "test.harbor.com" podTemplate(label: label, cloud: 'kubernetes', imagePullSecrets: ['test-harbor'], containers: [ containerTemplate(name: 'node', image: 'node:14.16.0-alpine3.10', ttyEnabled: true, command: 'cat'), containerTemplate(name: 'maven', image: 'test.harbor.com/maven:3.6.3-jdk-8', ttyEnabled: true, command: 'cat'), containerTemplate(name: 'docker', image: 'docker:20.10.5-git', , ttyEnabled: true, command: 'cat'), ], volumes: [ hostPathVolume(hostPath: '/var/run/docker.sock', mountPath:'/var/run/docker.sock'), persistentVolumeClaim(claimName: 'jenkins-build-pvc', mountPath: '/root/repo') ], workspaceVolume: persistentVolumeClaimWorkspaceVolume(claimName: 'jenkins-workspace-pvc') ) { node(label) { stage('Git Clone') { git branch: 'master', credentialsId: 'gitlab', url: 'https://test.gitlab.com/devil/test.git' } stage('Node Build') { container('node'){ sh """ cd vue npm install npm run build """ } } stage('Maven Build') { container('maven'){ sh "mvn package -Dmaven.test.skip=true" } } stage('Docker Build') { container('docker'){ withCredentials([usernamePassword(credentialsId: "harbor", passwordVariable: 'HARBOR_PWD', usernameVariable: 'HARBOR_USERNAME')]) { sh "docker login " + HARBOR_HOST + " -u ${HARBOR_USERNAME} -p ${HARBOR_PWD}" sh "docker build -t " + HARBOR_HOST + "/${params.IMAGE_NAME}:${params.IMAGE_TAG} ." sh "docker push " + HARBOR_HOST + "/${params.IMAGE_NAME}:${params.IMAGE_TAG}" } } } stage('Deploy') { sh "sed -e 's#{IMAGE_URL}#" + HARBOR_HOST + "/${params.IMAGE_NAME}#g;s#{IMAGE_TAG}#${params.IMAGE_TAG}#g;s#{APP_NAME}#${params.APP_NAME}#g;s#{REPLICAS_NUM}#${params.REPLICAS_NUM}#g;s#{HEAP_SIZE}#${params.HEAP_SIZE}#g;s#{DIRECT_MEMORY_SIZE}#${params.DIRECT_MEMORY_SIZE}#g' k8s-deployment-tpl.yaml > k8s-deployment.yml" sh "cat k8s-deployment.yml" kubernetesDeploy(configs: 'k8s-deployment.yml', kubeconfigId: "k8s-client") } } }
容器模板相关
kubectl create secret docker-registry -n jenkins harbor --docker-username=*** --docker-password=**** --docker-email=aaa@gg.com --docker-server=host
数据挂载相关
kubeconfig类型凭证,系统管理-> manager Credentials 创建凭证,credentialsId同理,基于需要用Username/Password或者其它类型
上面pipeline最后Deploy指定了项目根目录下k8s-deployment-tpl.yaml,用自定义的构建参数进行文本替换,生成k8s-deployment.yml用于k8s发布插件发布。k8s-deployment-tpl.yaml 模板内容如下:
apiVersion: apps/v1beta1 kind: Deployment metadata: name: {APP_NAME} spec: replicas: {REPLICAS_NUM} template: metadata: name: {APP_NAME} labels: app: {APP_NAME} spec: containers: - image: {IMAGE_URL}:{IMAGE_TAG} name: {APP_NAME} ports: - containerPort: 80 volumeMounts: - name: config mountPath: /root/config.yaml subPath: config.yaml volumes: - name: config configMap: name: test-config items: - key: config.yaml path: config.yaml --- apiVersion: v1 kind: Service metadata: name: {APP_NAME} spec: ports: - port: 80 targetPort: 80 selector: app: {APP_NAME}
创建 pod 模板
这里的配置其实和上面pipeline中podTemplate相似,创建完pod模板后,构建一个自由风格的软件项目,在标签中选择刚刚创建的模板,这样就会自动按模板要求进行操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。