• OpenShift中GitOps的深入和思考


      为了实现高可用性,不少客户会在生产环境中遇到多集群多实例的部署问题,相对比较简单的做法是分别部署多套独立的集群,然后通过cicd的流水线,比如jenkins把应用发布到不同的多套集群环境中间去,这种做法多了以后,存在的问题也比较明显,主要存在于

    • 后端发布的拓扑结构存在于发布流水线脚本中,一旦需要调整,很难运维。
    • 中间有后端环境变化,比如需要多加一个集群,那可能还需要修改流水线,重新运行流水线
    • 发布结构的一致性很难保证,有时候为了查错或者应对突然的负载情况,修改了应用的实例或者其他配置,这些改动和前期的规划很难保持一致。

    分布式环境最大的问题触发点还是在于规模,在很多客户环境下,部署30-50套应用,采用各种方式其实区别是不明显的,因为应用有限,运维的人数也有限,大家基本上对情况有个基本了解。

    但一旦部署规模上去以后,在一个大规模的分布式环境中,面对上百上千的应用,我们要考虑的是如何把握所有应用部署的架构,出现问题后如何最快的恢复,随着时间的推移怎样保证部署架构和设计的一致性。

      GitOps就是帮助我们去实现Infrasture as a code的利器,他是一个专门针对多集群的环境,采用yaml文件的描述性的持续发布平台。OpenShift gitops主要是基于ArgoCD的组件进行产品化,覆盖了如下的功能:

    • 自动化的ArgoCD的安装和升级
    • 多集群的配置管理
    • 应用部署结构,环境,以及发布历史的管理
    • 和OpenShift pipeline(基于teckton)端到端的集成

    1.基本部署单元Application(CRD)

      作为ArgoCD本身的项目来说,他的部署单元是一个Application(ArgoCD带来的CRD),这个Application的配置主要是包含了四个方面

    • 代码的Git Repository
    • Revision/Branch
    • 部署的集群和命名空间信息
    • 同步策略

    比较典型的一个例子如下:

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: pricelist-app
      namespace: argocd
    spec:
      destination:
        namespace: argocd
        server: https://kubernetes.default.svc
      project: default
      source:
        path: app-of-apps/apps
        repoURL: https://github.com/christianh814/gitops-examples
        targetRevision: master
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

     Application的部署支持Helm和Kustomize(缺省), ArgoCD本身就是以Application这个单元为中心的。所以你在ArgoCD里看到的视图也是基于Application来进行展示

     Application的问题和限制:

    • 每个应用只能定义一个Cluster
    • 只有一种资源类型,或者选择git,或者选择helm
    • 只能定义一个git repo和helm chart

    如果我是在一个实际的环境中,可能是一堆的应用,需要部署在3,5个集群上,那就需要针对这些环境每个都去写Application,如果我有10个应用,那可能就需要写10*5个Application了。。。。

    为了解决这个问题,在ArgoCD中引入了ApplicationSets的概念。

    2.复杂部署场景下的ApplicationSets

    核心点如下:

    • App Pattern支持定义批量的应用(用yaml和Helm都可以,一键部署一批)
    • 管理Application的生命周期
    • 构建Application的Factory模式

      主要引入了Generators的概念,主要有三类

    • List Generators
    • Cluster Generators
    • Git Generators

    List Generators

    简单来看List Generators, 发布应用到多集群

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: bgd
      namespace: openshift-gitops
    spec:
      generators:
      - list:
          elements:
          - cluster: cluster1
            url: https://api.cluster1.chx.osecloud.com:6443
          - cluster: cluster2
            url: https://api.cluster2.chx.osecloud.com:6443
          - cluster: cluster3
            url: https://api.cluster3.chx.osecloud.com:6443
      template:
        metadata:
          name: '{{cluster}}-bgd'
        spec:
          project: default
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
            repoURL: https://github.com/christianh814/gitops-examples
            targetRevision: master
            path: applicationsets/list-generator/v0.1/overlays/{{cluster}}
          destination:
            server: '{{url}}'
            namespace: bgd

    Cluster generator

    ArgoCD 将集群信息保存到Secret中间去,因此查看Secret的信息知道目前的集群

    $ oc get secrets -n openshift-gitops -l argocd.argoproj.io/secret-type=cluster
    NAME                                           TYPE DATA   AGE
    cluster-api.cluster1.chx.osecloud.com-74873278 Opaque   3  23m
    cluster-api.cluster2.chx.osecloud.com-2320437559   Opaque   3  23m
    cluster-api.cluster3.chx.osecloud.com-2066075908   Opaque   3  23m
    
    
    $ argocd cluster list
    SERVER                                  NAME    VERSION  STATUS  MESSAGE
    https://api.cluster1.chx.osecloud.com:6443  cluster1 1.20 Successful  
    https://api.cluster2.chx.osecloud.com:6443  cluster2 1.20 Successful  
    https://api.cluster3.chx.osecloud.com:6443  cluster3 1.20 Successful

    构建ApplicationSet

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: bgd
      namespace: openshift-gitops
    spec:
      generators:
      - clusters: {} # targets all clusters
      template:
        metadata:
          name: '{{name}}-bgd' # the "name" is the name field in the secret
        spec:
          project: default
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
            repoURL: https://github.com/christianh814/gitops-examples
            targetRevision: master
            path: applicationsets/cluster-generator/overlays/dev/
          destination:
            server: '{{server}}' # "server" from the field in the secret
            namespace: bgd

    也可以基于label模式部署到特定的集群,比如开发集群。

    Git Generators

    Git Generators包含两类,一种是目录类型,一种是文件类型,从例子上看,目录类型更多的是针对了部署多个应用,例如

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: pricelist
      namespace: openshift-gitops
    spec:
      generators:
      - git:
          repoURL: https://github.com/christianh814/gitops-examples
          revision: master
          directories:
          - path: applicationsets/git-dir-generator/apps/*
      template:
        metadata:
          name: '{{path.basename}}'
        spec:
          project: default
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
            repoURL: https://github.com/christianh814/gitops-examples
            targetRevision: master
            path: '{{path}}'
          destination:
            server: https://api.cluster1.chx.osecloud.com:6443
            namespace: pricelist

    在apps下,可以看到三个应用,支持通过不同的模式部署

    $ tree applicationsets/git-dir-generator/apps
    applicationsets/git-dir-generator/apps
    ├── pricelist-config
    │   ├── kustomization.yaml
    │   ├── pricelist-config-ns.yaml
    │   └── pricelist-config-rb.yaml
    ├── pricelist-db
    │   ├── Chart.yaml
    │   └── values.yaml
    └── pricelist-frontend
        ├── kustomization.yaml
        ├── pricelist-deploy.yaml
        ├── pricelist-job.yaml
        ├── pricelist-route.yaml
        └── pricelist-svc.yaml
    3 directories, 10 files

    而对于文件方式,需要指定到一个json文件config.json

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: bgd
      namespace: openshift-gitops
    spec:
      generators:
      - git:
          repoURL: https://github.com/christianh814/gitops-examples
          revision: master
          files:
          - path: "applicationsets/git-generator/cluster-config/**/config.json"
      template:
        metadata:
          name: '{{cluster.name}}-bgd'
        spec:
          project: default
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
            repoURL: https://github.com/christianh814/gitops-examples
            targetRevision: master
            path: applicationsets/git-generator/overlays/{{cluster.overlay}}
          destination:
            server: '{{cluster.server}}'
            namespace: bgd
    $ tree applicationsets/git-generator/
    applicationsets/git-generator/
    ├── appset-bgd.yaml
    ├── base
    │   ├── bgd-deployment.yaml
    │   ├── bgd-namespace.yaml
    │   ├── bgd-route.yaml
    │   ├── bgd-svc.yaml
    │   └── kustomization.yaml
    ├── cluster-config
    │   ├── cluster1
    │   │   └── config.json
    │   ├── cluster2
    │   │   └── config.json
    │   └── cluster3
    │       └── config.json
    └── overlays
        ├── cluster1
        │   ├── bgd-deployment.yaml
        │   └── kustomization.yaml
        ├── cluster2
        │   ├── bgd-deployment.yaml
        │   └── kustomization.yaml
        └── cluster3
            ├── bgd-deployment.yaml
            └── kustomization.yaml

    config.json更多的指定了被部署的集群信息。

     3.状态的同步

    ArgoCD缺省会每个3分钟进行当前状态的同步,如果你直接修改了集群中的配置,比如replicas, 和配置不符会由ArgoCD直接修改过来。

    这个同步时间应该是可以设置,暂时没有研究。

    4.一些思考

    GitOps是一个很好的理念,在ArgoCD中也针对实际的场景进行实现,并且功能继续在增强过程中,但在我目前接触的客户中相对来说比较少的应用,自己觉得主要是几个方面原因:

    • 很多客户的部署规模有限,环境复杂性不高,基本运维人员能搞定
    • 在生产环境中,大家还是习惯了直接去改,毕竟改一个集群,不会影响到其他的集群,万一出错,还有别的集群顶着,而如果修改git里的配置,那可能会影响到其他集群,带来关联性影响。

    关于第二点,我认为更好的办法是生产环境中停掉自动同步功能,在确认修改一个没有问题以后,再通过修改git,通过argocd同步到其他环境。

    总的来说,除了多集群发布和同步的功能,我们需要仔细考虑的一点是,如果一觉醒来,当我们的环境出现各种问题,需要重新构建的时候,从平台方出发,我们如何能在最短的时间内将现有的应用重新发布。

    我们不太可能要求在让所有应用团队基于流水线都进行一遍发布,那唯一可行的就是,通过gitops定义现有的部署结构的完整视图,然后在新的环境中批量重建,也许这种场景下的最佳办法。

  • 相关阅读:
    保护个人劳动成果----------代码混淆 (war/jar)
    获取计算机所有属性硬件信息
    得到某个文件夹下所有的文件名称
    下载的方法
    shell停止/启动/重启tomcat
    线程超时
    2020 0508 开通博客
    spring mvc 的一些状态码
    restful接口设计规范总结 转发的 第一次接触时候发现的文章(个人觉得不错)
    spring mvc常用注解
  • 原文地址:https://www.cnblogs.com/ericnie/p/15927201.html
Copyright © 2020-2023  润新知