ArgoCD

遵循GitOPS模式,应用定义、配置和环境等都应该是声明式和版本化的。应用部署和生命周期管理是自动化、可审计和易于理解的

特性

  • 拥有GitOPS的一切特性,如回滚到任意git commit点
  • 自动发布应用到指定环境,支持多集群管理
  • 支持多种配置管理工具、模板 (Kustomize,Helm, Jsonnet, plain-YAML,自定义配置管理插件)
  • 支持单点登录 (OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, LinkedIn)
  • 支持多租户及RBAC授权
  • 服务健康状态分析
  • 资源版本偏移检查和Web UI实时可视化
  • 可自动或手动同步资源到目标状态
  • 提供命令行工具,自动化集成简单方便
  • Webhook 集成 (GitHub, BitBucket, GitLab)
  • 支持访问令牌
  • 支持各阶段钩子定义PreSync, Sync, PostSync hooks to support complex application rollouts (e.g.blue/green & canary upgrades)
  • 应用事件和API调用审计追踪
  • 有暴露Prometheus 指标
  • Parameter overrides for overriding helm parameters in Git

几个核心概念

  • Application:指定manifest路径下的一组kubernetes资源,是一个CRD

  • AppProject:Application的逻辑分组,可以配置一些约束选项,如限制git源、目标集群、namespace和资源类型等,也可以订阅project roles

  • App of Apps:官网文档中的 cluster bootstrapping,一个Application包含多个子Application,在批量创建Application时比较有用,也可以用来自我管理(官方文档有示例)

下图是定义了一个Application对象,其指定的仓库目录下包含多种资源,其中的子Application对象所指定的仓库目录又可以包含多种资源,我们可以开启递归的选项,在往仓库添加资源对象的时候自动apply到对应集群当中去

image-ArgoAppOfApp

注意点:

  • 一个ArgoCD实例中,Application名字是唯一的,且只能放在与argo部署的同一名称空间中
  • Application中没有指定resources-finalizer.argocd.argoproj.io终结器,在删除Application的时候是不会删除它所管理的资源,App of Apps也是一样

ApplicationSet

跨集群和仓库灵活的管理Applications,补充了以集群管理为中心的场景

  • 单个manifest管理到多个集群
  • 单个manifest部署多个来自于一个或者多个仓库的application
  • 支持多仓库

部署说明

ArgoCD很大程度上是无状态的,所有数据以k8s里面对象的形式存在。

高可用安装相比普通模式安装不同点在于redis集群化了,个人觉得倒没太大区别,其中

  • argocd-server 无状态,可水平伸缩
  • argocd-dex-server 用了in-memory数据库,不可扩展
  • argocd-application-controller是statefulset部署,其他都是Deployment部署

ingress访问配置参考注意 argo-server 需要添加 –insecure 选项启动,否则它总是会重定向到443端口,在与ingress一起使用的时候容易引起无限重定向

初始密码获取执行 kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

备份恢复:argocd admin 子命令可以导入或导出 ArgoCD 相关的资源,恢复时再 import 到集群即可

用户管理

sso

此处配置keycloak为provider。委托 OIDC provider 进行身份验证,在 argocd-cm 的 oidc.config 下面添加 OAuth2 配置,为了方便命令行访问,可关闭keycloak client的Client authentication

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
data:
  exec.enabled: "true"
  oidc.config: |
    name: Keycloak
    issuer: https://login.y.z/realms/abc
    clientID: ArgoCD
    requestedScopes: ["openid", "profile", "email"]    
  url: https://argocd.y.z
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-cm
  namespace: argocd

授权

允许自定义角色,预定义角色有两个:

  • role:readonly
  • role:admin

可以对应namespace下面configmap授权

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-rbac-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    g, ops-group, role:admin    

自定义权限,如下自定义角色common-user,拥有指定的一些适当权限给dev组:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
data:
  policy.csv: |
    p, role:common-user, applications, get, */*, allow
    p, role:common-user, applications, override, s*/*, allow
    p, role:common-user, applications, sync, */*, allow
    p, role:common-user, projects, get, *, allow
    g, ops, role:admin
    g, dev, role:common-user
    g, baiqi-test, role:common-user
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-rbac-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-rbac-cm
  namespace: argocd

Git 仓库

ArgoCD相关资源和业务服务的manifest仓库分开,k8s集群配置等有些资源涉及到敏感信息,最好对敏感信息进行加密,如bitnami开源的sealed-secrets

服务仓库可以对开发人员放开pr权限,方便开发同学按自己需求更改资源配置等,提交pr给运维同学

仓库目录可以按照团队、环境等维护单元统一组织,方便开发自动化流程

ArgoRollout

特性

  • 支持蓝绿策略、灰度策略
  • 细粒度、加权流量整形
  • 根据指标自动发布或回滚
  • 可手动操作发布
  • 可自定义metric和业务关键指标分析
  • 与ingress控制器集成,如nginx、alb、apisix
  • 服务网格的集成,如Istio、Linkerd、SMI
  • 可同时支持多个ingress/servermesh provider
  • 与metric provider集成

核心概念

Rollout,是自定义的工作负载,相当于Deployment对象。在需要高级部署或渐进式交付的情况下替换Deployment,可以由Deployment直接迁移到Rollout对象。

Rollout可以单独工作,Rollout Controller管控Rollout对象,不影响原来的任何资源,但是流量控制会比较单一,只能通过副本数来控制,通过与nginx-controller集成可以细粒度控制流量权重。

搭配nginx控制器的灰度

存在一个stable的ingress,路由流量到stable的service,更新版本时,自动克隆一个canary ingress对象,并添加canary相关注解,利用ingress Controller的canary能力进行流量切分。

以官方提供的例子为例:

1
2
3
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/rollout.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/services.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/ingress.yaml

更新策略调整如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
spec:
  replicas: 5
  strategy:
    canary:
      # Reference to a Service which the controller will update to point to the canary ReplicaSet
      canaryService: rollouts-demo-canary
      # Reference to a Service which the controller will update to point to the stable ReplicaSet
      stableService: rollouts-demo-stable
      trafficRouting:
        nginx:
          # Reference to an Ingress which has a rule pointing to the stable service (e.g. rollouts-demo-stable)
          # This ingress will be cloned with a new name, in order to achieve NGINX traffic splitting.
          stableIngress: rollouts-demo-stable
      steps:
        - setWeight: 20
        - pause: { }
        - setWeight: 40
        - pause: { duration: 10 }
        - setWeight: 60
        - pause: { duration: 10 }
        - setWeight: 80
        - pause: { duration: 60 }

在第一阶段完成,第二阶段暂停后的状态如下:

image-NginxRollout

此时canary-ingress的注解自动被设置权重为20

1
2
3
4
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"

通过 ArgoCD 的面板可以直观看到流量分发路径:

image-Rollout-ingress

其中,俩service的selector标签选择器里面自动添加rollouts-pod-template-hash标签,用以区分选择不同版本,完全更新完成后,canary ingress的权重设置为0,即所有流量全部走stable ingress

蓝绿

与canary类似,通过给service注入选择器标签来切换流量

官方示例为例:

  1. 从 Revision 1 到 Revision 2 ,preview指向新版本,active指向老版本

    image-bluegreen-1

Rollout UI里面显示的副本数情况,新老版本各两个

image-bluegreen-1.2

  1. 更新完毕后,俩service都指向新版本

    image-bluegreen-2