GitOps进化:深入探讨 Argo CD 及其对持续部署的影响

什么是 GitOps?

虽然软件开发生命周期的大部分已经实现自动化,但基础设施仍然在很大程度上依赖于人工,需要专业团队的参与。随着当今基础设施需求的不断增长,实施基础设施自动化变得越来越重要。现代基础设施需要具备弹性,以便能够有效管理持续部署所需的云资源。

现代云原生应用程序的开发都兼顾了速度和规模。拥有成熟 DevOps 文化的组织每天可以将代码部署到生产环境中数百次。DevOps 团队可以通过版本控制、代码审查和 CI/CD 流水线等开发最佳实践来实现这一点,这些实践可以自动化测试和部署。

GitOps 用于自动化基础设施的配置流程,尤其是现代云基础设施。与团队使用应用程序源代码的方式类似,采用 GitOps 的运营团队使用以代码形式存储的配置文件(即基础设施即代码)。GitOps 配置文件每次部署时都会生成相同的基础设施环境,就像应用程序源代码每次构建时都会生成相同的应用程序二进制文件一样。

Argo CD是什么?

Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。

Argo CD 的主要功能

  • 基于 Git 的工作流:以代码形式管理基础设施和应用程序。
  • 声明式应用程序管理和同步机制。
  • 支持多个 Git 仓库和应用程序源。
  • 自动回滚和应用程序状态健康检查。

Argo CD 的架构

Argo CD 组件

  • Web 应用

Argo CD 附带一个强大的 Web 界面,可用于管理部署在给定 Kubernetes 集群中的应用程序。

  • CLI

Argo CD 提供了一个 CLI,用户可以使用它与 Argo CD API 交互。该 CLI 还可用于自动化和脚本编写。

  • API 服务器

定义 Argo CD 公开的专有 API,用于支持 Web 应用和 CLI 功能。

  • 应用程序控制器

应用程序控制器负责协调 Kubernetes 中的应用程序资源,将所需的应用程序状态(由 Git 提供)与实时状态(由 Kubernetes 提供)同步。应用程序控制器还负责协调项目资源。

  • ApplicationSet 控制器

ApplicationSet 控制器负责协调 ApplicationSet 资源。

  • Repo 服务器

Repo 服务器在 Argo CD 架构中扮演着重要的角色,因为它负责与 Git 存储库交互,为属于给定应用程序的所有 Kubernetes 资源生成所需的状态。

  • Redis

Argo CD 使用 Redis 提供缓存层,以减少发送到 Kube API 以及 Git 提供程序的请求。它还支持一些 UI 操作。

  • Kube API

Argo CD 控制器将连接到 Kubernetes API 以运行协调循环。

  • Git

作为 gitops 工具,Argo CD 要求在 Git 存储库中提供 Kubernetes 资源的所需状态。

我们在这里使用"git"来代表实际的 git 存储库、Helm 存储库或 OCI 工件存储库。Argo CD 支持所有这些选项。

  • Dex

Argo CD 依赖 Dex 为外部 OIDC 提供程序提供身份验证。但是,可以使用其他工具代替 Dex。

Argo CD 与 Git 仓库和 Kubernetes 集群交互的工作流程。

安装和配置

1.创建namespace

2. 使用官方的yaml文件来安装

复制代码
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

3. 等待Argo CD 组件启动和运行

复制代码
ninjamac@ip-192-168-1-101 ~ % kubectl get pod -n argocd
NAME                                               READY   STATUS    RESTARTS      AGE
argocd-application-controller-0                    1/1     Running   0             12m
argocd-applicationset-controller-cc68b7b7b-fvdb8   1/1     Running   0             12m
argocd-dex-server-555b55c97d-2sbsl                 1/1     Running   1 (92s ago)   12m
argocd-notifications-controller-65655df9d5-xgtw9   1/1     Running   0             12m
argocd-redis-764b74c9b9-m7qn7                      1/1     Running   0             12m
argocd-repo-server-7dcbcd967b-k9nbz                1/1     Running   0             12m
argocd-server-5b9cc8b776-rkfkv                     1/1     Running   0             12m

