jenkins 调用Rancher2.x api实现CI/CD
一、概述
在前面的文章中,链接如下:
https://www.cnblogs.com/xiao987334176/p/13162700.html
已经通过Redeploy Rancher2.x Workload插件实现CI/CD,但是有一个问题,不能写Pipeline脚本。
那么本文将介绍通过python脚本调用Rancher2.x api,以Pipeline脚本来实现CI/CD。
二、改造python脚本
在前面的文章中,链接如下:
https://www.cnblogs.com/xiao987334176/articles/13177526.html
已经通过python脚本调用Rancher2.x api,实现了修改镜像地址。
但是在jenkins调用它时,需要传一个BUILD_NUMBER参数给python脚本,来控制镜像版本。
比如:
python rancher_deploy.py 100
其中,100就是BUILD_NUMBER
那么改造后的rancher_deploy.py代码如下:
#!usr/bin/python # -*- coding: utf-8 -*- import requests # 去除requests警告信息 from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) import sys def update_image(BUILD_NUMBER): """ 修改镜像地址 :param BUILD_NUMBER: jenkins构建id :return: bool """ CATTLE_ACCESS_KEY = 'token-v82g7' RANCHER_SECRET_KEY = 'zzph8mnrv7r2q5qqt9kds85xvjcwzpg5btkttpvj72nmfll8jmxn67' # 请求头 header = {'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer {}:{}'.format(CATTLE_ACCESS_KEY, RANCHER_SECRET_KEY)} # 请求数据,r表示保留数据源格式。格式为:r"""json数据"""%BUILD_NUMBER content = r"""{"annotations":{"cattle.io/timestamp":"2020-06-22T10:42:46Z"},"containers":[{"allowPrivilegeEscalation":false,"image":"10.212.82.86:1180/java/admin-master:%s","imagePullPolicy":"Always","initContainer":false,"name":"admin-master","ports":[{"containerPort":8088,"dnsName":"admin-master-nodeport","hostPort":0,"kind":"NodePort","name":"tcp-8088","protocol":"TCP","sourcePort":0,"type":"/v3/project/schemas/containerPort"}],"privileged":false,"readOnly":false,"resources":{"type":"/v3/project/schemas/resourceRequirements"},"restartCount":0,"runAsNonRoot":false,"stdin":true,"stdinOnce":false,"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","tty":true,"type":"/v3/project/schemas/container"}],"created":"2020-06-22T10:42:46Z","creatorId":null,"deploymentConfig":{"maxSurge":1,"maxUnavailable":0,"minReadySeconds":0,"progressDeadlineSeconds":600,"revisionHistoryLimit":10,"strategy":"RollingUpdate"},"deploymentStatus":{"availableReplicas":1,"conditions":[{"lastTransitionTime":"2020-06-22T10:42:48Z","lastTransitionTimeTS":1592822568000,"lastUpdateTime":"2020-06-22T10:42:48Z","lastUpdateTimeTS":1592822568000,"message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable","status":"True","type":"Available"},{"lastTransitionTime":"2020-06-22T10:42:46Z","lastTransitionTimeTS":1592822566000,"lastUpdateTime":"2020-06-22T10:54:54Z","lastUpdateTimeTS":1592823294000,"message":"ReplicaSet \"admin-master-6c49c7c4b\" has successfully progressed.","reason":"NewReplicaSetAvailable","status":"True","type":"Progressing"}],"observedGeneration":7,"readyReplicas":1,"replicas":1,"type":"/v3/project/schemas/deploymentStatus","unavailableReplicas":0,"updatedReplicas":1},"dnsConfig":null,"dnsPolicy":"ClusterFirst","ephemeralContainers":[],"gids":[],"hostAliases":[],"hostIPC":false,"hostNetwork":false,"hostPID":false,"imagePullSecrets":[],"labels":{"workload.user.cattle.io/workloadselector":"deployment-default-admin-master"},"name":"admin-master","namespaceId":"default","nodeId":"","ownerReferences":[],"paused":false,"projectId":"c-l5nxb:p-dghs7","publicEndpoints":[],"readinessGates":[],"restartPolicy":"Always","scale":1,"scheduling":{"scheduler":"default-scheduler"},"selector":{"matchLabels":{"workload.user.cattle.io/workloadselector":"deployment-default-admin-master"},"type":"/v3/project/schemas/labelSelector"},"state":"active","sysctls":[],"terminationGracePeriodSeconds":30,"topologySpreadConstraints":[],"transitioning":"no","transitioningMessage":"","uuid":"96952959-73f4-48eb-9c8a-0476689c85f0","volumes":[],"windowsOptions":null,"workloadAnnotations":{"deployment.kubernetes.io/revision":"2","field.cattle.io/creatorId":"user-kmvzg"},"workloadLabels":{"cattle.io/creator":"norman","workload.user.cattle.io/workloadselector":"deployment-default-admin-master"},"workloadMetrics":[]}"""%BUILD_NUMBER # 应用服务api地址 api_url = 'https://10.212.82.86/v3/project/c-l5nxb:p-dghs7/workloads/deployment:default:admin-master' # 发送put请求,verify=False表示关闭验证证书 r = requests.put(api_url, data=content, headers=header, verify=False) # print(r.text) # print(r.status_code) # 判断返回状态码 if (r.status_code == 200): print('deploy ok') return True else: print('deploy error') return False if __name__ == '__main__': num = len(sys.argv) - 1 # 参数个数 if num < 1: exit("参数缺失,比如: python rancher_deploy.py 100") elif num > 1: exit("参数过多,比如: python rancher_deploy.py 100") else: pass BUILD_NUMBER = sys.argv[1] # jenkins构建id if not BUILD_NUMBER: exit("BUILD_NUMBER 不能为空") if not BUILD_NUMBER.isdigit(): exit("BUILD_NUMBER 必须是数字") ret = update_image(BUILD_NUMBER) if not ret: exit(1) else: exit(0)
说明:
content 参数要特别注意,格式为r"""json数据"""%BUILD_NUMBER。其中镜像的版本比如用%s表示,后面的%BUILD_NUMBER会替换掉版本号。
在代码末尾处,exit(0)表示正常。因为jenkins调用脚本时,退出码为0,才会判断为正常。否则为不正常!
由于一个分支,就是一个环境。这个python脚本,也是根据环境来的。因此,需要将此python代码提交至项目根目录即可。
三、Pipeline脚本
新建一个流水线风格的job
通用配置
参数化构建
流水线脚本
完整代码如下:
env.CREDENTIALSID = '7a294fc5-2b2b-4d2d-92ff-54324e1b032a' env.BRANCHES = 'master' env.GIT_URL = 'ssh://git@10.212.21.158:/home/git/git_storage/admin-master' env.HARBOR_PROJECT = '10.212.82.86:1180/java/admin-master' node { if (env.Status == 'Deploy'){ stage('code pull') { checkout([$class: 'GitSCM', branches: [[name: env.BRANCHES]], doGenerateSubmoduleConfigurations: false, userRemoteConfigs: [[credentialsId: env.CREDENTIALSID, url: env.GIT_URL]]]) } stage('code Build') { sh 'mvn -f pom.xml clean package' } stage('docker push') { sh 'cd ${WORKSPACE} && cp dockerfile target' sh 'cd ${WORKSPACE}/target && docker build -t ${HARBOR_PROJECT}:${BUILD_NUMBER} .' sh 'docker push ${HARBOR_PROJECT}:${BUILD_NUMBER}' sh 'docker rmi ${HARBOR_PROJECT}:${BUILD_NUMBER}' } stage('rancher deploy') { sh 'python rancher_deploy.py ${BUILD_NUMBER}' } }else{ stage('rancher rollback') { sh 'python rancher_deploy.py ${BUILD_ID}' } } }
登录到jenkins服务器,安装pip和request模块
yum install -y python-pip
pip install requests
注意:上面的脚本,python 2.7也可以执行。
发布
效果如下:
登录Rancher,查看镜像是否更改
回滚
比如我需要回滚到2
效果如下:
登录Rancher,查看镜像是否更改