argo之argocd
argocd
k8s中gitops部署工具,核心组件是Application Controller相关的CRD
argo的所有组件通过专用k8s crd实现,支持集成其他cncf项目,如grpc、普罗米修斯、helm、cloudevents等
官网:https://argoproj.github.io/cd/
github:https://github.com/argoproj/argo-cd
文档:https://argo-cd.readthedocs.io/en/
功能
- 结合配置管理工具,ksonnet、jsonnet、helm、kustomize实现程序配置
- 将应用自动部署到指定环境,并监控已部署应用
- 基于web和cli操作
- presync、sync、postsync hooks以及支持高级应用部署策略
- sso集成(单点登录),劫持oidc、ldap、saml2.0、gitlab、微软、linkedin等
- webhook集成。如github、bitbucket、gitlab
- 可独立使用,也可结合现有pipeline作为部分使用,如argo workflow、jenkins、gitlab ci等
Argo生态子项目
- argo workflows:基于k8s平台的原生工作流引擎,支持dag个step-based工作流(类似tekton的功能)
- argo events:事件管理器,用于触发k8s中argo工作流和其他操作(knative要比这个好用)
- argo cd:由argo社区和intuit维护的开源项目,支持gitops范式的声明式k8s资源管理
- argo rollouts:高级交付策略工具,支持声明式渐进式交付策略,如金丝雀、蓝绿部署
CRD资源
application
定义由argocd管理的应用,受控于application控制器
applicationSet
以模板化形式自动生成由argoCD管理的应用,支持从多个不同角度构建模板,如不同git仓库、不同k8s集群等
受控于applicationSet控制器
appProject
为application提供逻辑分组,并提供:
- 限制可用部署的内容,如指定受信任的git仓库白名单
- 限制应用部署的目标位置(集群或命名空间)
- 限制部署的资源类型,如rbac、crd、ds控制器等
每个application都属于1个appProject,未指定时,则隶属于default的默认项目(default项目可修改但不能删除)
核心概念
application
基于Application资源创建,支持使用配置管理工具管理:helm、kustomize、jsonnet
2部分组成
1组在k8s中部署和运行的应用的资源配置文件,其中定义的内容为:
- source:配置文件获取处,包括git仓库地址和配置文件所在目录
- destination:配置文件中定义的对象应该创建运行在何处
2个状态属性
sync status
application的实际状态与git仓库中定义的期望状态是否一致
状态:
- synced:一致
- OutOfSync:不一致
health status
application的健康状态,是各资源的健康状态的聚合信息
状态:
- healthy:健康
- processing:处于尝试转为健康状态的进程中
- degraded:降级
- missing:缺失,即在git仓库中存在资源定义,但未完成部署
project
基于AppProject资源创建,能够将Application进行分组的逻辑组件
主要用于将租户或团队间的Application彼此隔离,并且支持在组内进行细粒度的权限管控
支持为内部Application上的Source和Destination分别指定各自的黑白名单
ArgoCD架构
程序组件
argocd api-server
api接口,为web UI、cli、相关CI/CD系统提供服务,包括:
- 管理应用程序并报告其状态
- 调用并发起应用程序的特定操作,例如sync、rollback以及用户定义的其它行为
- 管理Repository和Cluster相关的凭据
- 将身份认证与授权功能委派给外部IdP(identity providers)服务
- 强制实施RBAC
- 监听及转发Git Webhook相关的事件等
repository server
内部服务,用于为相关的git仓库维护1个本地缓存,负责根据输入内容生成和返回本地k8s的配置资源:
- 仓库url、revision(commit、tag、branch)、应用路径
- 模板配置
application controller
- 负责为管理的目标应用程序提供遵循Kubernetes控制器模式的调谐循环
- 它持续监视正在运行的应用程序,并将其当前的活动状态与定义在GitRepo中的期望状态进行比较
- 确保活动状态不断逼近或等同于期望状态
applicationSet controller
- 以模板化形式自动生成由ArgoCD管理的应用程序
- 支持从多个不同的角度构建模板,例如不同的Git Repo,或者不同的Kubernetes Cluster等
- ApplicationSet受控于专用的ApplicationSet Controller
notification controoler
- 持续监控ArgoCD管理的Application,并支持通过多种不同的方式将其状态变化通知给用户(钉钉、企业微信、邮件等)
- 支持Trigger和Template
redis和dex-server
redis提供缓存服务,dex-server提供内存数据库
argo rollouts
可选组件,单独部署
与ingress控制器和服务网格集成,为application提供高级部署功能,如蓝绿部署、金丝雀、渐进式交付(金丝雀)
工作模式
- 用户发起pr合并请求,触发webhook事件
- repository server读取事件并使用redis缓存到本地
- application控制器通过用户定义的配置清单,与redis中缓存配置、k8s中实际运行配置做比较
- 比较配置后有不同之处,则根据定义的配置,做自动化部署或者成为部署pipeline的一部分。后续可根据普罗米修斯的指标数据,自动完成金丝雀流量迁移
CRD配置
演示代码仓库可以克隆到自己本地gitlab中,方便操作
代码仓库:https://gitee.com/mageedu/spring-boot-helloWorld.git
配置仓库:https://gitee.com/mageedu/spring-boot-helloworld-deployment.git
application资源
简写app,资源定义必须在argocd命名空间中
web UI
图形化界面中也可以配置
自动同步策略
自动同步策略允许ArgoCD在检测到GitRepo与实际状态之间存在差异时自动启动同步操作
- Prune Resource(自动修剪):集群上某个资源在GitRepo中找不到对应的配置时,自动删除集群上的该资源
- Self Heal(自愈):因各种原因(如手动修改)集群上资源的实时状态而导致与GitRepo不匹配时,自动将实 际状态与GitRepo的期望状态同步;
同步选项
同步选项(Sync Options)用于禁用或启用同步过程中的某些特性
- ApplyOutOfSyncOnly:仅对那些处于OutOfSync状态的资源执行同步操作
- PrunePropagationPolicy:资源修剪传播策略,默认使用foreground策略(等待完成),另外可选的策略还有background(不等待完成)和orphan (孤儿策略,丢弃出去)
- PruneLast:在同步操作的最后再执行修剪操作,即其它资源已经部署且转为健康状态后再进行Prune
- Replace:对资源的修改,以replace方式进行,而非默认的apply
- FailOnSharedResource:默认的同步操作不会考虑GitRepo中定义的资源是否已经被其它Application所使用,当将该选项设置为true,意味着在发现资源已经被其它Application所使用时,则将同步状态设置为fail
- RespectIgnoreDifferences:在同步阶段忽略期望状态的字段
- CreateNamespace:创建缺失的名称空间
- Validation:是否执行资源规范格式的校验,相当于“kubectl apply --validate={true|false}”,默认为true
命令
argocd app list
argocd app get my-app
argocd app set my-app -p image.tag=v1.0.1
argocd app create spring-boot-hello --repo https://gitee.com/mageedu/spring-boot-helloworld-deployment.git --path deploy/kubernetes --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse --sync-policy auto --self-heal
argocd app delete argocd/spring-boot-hello -y
语法
注:资源必须定义在argocd控制器相同的ns中,否则无法识别
kubectl explain app
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
argocd.argoproj.io/sync-options: Prune=false #pod运行时,git配置仓库中没有运行此版本配置,是否删除pod,false为不删除,默认true,一般删除即可
argocd.argoproj.io/sync-options: validate=false #部署时是否验证yaml语法,默认false为不验证
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true #跳过试运行
argocd.argoproj.io/sync-options: Delete=false #删除app后,保留他们,保留pvc时有用
argocd.argoproj.io/sync-options: PruneLast=true #配置变更做先修改后删除
argocd.argoproj.io/sync-options: Replace=true #更新改替换
argocd.argoproj.io/sync-options: ServerSideApply=true #直接在服务端运行
namespace: argocd
spec:
destination: #应用要部署的k8s集群api-server访问入口
name: str
namespace: str
server: str
ignoreDifferences: #忽略同步的资源,必须配合同步选项RespectIgnoreDifferences=true使用。用于配置仓库与集群状态不匹配时
#当配合istio使用时,需要忽略istio的路由策略,确保流量可以稳定迁移,istio的json忽略路径为:/spec/http/0
- name: str
namespace: str #命名空间
kind: str #资源类型
group: str #资源组
jqPathExpressions: [str] #jq命令的路径匹配方法
jsonPointers: [str] #json格式路径
managedFieldsManagers: [str]
- name: istio-ignore
group: networking.istio.io
kind: kind: VirtualService
jsonPointers:
- /spec/http/0
info:
- name: str
value: str
project: str
revisionHistoryLimit: int
source: #配置仓库以及配置访问、使用方法
path: str #git仓库中配置清单路径
directory:
exclude: str
include: str
jsonnet:
extVars:
- name: str
value: str
code: boolean
libs: [str]
tlas:
- name: str
value: str
code: boolean
recurse: boolean
helm: #由helm指定在chart上使用的自定义资源
fileParameters:
- name: str
path: str
ignoreMissingValueFiles: boolean
parameters:
- name: str
value: str
forceString: boolean
passCredentials: boolean
releaseName: str
skipCrds: boolean
valueFiles: [str]
values: str
valuesObject:
version: str
chart: str #由chart字段指定要使用的chart
kustomize:
commonAnnotations: {}
commonAnnotationsEnvsubst: boolean
commonLabels: {}
forceCommonAnnotations: boolean
forceCommonLabels: boolean
images: [str]
namePrefix: str
nameSuffix: str
namespace: str
replicas: str
version: str
plugin:
name: str
env:
- name: str
value: str
parameters:
- name: str
array: [str]
string: str
map: {}
ref: str
repoURL: str #git仓库
targetRevision: str
sources: #参考source,在此处可定义多个source
- chart: str
helm:
...
syncPolicy: #同步策略配置
automated:
allowEmpty: boolean #是否同步空资源
prune: boolean #自动修剪
selfHeal: boolean #自愈
managedNamespaceMetadata: #为ns设置元数据
annotations: {}
labels: {}
retry: #重试配置
backoff:
duration: str #重试时间
factor: str #重试因子,重试时间累积增长
maxDuration: str #最长重试时间
limit: int #最大重试次数
syncOptions: [str] #配置同步选项
- ApplyOutOfSyncOnly=true #只同步修改部分(OutOfSync状态做同步),一般开启。默认app配置更改时全部同步,pod多时api有压力
- PrunePropagationPolicy=策略 #配置仓库中配置删除时,k8s中对应的内容也要删掉,使用k8s的垃圾回收机制,参考:https://kubernetes.io/zh-cn/docs/concepts/architecture/garbage-collection/
#background,后台删除,相当于异步
#foreground,前台删除,相当于同步
#orphan,单独启动1个回收
- PruneLast=true #配置更新时,集群中进行先修改,后删除(所有资源健康状态后进行)
- Replace=true #配置变更时,使用kubectl create/replace,而不是apply更新(只有在更新可能导致配置不一致时才应该用替换,平时都改更新)
- ServerSideApply=true #配置直接在服务端api-server运行,避免因为某些配置内容字节大小超出cli运行的字节限制。并且允许只给出清单中修改部分(修改deploy控制器副本数时,yaml中只用给出资源、spec.replicas数量就可以),需结合Validate选项
- Validate=false #校验yaml语法,默认true为校验
- FailOnSharedResource=true #如果发现配置中git仓库已经被其他app使用,并运行了,为true时则表示将本次同步状态设为错误
- RespectIgnoreDifferences=true #忽略不同步的资源,必须结合spec.ignoreDifferences字段使用
- CreateNamespace=true #自动创建不存在的ns
示例:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: spring-boot-hello
namespace: argocd
spec:
destination:
namespace: hello
server: https://kubernetes.default.svc #api-server地址
project: default
source:
path: deploy/kubernetes #git仓库中配置清单路径
repoURL: https://gitee.com/mageedu/spring-boot-helloworld-deployment.git #git仓库
syncPolicy:
automated: #开启自愈
selfHeal: true
syncOptions: #同步选项开启
- Validate=false #关闭严格校验语法
- ApplyOutOfSyncOnly=true #开启增量同步
- CreateNamespace=true #自动创建ns
appproj资源
简写:appproj、appprojs
注:default appproj由argocd自动创建,允许用户修改但不能删除
作用:
- 为app提供逻辑分组
- 可限制部署的内容,如指定受信任的git仓库
- 限制app部署的位置,如指定集群和ns
- 限制不允许部署的资源,如rbac、crd、ds、networkPolicy等
- 定义project role,为app提供rbac机制,以绑定到oidc组或jwt token
命令
#配置rbac
argocd proj role list
argocd proj role get
argocd proj role create
argocd proj role delete
argocd proj role add-policy
argocd proj role remove-policy
语法
kubectl explain appproj
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: default
namespace: argocd
spec:
clusterResourceBlacklist: #集群资源黑名单
- group: str
kind: str
clusterResourceWhitelist: #集群资源白名单,允许部署的资源,*为所有
- group: '*' #任意组
kind: '*' #任意资源类型
namespaceResourceBlacklist: #ns资源黑名单
- group: str
kind: str
namespaceResourceWhitelist: #ns资源白名单
- group: str
kind: str
description: 描述
destinations: #允许部署的集群和ns,*为所有
- namespace: '*'
server: '*'
name: str #名称,可选
orphanedResources:
ignore:
- name: str
group: str
kind: str
warn: boolean
permitOnlyProjectScopedClusters: boolean
roles: #允许接入rbac、oauth2等
- name: str #用户名
description: str
groups: [str]
jwtTokens: #jwk认证
- id: str
exp: int
iat: int
policies: [str] #资源访问权限,对哪些资源可增删改查,需根据具体项目来定
signatureKeys:
- keyID: str
sourceNamespaces: [str]
sourceRepos: #允许获取配置的git仓库位置,*为所有
- '*'
syncWindows:
- applications: [str]
clusters: [str]
duration: str
kind: str
manualSync: boolean
namespaces: [str]
schedule: str
timeZone: str
示例
例1:默认创建的appproj
argocd自动创建,允许被修改,但不能被删除
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: default
namespace: argocd
spec:
clusterResourceWhitelist: #允许部署任意类型资源
- group: '*'
kind: '*'
destinations: #允许将app资源部署到任意集群、ns
- namespace: '*'
server: '*'
sourceRepos: #允许从任意仓库源获取配置清单
- '*'
applicationSet资源
简写:appset、appsets
定义可自动生成app的模板,从而在monorepo(一个repo中定义第一个app)或多个repo跨大量集群的场景中自动化管理app
由generator和app模板组成,generator生成kv参数,将参数替换到app模板中,就实现模板化
由独立的控制器applicationset-controller维护
功能
- 目标化集群的模板化,在单个资源配置文件中适配部署到多个k8s集群
- 源git配置仓库的模板化
- 支持monorepo
工作模式
appset控制器仅确保appset资源的期望状态与实际状态保持一致
- ApplicationSet负责管理app,因此appset控制器会生成或更新app资源
- 生成/更新的app资源由app控制器确保期望状态与实际状态保持一致
语法
kubectl explain appset
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
spec:
applyNestedSelectors: boolean
generators: #生成器,生成的参数,参数会被用于渲染template字段中的模板,是模板的数据源
- clusterDecisionResource:
name: str
configMapRef: str
labelSelector:
matchExpressions:
- key: str
operator: str
value: [str]
matchLabels: {}
requeueAfterSeconds: int
template: #直接参考app资源
metadata:
name: str
namespace: str
labels: {}
annotations: {}
finalizers: [str]
spec:
values: {}
clusters: #部署的目标k8s集群生成器
selector:
matchExpressions:
- key: str
operator: str
value: [str]
matchLabels: {}
template: #直接参考app资源
value: {}
git: #git生成器
directories:
- exclude: boolean
path: str
files:
- path: str
pathParamPrefix: str
repoURL: str
requeueAfterSeconds: int
revision: str
template: #直接参考app资源
value: {}
list: #列表生成器
elements: #列表元素,例子中列表的元素作为后面模板的配置文件获取位置,也是集群的ns
- env: dev
- env: stag
- env: prod
elementsYaml: str
template: #直接参考app资源
matrix: #矩阵生成器,在指定的生成器之间做交叉组合生成
generators: #直接参考本资源的.spec.generators部分
template: #直接参考app资源
merge:
generators: #直接参考本资源的.spec.generators部分
mergeKeys: [str]
template: #直接参考app资源
plugin:
configMapRef:
name: str
input:
parameters: {}
requeueAfterSeconds: int
template: #直接参考app资源
values: {}
pullRequest: #对接pr请求的平台
azuredevops:
bitbucket:
bitbucketServer:
filters:
- branchMatch: str
targetBranchMatch: str
gitea:
github:
gitlab:
requeueAfterSeconds: int
template: #直接参考app资源
scmProvider:
awsCodeCommit:
cloneProtocol: str
... #省略部分参考:spec.generators.pullRequest
requeueAfterSeconds: int
template: #直接参考app资源
values: {}
selector:
matchExpressions:
matchLabels: {}
goTemplate: boolean
goTemplateOptions: [str]
preservedFields:
annotations: [str]
strategy:
rollingSync:
- steps:
matchExpressions:
maxUpdate:
type: str
syncPolicy: #资源同步策略
applicationsSync: str
preserveResourcesOnDeletion: boolean #是否在删除当前appset资源时,一起删除由其创建的app。也就是级联删除,false为删除
template: #直接参考app资源,可引用生成器中定义的内容,使用方法为:{{ 生成器变量名 }},与ansible类似
metadata:
name: {{ env }}-名称 #使用生成器变量,对应前面列表生成器的env例子
spec:
...
source:
path: helloworld/{{ env }}
destination:
namespace: '{{ env }}'
示例
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: helloworld
namespace: argocd
spec:
generators:
- list: #列表生成器
elements: ##列表元素,例子中列表的元素作为后面模板的配置文件获取位置,也是集群的ns
- environment: dev
- environment: staging
- environment: prod
template:
metadata:
name: '{{environment}}-spring-boot' #循环取变量
spec:
project: default
source:
repoURL: https://gitee.com/mageedu/spring-boot-helloworld-deployment.git
targetRevision: HEAD
path: helloworld/{{environment}}
destination:
server: https://kubernetes.default.svc
namespace: '{{environment}}'
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- Validate=false
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true