4.访问Argo CD API server

使用 LoadBalancer 服务公开 Argo CD API 服务器(用于外部访问)或使用端口转发进行本地访问:

复制代码
kubectl port-forward svc/argocd-server -n argocd 8080:443Forwarding from 127.0.0.1:8080 -> 8080Forwarding from [::1]:8080 -> 8080

获得Argo CD 管理员密码

复制代码
ninjamac@ip-192-168-1-101 kong % argocd admin initial-password -n argocd
xxxxxxxxxxxxxx

登录Argo CD

在浏览器中输入http://127.0.0.1:8080,输入用户名admin和修改后的密码。

使用 Argo CD 管理应用程序

首先,我们需要运行以下命令将当前命名空间设置为 argocd:

复制代码
ninjamac@ip-192-168-1-101 argocd % kubectl config set-context --current --namespace=argocd
Context "minikube" modified.

使用以下命令创建示例guestbook应用程序:

复制代码
ninjamac@ip-192-168-1-101 argocd % argocd login 127.0.0.1:8080 --username admin --password argocd2025

WARNING: server certificate had error: tls: failed to verify certificate: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y   
'admin:login' logged in successfully
Context '127.0.0.1:8080' updated
ninjamac@ip-192-168-1-101 argocd % argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
application 'guestbook' created

将 Argo CD 与 Jenkins 流水线集成

生成token

复制代码
ninjamac@ip-192-168-1-101 argocd % curl -X POST https://localhost:8080/api/v1/session -H "Content-Type: application/json" -d '{"username": "admin", "password": "xxxxxxxx"}' -k   
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhcmdvY2QiLCJzdWIiOiJhZG1pbjpsb2dpbiIsImV4cCI6MTc0NTcxNjkzNCwibmJmIjoxNzQ1NjMwNTM0LCJpYXQiOjE3NDU2MzA1MzQsImp0aSI6ImU0ZDQwNjk0LTNkYTktNDBiNS1hODRmLWM1ZWU0NDJkMGQxMCJ9.OkmofUhhb7EG9TDSm_ZQNE9-HQBCYpSVKVXtN70wAJI"}

创建jenkins file

复制代码
pipeline {
  agent any

  environment {
    ARGOCDSERVER = "https://argocd-server.example.com"
    ARGOCDPROJECT = "my-project"
    ARGOCDAPP = "my-app"
    K8SCONTEXT = "my-k8s-context"
    K8SNAMESPACE = "my-namespace"
    ARGOCDSYNCOPTIONS = "--sync-policy=auto --prune"
  }

  stages {
    stage('Deploy') {
      steps {
        script {
          def argocdToken = credentials('argocd-token')

          def appSpecFile = readFile("argocd/myapp.yaml")

          def argocd = new Argocd(server: ARGOCDSERVER, token: argocdToken)
          argocd.createApplication(appSpecFile, project: ARGOCDPROJECT)
          argocd.syncApplication(ARGOCDAPP, ARGOCDSYNCOPTIONS)
        }
      }
    }
  }
}

创建myapp.yaml

复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp
  project: default
  source:
    repoURL: https://github.com/myorg/myapp.git
    targetRevision: HEAD
    path: kubernetes/overlays/dev
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
  syncOptions:
    - --skip-hooks
  helm:
    valueFiles:
      - values.yaml

创建deployment.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myorg/myapp:latest
        ports:
        - containerPort: 8080
        env:
        - name: MYAPP_ENV
          value: "prod"

创建service.yaml

复制代码
apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    targetPort: 8080
  type: LoadBalancer

Argo CD 与GitLab CI的集成

让我们深入了解 ArgoCD 与 GitLab CI 集成的详细步骤。

GitLab 和 ArgoCD 简化了 CI/CD 工作流程,支持无缝部署到 Kubernetes 集群。

配置 GitLab CI/CD 流水线

设置您的 GitLab CI 流水线,通过 ArgoCD 触​​发部署。

