在本文中,我们将探索我发现的一些 Argo 优秀实践。
1. 不允许提供空的 retryStrategy
项目:Argo Workflows
优秀实践: 用户可以指定一个retryStrategy来指示如何在工作流中重试失败或错误的步骤。提供一个空的retryStrategy(即retryStrategy: {})将导致容器重试直到完成并最终导致 OOM 问题。
2. 确保未将 Workflow pod 配置为使用默认服务帐户
项目:Argo Workflows
优秀实践: 工作流中的所有 pod 都可以使用在workflow.spec.serviceAccountName 中指定的服务帐户运行。如果省略,Argo 将使用工作流命名空间的默认服务帐户。这为工作流(即 pod)提供了与 Kubernetes API 服务器交互的能力。这允许访问单个容器的攻击者通过使用AutomountServiceAccountToken滥用 Kubernetes 。禁用了AutomountServiceAccountToken选项,那么 Argo 将使用的默认服务帐户将没有任何权限,并且工作流将失败。
建议创建具有适当角色的专用用户管理服务帐户。
3. 确保 ConfigMaps label 中存在 part-of: argocd
项目:Argo CD
优秀实践: Argo CD 不会使用未标记app.kubernetes.io/part-of: argocd 的相关 ConfigMap 资源。
安装 Argo CD 时,其原子配置包含一些services和configMaps。对于每种特定类型的 ConfigMap 和 Secret 资源,只有一个受支持的资源名称,如果您需要在创建它们之前合并您需要做的事情。使用标签 app.kubernetes.io/part-of: argocd 注释您的 ConfigMap 资源很重要,否则 Argo CD 将无法使用它们。
4. 用 DAG 禁用以设置 FailFast = false
项目:Argo Workflows
优秀实践: 作为在Workflow中指定步骤序列的替代方法,您可以通过指定每个任务的依赖关系将工作流定义为有向无环图 (DAG)。DAG 逻辑具有内置的快速故障功能,可在检测到其中一个 DAG 节点发生故障时立即停止调度新步骤。然后它会等到所有 DAG 节点都完成后才会使 DAG 本身失败。FailFast[4]标志默认为true。如果设置为false,它将允许 DAG 运行 DAG 的所有分支以完成(成功或失败),而不管 DAG 中分支的失败结果。
5. 确保 Rollout 暂停步骤具有配置的持续时间
项目:Argo Rollouts
优秀实践: 对于每个 Rollout,我们可以定义一个步骤列表。每个步骤都可以有两个字段之一:setWeight和pause。setWeight字段指示应该发送到金丝雀的流量百分比,而 pause字面意思是指示部署暂停。
在幕后,Argo 控制器使用这些步骤在推出期间操作 ReplicaSet。当控制器达到推出的暂停步骤时,它会将PauseCondition结构添加到.status.PauseConditions字段。如果设置了暂停结构中的持续时间字段,则在等待持续时间字段的值之前,部署不会进行到下一步。但是,如果省略了持续时间字段,则推出可能会无限期地等待,直到添加的暂停条件被删除。
6. 指定 Rollout 的 revisionHistoryLimit
项目:Argo Rollouts
优秀实践: .spec.revisionHistoryLimit 是一个可选字段,指示应保留的旧 ReplicaSet 的数量以允许回滚。这些旧的 ReplicaSet 消耗 etcd 中的资源并挤占kubectl get rs的输出。每个 Deployment 修订的配置都存储在它的 ReplicaSets 中;因此,一旦删除了旧的 ReplicaSet,您就无法回滚到该版本的 Deployment。
默认情况下,会保留 10 个旧 ReplicaSet,但其理想值取决于新 Deployment 的频率和稳定性。更具体地说,将此字段设置为零意味着将清除所有具有 0 个副本的旧 ReplicaSet。在这种情况下,新的部署无法撤消,因为它的修订历史已被清除。
7. 将 scaleDownDelaySeconds 设置为 30s 以确保 iptables 跨集群中的节点传播
项目:Argo Rollouts
优秀实践: 当 rollout 更改service上的selector时,在所有节点更新其 iptables以将流量发送到新 Pod 而不是旧 Pod 之前存在传播延迟。如果在此延迟期间节点尚未更新,则流量将被定向到旧 pod。为了防止数据包被发送到杀死旧 pod 的节点,rollout 使用scaleDownDelaySeconds字段给节点足够的时间广播 iptables 的变化。如果省略,Rollout 会等待 30 秒,然后再缩减之前的 ReplicaSet。
建议将scaleDownDelaySeconds设置为至少 30 秒,以确保 iptables在集群中的节点间传播。原因是 Kubernetes 等待一个称为终止宽限期的指定时间。默认情况下,这是 30 秒。
8. 确保在 Error 和 TransientError 时重试
项目:Argo Workflows
优秀实践: retryStrategy是Workflow CRD 的一个可选字段,它提供了用于重试工作流步骤的控件。retryStrategy的字段之一是retryPolicy,它定义了将被重试的 NodePhase 状态的策略(NodePhase 是当前节点的状态)。retryPolicy的选项可以是:Always、OnError或OnTransientError。此外,用户可以使用表达式[9]来控制更多的重试次数。
- retryPolicy=Always:用户只想重试系统级错误(例如,节点死亡或被抢占),但不想重试用户级代码中发生的错误,因为这些失败表明存在错误。此外,与作为作业的工作流相比,此选项更适合长时间运行的容器。
- retryPolicy=OnError:不处理抢占,处理一些系统级错误,例如节点消失或 pod 被删除。但是,在 Pod 正常终止期间,kubelet 会为终止的 Pod 分配一个失败状态和一个关闭原因。因此,节点抢占导致节点状态为Failure,而不是Error,因此不会重试抢占。
我们建议设置retryPolicy: "Always"并使用以下表达式:
'lastRetry.status == "Error" or (lastRetry.status == "Failed" and asInt(lastRetry.exitCode) not in [0])'
- 1.
9. 确保 progressDeadlineAbort 设置为 true,特别是如果 progressDeadlineSeconds 已设置
项目:Argo Rollouts
优秀实践: 用户可以设置progressDeadlineSeconds,它以秒为单位说明在更新期间推出必须取得进展的最长时间,然后才被认为失败。
如果 rollout pod 陷入错误状态(例如image pull back off),则 rollout 会在超过进度期限后降级,但错误的replica set/pods 不会按比例缩小。Pod 将不断重试,最终推出消息将显示ProgressDeadlineExceeded: The replicaset has timed out progressing。要中止推出,用户应同时设置progressDeadlineSeconds和设置progressDeadlineAbort: true
10. 确保自定义资源与 ArgoCD 实例的命名空间匹配
项目:Argo CD
优秀实践: 在每个存储库中,所有Application和AppProject清单都应匹配相同的metadata.namespace。原因实际上取决于您如何安装 Argo CD。
如果您在典型部署中部署了 Argo CD,则 Argo CD 会在后台创建两个ClusterRoles和ClusterRoleBinding,默认情况下它们引用argocd命名空间。在这种情况下,建议不仅要确保所有 Argo CD 资源与 Argo CD 实例的命名空间匹配,还要使用argocd命名空间,否则,您需要确保更新所有 Argo CD 内部资源中的命名空间引用。
但是,如果您为外部集群部署 Argo CD(在“命名空间隔离模式”中),那么 Argo 会在部署 Argo CD 的命名空间中创建角色和关联的RoleBinding,而不是ClusterRole和ClusterRoleBinding。创建的服务帐户被授予有限级别的管理访问权限,因此要使 Argo CD 能够按需要运行,必须明确授予对命名空间的访问权限。在这种情况下,建议确保所有资源,包括 Application和AppProject,使用 ArgoCD 实例的正确命名空间。
原文:https://datree.io/resources/argocd-best-practices-you-should-know