优化Argocd触发CD的速度
Argo CD每三分钟轮询一次Git存储库,以检测清单的变化。为了消除轮询带来的延迟,可以将API服务器配置为接收Webhook事件。Argo CD支持来自GitHub,GitLab,Bitbucket,Bitbucket Server和Gogs的Git Webhook通知,更多点击官网:
https://argoproj.github.io/argo-cd/。
我这里使用Gitlab作为仓库地址。
(1)在argocd中配置webhook token
使用kubectl edit secret argocd-secret -n argocd
命令进行配置:
apiVersion: v1 kind: Secret metadata: name: argocd-secret namespace: argocd type: Opaque data: ... stringData: # gitlab webhook secret webhook.gitlab.secret: coolops
配置完点击保存会自动生成一个secret,如下:
# kubectl describe secret argocd-secret -n argocd Name: argocd-secret Namespace: argocd Labels: app.kubernetes.io/name=argocd-secret app.kubernetes.io/part-of=argocd Annotations: Type: Opaque Data ==== admin.passwordMtime: 20 bytes server.secretkey: 44 bytes tls.crt: 1237 bytes tls.key: 1679 bytes webhook.gitlab.secret: 7 bytes admin.password: 60 bytes
(2)在gitlab的代码仓库配置webhook,如下:
由于集群内部证书是无效证书,所有要把Enabled SSL去掉,如下:
然后点击保存,点击测试,看是否链接成功。如果有如下提示则表示webhook配置没问题了。
现在可以进行修改gitlab仓库,观察是否一提交,argocd那边就可以响应了。
使用argo rollouts进行金丝雀发布
关于argo rollouts的更多介绍可以查看之前的文章《使用argo-rollouts实现金丝雀发布》。
按着官方文档进行安装,官方地址为:https://argoproj.github.io/argo-rollouts/installation/#kubectl-plugin-installation
(1)在Kubernetes集群中安装argo-rollouts
kubectl create namespace argo-rollouts kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml
(2)安装argo-rollouts的kubectl plugin
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64 chmod +x ./kubectl-argo-rollouts-linux-amd64 mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
(3)我们这里主要是要重写deployment的配置文件,主要的配置清单如下。
rollout.yaml
apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: rollouts-simple-java spec: replicas: 3 strategy: canary: canaryService: rollouts-simple-java-canary stableService: rollouts-simple-java-stable trafficRouting: nginx: stableIngress: rollouts-simple-java-stable steps: - setWeight: 20 - pause: {duration: 60} - setWeight: 50 - pause: {duration: 10} - setWeight: 80 - pause: {duration: 10} revisionHistoryLimit: 2 selector: matchLabels: app: rollouts-simple-java template: metadata: labels: app: rollouts-simple-java spec: containers: - args: - -jar - /opt/myapp.jar - --server.port=8080 command: - java env: - name: HOST_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.hostIP image: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp:latest imagePullPolicy: IfNotPresent lifecycle: preStop: exec: command: - /bin/sh - -c - /bin/sleep 30 livenessProbe: failureThreshold: 3 httpGet: path: /hello port: 8080 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 15 successThreshold: 1 timeoutSeconds: 1 name: myapp ports: - containerPort: 8080 name: http protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /hello port: 8080 scheme: HTTP periodSeconds: 15 successThreshold: 1 timeoutSeconds: 1 resources: limits: cpu: "1" memory: 2Gi requests: cpu: 100m memory: 1Gi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirstWithHostNet imagePullSecrets: - name: gitlab-registry
services.yaml
apiVersion: v1 kind: Service metadata: name: rollouts-simple-java-canary spec: ports: - port: 8080 targetPort: http protocol: TCP name: http selector: app: rollouts-simple-java # This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.: # rollouts-pod-template-hash: 7bf84f9696 --- apiVersion: v1 kind: Service metadata: name: rollouts-simple-java-stable spec: ports: - port: 8080 targetPort: http protocol: TCP name: http selector: app: rollouts-simple-java # This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.: # rollouts-pod-template-hash: 789746c88d
ingress.yaml
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: rollouts-simple-java-stable annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: rollouts-simple-java.coolops.cn http: paths: - path: / backend: # Reference to a Service name, also specified in the Rollout spec.strategy.canary.stableService field serviceName: rollouts-simple-java-stable servicePort: 8080
kustomization.yaml
# Example configuration for the webserver # at https://github.com/monopole/hello commonLabels: app: rollouts-simple-java resources: - rollout.yaml - services.yaml - ingress.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp newTag: "latest" namespace: dev
让后将这些文件保存到gitlab yaml仓库里,比如:
这里的金丝雀发布是才有的时间暂停的方式,还可以采用手动继续的方式。我这里方便测试就才有了时间暂停。
给代码仓库打Tag
为啥要给代码仓库打Tag呢?
当一个代码仓库进过长时间的迭代,针对不同的时期和需求,必定会有不同的版本。而借助 Git 提供的标签功能,可以快捷方便地记录代码版本。无论什么时候,想取回某个版本,不再需要查找冗长的commit_id
,只需要取出打标签的历史版本即可。
可以这么理解:标签是版本库的一个快照。在主流的 Git 平台上,版本可以直接下载的,节省了开发者的不少精力。
这里通过gitlab的api对代码仓库打tag。API的具体操作见
https://docs.gitlab.com/ee/api/tags.html
这里在shareLibrary的代码仓库中创建了gitlab.groovy文件。
具体内容如下:
package org.devops //封装HTTP请求 def HttpReq(reqType,reqUrl,reqBody){ def gitServer = "http://172.17.100.135:32080/api/v4" withCredentials([string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) { result = httpRequest customHeaders: [[maskValue: true, name: 'PRIVATE-TOKEN', value: "${gitlabToken}"]], httpMode: reqType, contentType: "APPLICATION_JSON", consoleLogResponseBody: true, ignoreSslErrors: true, requestBody: reqBody, url: "${gitServer}/${reqUrl}" //quiet: true } return result } //获取项目ID def GetProjectID(projectName){ projectApi = "projects?search=${projectName}" response = HttpReq('GET',projectApi,'') def result = readJSON text: """${response.content}""" for (repo in result){ // println(repo['path_with_namespace']) if (repo['path'] == "${projectName}"){ repoId = repo['id'] println(repoId) } } return repoId } // 给仓库打tag def TagGitlab(projectId,tag_name,tag_ref){ def apiUrl = "projects/${projectId}/repository/tags" reqBody = """{"tag_name": "${tag_name}","ref": "${tag_ref}"}""" HttpReq('POST',apiUrl,reqBody) }
首先通过GetProjectID
获取到项目仓库的ID,然后再调用TagGitlab
进行打Tag。
然后我们需要在Jenkins上创建一个名叫gitlab-token
的token凭据。
(1)在gitlab上生成token
(2)在Jenkins上创建凭据
系统管理->凭据管理->全局凭据->添加凭据
注意这个ID,要和gitlab.groovy中的ID一一对应。