在您的 git 仓库根目录中创建 .gitlab-ci.yaml 文件

复制代码
stages:
  - build
  - deploy

variables:
  # Set your Docker image name to nginx
  IMAGE_NAME: nginx
  IMAGE_TAG: latest
  # Define your AWS ECR repository URL
  ECR_REPOSITORY: your-account-id.dkr.ecr.your-region.amazonaws.com/nginx

# Define your Kubernetes context for EKS
 KUBE_CONTEXT: dev-eks-cluster
 AWS_ACCESS_KEY_ID: $DEV_AWS_ACCESS_KEY_ID
 AWS_SECRET_ACCESS_KEY: $DEV_AWS_SECRET_ACCESS_KEY

build:
  stage: build
  Script:
    - apk add --no-cache aws-cli  
    - aws configure set aws_access_key_id ${AWS_ACCESS_KEY_ID} --profile default
    - aws configure set aws_secret_access_key ${AWS_SECRET_ACCESS_KEY} --profile default
    - echo "Building the Nginx Docker image"
    - docker build -t $IMAGE_NAME:$IMAGE_TAG .
    - echo "Logging in to AWS ECR..."
    - aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin $ECR_REPOSITORY
    - echo "Tagging Docker image for ECR..."
    - docker tag $IMAGE_NAME:$IMAGE_TAG $ECR_REPOSITORY:$IMAGE_TAG
    - echo "Pushing Docker image to ECR..."
    - docker push $ECR_REPOSITORY:$IMAGE_TAG
  only:
    - dev

deploy:
  stage: deploy
  Script:
    - apk add --no-cache aws-cli  
    - aws configure set aws_access_key_id ${AWS_ACCESS_KEY_ID} --profile default
    - aws configure set aws_secret_access_key ${AWS_SECRET_ACCESS_KEY} --profile default
    - echo "Deploying to Kubernetes"
    - echo "Setting Kubernetes context to $KUBE_CONTEXT"
    - kubectl config use-context $KUBE_CONTEXT  # Switch to the specified Kubernetes context
    - kubectl apply -f k8s/deployment.yaml
  only:
    - dev

上述流水线包含一个构建阶段和一个部署阶段,部署阶段将在构建成功后触发 Kubernetes 部署。

设置 ArgoCD 以跟踪您的 GitLab 代码库

现在,配置 ArgoCD 以监控 Git 代码库的更改并自动部署更新。

创建 ArgoCD 应用程序 YAML:

复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gitlab-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://gitlab.com/repo-name.git'
    path: 'k8s'
    targetRevision: developer
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

现在,使用以下命令应用上述文件:

复制代码
Kubectl apply -f gitlab-argo.yaml -nargocd

此配置指示 ArgoCD 跟踪 GitLab 代码库中的更改并将更新部署到 Kubernetes 集群中。

触发 GitLab CI 流水线

将更改推送到 GitLab 中的开发者分支,.gitlab-ci.yml 中定义的流水线将触发:

  1. 构建阶段:执行测试或构建 Docker 镜像并将其推送到 aws ecr 代码库。
  2. 部署阶段:推送配置更改,这些更改将由 ArgoCD 同步并自动应用到您的 Kubernetes 集群。

您可以在 ArgoCD 用户界面中监控部署进度,从而可以直观地了解应用程序的状态。

将 GitLab CI 的灵活性与 ArgoCD 的强大功能相结合,您的 Kubernetes 工作流程将焕然一新。

监控和可观察性

应用控制器

ArgoCD 中的应用控制器负责管理和协调应用程序的预期状态。监控应用控制器时,您可以收集和分析以下指标和信息:

  • 应用同步状态:您可以监控应用程序的同步状态,包括它们是否为最新版本或是否遇到同步错误。
  • 资源健康状况:监控应用程序内资源(例如 Pod、服务)的健康状况,以检测崩溃或资源过度使用等问题。
  • 应用部署历史记录:跟踪应用程序部署和回滚的历史记录,以识别趋势和异常。
  • 性能指标:收集与应用控制器的资源消耗和响应时间相关的性能指标。
  • 错误和事件日志:收集应用控制器生成的日志和事件,以诊断和解决问题。

ArgoCD 服务器

ArgoCD 服务器是核心组件,它提供基于 Web 的用户界面和 API,用于管理应用程序和 GitOps 工作流。监控 ArgoCD 服务器时,您可以捕获以下信息:

  • API 请求指标:监控 ArgoCD REST API 的使用情况和性能,包括请求数量、响应时间和错误率。
  • 用户身份验证和授权:跟踪用户登录、身份验证失败和访问控制事件,以确保安全性和合规性。
  • 资源使用情况:监控服务器资源利用率(CPU、内存),以检测性能瓶颈和扩展需求。
  • 应用程序活动:收集有关应用程序 CRUD(创建、读取、更新、删除)操作和部署的信息。
  • 仪表板指标:如果 ArgoCD 提供基于 Web 的仪表板,您可以监控仪表板的使用情况、用户交互和导航模式。

代码库服务器

ArgoCD 中的代码库服务器负责与 Git 代码库交互,以获取应用程序清单并同步应用程序状态。监控代码库服务器时,您可以收集以下数据:

  • Git 代码库同步:监控 Git 代码库同步的状态,包括同步错误和代码库获取时间。
  • 资源缓存:跟踪 Git 仓库资源的缓存,这有助于减少频繁获取数据的需求,从而优化性能。
  • 身份验证和访问:监控 Git 仓库的身份验证和访问控制,以确保对 Git 仓库的安全访问。
  • 资源完整性:验证 Git 仓库数据的完整性,并识别任何损坏或不一致问题。
  • 资源使用情况:监控仓库服务器的资源利用率,例如 CPU 和内存消耗。

在本文中,我将仅指导如何通过应用程序控制器和 ArgoCD 服务器公开指标,并使用其 CRD 在 Prometheus 端收集这些指标。

ArgoCD 服务器指标 (8083)

编辑 argocd-server svc 文件 (kubectl edit svc argocd-server -n argocd)

如果 argocd-server svc 文件中不存在该端口,请在 spec.ports 下添加指标端点端口,目标端口为 8083

编辑 argocd-server 部署文件 (kubectl edit deploy argocd-server -n argocd)

在 argocd-server 部署文件的 spec.template.annotations 下添加以下内容:

在 argocd-server 部署文件的 spec.template.spec.containers.args 下添加以下内容:

在 ports.containerPort 下,根据需要将端口更改为 8083

完成上述所有步骤后,您可以验证指标是否在 8083 端口公开。

操作方法:kubectl port-forward -n argocd svc/argocd-server 8083

检查 localhost:8083/metrics 是否可用。

验证成功后,可以在 Prometheus 端设置服务监视器,以便在该端点查找指标。

argocd-server 指标的 ServiceMonitor:

SVC 名称应准确指定,例如:argocd-server

ServiceMonitor 配置成功后,它应该以如下方式在 Prometheus 用户界面中可见。

应用程序控制器指标 (8082)

在本例中,Argocd-application-controller 是一个 StatefulSet。我们可以通过以下命令检查 StatefulSet 配置:kubectl edit statefulset <name> -n <namespace>

在 spec.template.metadata.annotations 下添加:

值得注意的是,在服务监视器或 Pod 监视器的 matchLabels 下,必须准确指定标签,否则可能导致 CRD 配置错误。

实际上,指定的名称应该与选择器下相关 Pod 或服务中的键值对匹配。如下图所示。

完成这些步骤后,我们可以运行以下命令进行端口转发,以便在 8082 端口收集指标:kubectl port-forward -n argocd pod/argocd-application-controller-0 8082

与 argocd-server 类似,可以通过检查 localhost:8082/metrics 端点来验证指标是否从 argocd 公开。

将指标获取到 Prometheus

由于应用程序控制器指标通过 statefulSet 公开,因此必须创建一个 PodMonitor。如果为此目的创建了 servicemonitor,argocd-application-controller 将不会被列为活动目标之一,因此标签会被丢弃,从而导致 servicemonitor 中 matchLabels 下提到的标签无法匹配。因此,必须实现 podmonitor。

成功配置 PodMonitor 后,它应该会以这样的方式显示在 Prometheus 界面中。

终于!您可以通过 Prometheus 查看指标了

使用 Argo CD 的最佳实践

1. 拥抱 GitOps 原则

Argo CD 的核心是一款 GitOps 工具。为了有效地使用它,您应该完全拥抱 GitOps 原则:

使用 Git 作为单一事实来源:所有应用程序清单、配置文件和环境状态都应驻留在受版本控制的 Git 仓库中。这种方法可确保您的 Kubernetes 集群始终反映 Git 中定义的状态,从而提高一致性和可追溯性。

使用 Git 提交自动同步:配置 Argo CD 以自动将应用程序状态与 Git 提交同步。此设置可确保推送到仓库的任何更改都能快速一致地反映在您的 Kubernetes 集群中。

2. 合理组织仓库和清单

合理组织仓库和清单对于可维护性和可扩展性至关重要:

使用多仓库方法:对于较大的组织或项目,可以考虑将清单拆分到多个仓库中------一个用于应用程序清单,一个用于特定于环境的配置,另一个用于共享资源。这种结构使权限管理、关注点分离和维护清晰的历史记录更加容易。

利用 Helm Charts 或 Kustomize:使用 Helm 或 Kustomize 管理您的 Kubernetes 清单。这些工具提供的模板功能可以减少重复,简化配置管理,并更轻松地处理应用程序的多个环境或版本。

3. 正确配置 Argo CD 应用程序

Argo CD 使用"应用程序"来表示部署。正确的配置是关键:

使用声明式应用程序定义:在 Git 代码库中以声明式方式定义您的 Argo CD 应用程序。这种做法使您能够将应用程序作为代码进行管理、版本控制更改并强制一致性。

设置适当的同步策略:配置同步策略以匹配您的部署策略。对于持续部署到非生产环境,请使用"自动同步",对于可能需要人工审批的生产部署,请使用"手动同步"。

4. 实施强大的安全实践

在管理大规模部署时,安全性至关重要。以下是一些关键实践:

使用 RBAC 进行访问控制:在 Argo CD 中实施基于角色的访问控制 (RBAC),以限制对关键操作的访问。为不同的团队定义角色,并确保只有授权用户才有权部署或修改应用程序。

启用单点登录 (SSO) 和外部身份验证:将 Argo CD 与外部身份验证提供程序(例如 OAuth、SAML 或 LDAP)集成,以启用单点登录 (SSO)。此设置简化了用户管理,增强了安全性,并符合组织标准。

监控访问日志和审计跟踪:定期监控 Argo CD 访问日志和审计跟踪,以跟踪用户活动。这些日志对于检测未经授权的访问或配置更改以及满足合规性要求至关重要。

5. 优化应用程序健康和同步设置

Argo CD 提供健康检查和同步选项,以确保应用程序保持理想状态:

定义自定义健康检查:使用自定义健康检查来验证除默认 Kubernetes 探测之外的应用程序健康状况。这可能包括对应用程序功能至关重要的特定服务、端点或业务逻辑的检查。

启用资源修剪:Argo CD 允许您修剪 Git 代码库中不再定义的资源。此功能有助于防止配置漂移,并确保您的集群始终与所需状态同步。

利用同步:使用同步波来控制资源同步的顺序。当您需要确保某些资源(例如 ConfigMap 或 Secret)先于其他资源(例如 Deployment)创建时,此做法尤为有用。

Argo CD 监控和可观察性最佳实践

  1. 启用详细指标和警报

监控对于维护应用程序的健康和性能至关重要。Argo CD 提供了多种内置监控功能:

启用 Prometheus 指标:配置 Argo CD 以将指标公开给 Prometheus。此集成允许您跟踪各种指标,例如同步操作的数量、同步时长和应用程序健康状况。

为关键事件设置警报:使用 Prometheus Alertmanager 或 Grafana Alerts 等警报工具,为关键事件(例如同步失败、应用程序降级或漂移检测)创建通知。警报可帮助您快速响应事件并保持高可用性。

  1. 有效利用 Argo CD 仪表板

Argo CD 仪表板提供应用程序及其状态的实时视图:

监控应用程序的健康状况和状态:定期检查仪表板了解应用程序的状态,包括同步状态、健康检查和错误消息。仪表板提供可视化概览,帮助您快速识别和解决问题。

使用事件日志进行故障排除:Argo CD 的事件日志会捕获与应用程序相关的所有同步操作、错误和事件。利用此日志来解决问题、了解根本原因并实施纠正措施。

  1. 与外部可观察性工具集成

虽然 Argo CD 提供了基本的监控功能,但与外部可观察性工具集成可以增强可见性:

使用 Grafana 进行高级可视化:设置 Grafana 以可视化从 Argo CD 收集的 Prometheus 指标。创建自定义仪表板来监控部署的性能、健康状况和状态。

与集中式日志系统集成:将 Argo CD 日志转发到 Elasticsearch、Loki 或 Fluentd 等集中式日志解决方案。此集成支持高级日志分析、搜索以及与其他基础架构组件的关联。

  1. 实施 GitOps 监控工具

GitOps 监控工具提供用于观察和管理 GitOps 工作流的专用功能:

使用 Argo CD 通知:配置 Argo CD 通知,以便直接在 Slack、Microsoft Teams 或电子邮件等工具中接收警报和通知。此集成可帮助团队实时了解部署事件和应用程序状态。

利用 Flux 或 Weave GitOps 等工具:将 Argo CD 与其他 GitOps 工具(例如 Flux 或 Weave GitOps)结合使用,以扩展跨多个集群或环境的监控和可观察性功能。

优化 Argo CD 性能的技巧

扩展 Argo CD 以实现高可用性:以高可用性模式部署 Argo CD,每个组件(例如 API 服务器、控制器和存储库服务器)均有多个副本,以处理大规模部署并确保冗余。

调整资源限制和请求:为 Argo CD 组件定义适当的资源请求和限制,以确保最佳性能,避免资源争用。定期监控资源使用情况,并根据工作负载调整限制。

使用缓存存储库实现更快同步:在 Argo CD 中启用存储库缓存以加快同步操作速度,尤其适用于大型存储库或包含多个应用程序的环境。缓存可减少从 Git 获取清单并将其应用于集群所需的时间。

定期清理旧应用程序和资源:从 Argo CD 和 Git 存储库中删除未使用的应用程序、资源和清单。此清理操作可减少混乱,最大限度地降低资源消耗,并确保精简高效的部署环境。

结论

通过遵循这些最佳实践和技巧,您可以充分利用 Argo CD 的强大功能,在 Kubernetes 环境中实现无缝的应用程序部署和监控。从拥抱 GitOps 原则、优化部署配置到增强可观察性和安全性,Argo CD 提供了一套全面的功能,可简化您的持续交付工作流程。

相关推荐
蓝莓味柯基1 天前
DevOps:概念与学习路径
运维·学习·devops
梁萌2 天前
14-DevOps-快速部署Kubernetes
运维·kubernetes·k8s·devops·kubeode
G皮T2 天前
【DevOps】Git 命令实战:一个简单的 Web 开发项目示例
git·github·devops·版本控制
云攀登者-望正茂2 天前
60个GitLab CI/CD 面试问题和答案
ci/cd·gitlab·devops
wish3664 天前
【APM】How to enable Trace to Logs on Grafana?
经验分享·grafana·devops
陈哥聊测试4 天前
开发认为测试不及时,测试吐槽工作量太大?
后端·测试·devops
梁萌5 天前
10-DevOps-Jenkins参数化构建实现多版本发布
运维·gitlab·jenkins·devops·tag
梁萌6 天前
11-DevOps-Jenkins Pipeline流水线作业
运维·jenkins·devops·流水线·pipline