目录标题
- 遇事不决,上github
- if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas
- 问题分析
- 如何解决并使集群恢复到正常状态
- 1. **检查和分配未分配的副本分片**
- 2. **查看节点日志**
- 3. **检查资源配置**
- 4. **手动升级节点**
- 5. **修改 `if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas` 策略**
- 6. **等待集群稳定**
- 总结
 
 
- phases
- 1. **ECK Operator 和 CR 状态**
- 2. **控制 `phases` 的行为**
- 3. **`phase` 和 `status` 字段**
- 4. **常见操作和触发 `phase` 变化**
- 5. **控制 `phase` 的具体行为**
- 总结
 
 
- conditions
- 1. **`conditions` 字段概述**
- 2. **`conditions` 是如何计算和更新的?**
- 3. **ECK Operator 相关代码**
- 4. **查看 ECK 代码中的条件类型定义**
- 5. **如何通过代码修改或调试条件**
- 总结
 
 
遇事不决,上github
https://github.com/search?q=repo%3Aelastic%2Fcloud-on-k8s%20if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas&type=issues
https://github.com/elastic/cloud-on-k8s/issues/7099
https://github.com/elastic/cloud-on-k8s/issues/4625
https://github.com/elastic/cloud-on-k8s/pull/4786


if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas

从你提供的 Elasticsearch CR 状态来看,集群正在进行升级,并且由于一些副本分片未分配,导致集群健康状态为 yellow,而且存在一些节点因为无法重启而处于 PENDING 状态。
问题分析
在你的状态中,关键的部分是以下几点:
-  Health 状态: yellow
 这通常意味着 Elasticsearch 集群中的某些副本分片无法分配。副本分片(replicas)未能分配到适当的节点上,可能是因为没有足够的资源(如节点或存储)来承载副本分片。
-  Upgrade 状态: Cannot restart node because of failed predicate
 这表示升级过程无法继续,因为节点无法按预期重启。升级过程中的一个predicate检查(if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas)失败。具体来说,这个检查的条件是,当集群健康状况为yellow(意味着副本分片未分配时),只能重启那些没有未分配副本分片的节点。
-  Phase: ApplyingChanges
 当前集群的状态为ApplyingChanges,这表示集群正在进行配置更改或操作,通常是升级或扩展过程中。这可能是集群还没有完全稳定下来。
如何解决并使集群恢复到正常状态
以下是一些可能的步骤来帮助将 CR 状态恢复到“启动”状态:
1. 检查和分配未分配的副本分片
集群的健康状态为 yellow,这意味着有副本分片未分配。需要确保所有副本分片都能分配到节点上。
你可以使用以下命令查看当前的分片状态,找出未分配的副本分片:
curl -X GET "localhost:9200/_cat/shards?v"
在返回的结果中,查看副本分片(Replica Shards)是否存在问题,确保没有副本分片处于 UNASSIGNED 状态。
如果存在未分配的副本分片,你可以手动触发重新分配副本分片:
curl -X POST "localhost:9200/_cluster/reroute"
这将强制 Elasticsearch 尝试重新分配未分配的分片。这样有可能帮助集群恢复到 green 状态。
2. 查看节点日志
日志中通常会记录节点无法重启的原因。使用以下命令查看相关节点的日志,了解重启失败的具体原因:
kubectl logs <node_pod_name>
尤其是查看 es-1fe5b379-es-data-0、es-1fe5b379-es-data-1、es-1fe5b379-es-data-2 节点的日志,以便找出为什么它们无法重启。
3. 检查资源配置
由于集群状态为 yellow 和升级中,可能是资源(如 CPU、内存、磁盘等)不足,导致副本分片未能分配。你可以检查这些节点的资源配置并确保有足够的资源。
可以通过以下命令查看节点的资源使用情况:
kubectl describe pod <pod_name>
根据集群的资源状况,调整 Elasticsearch CR 的资源限制(如 cpu 和 memory)来确保节点有足够的资源来完成操作。
4. 手动升级节点
由于升级过程中存在节点未重启的问题,你可以尝试手动重启这些节点。可以删除相应的 Elasticsearch Pods,ECK 将根据 CR 配置重新创建它们:
kubectl delete pod <pod_name> -n <namespace>
这将触发节点重新启动并应用新的配置。确保 Pod 重启后能够成功加入集群并分配副本分片。
5. 修改 if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas 策略
 
由于当前升级过程受到了 if_yellow_only_restart_upgrading_nodes_with_unassigned_replicas 规则的限制,你可以考虑暂时修改升级策略,使其忽略黄色健康状态下的副本分片问题,允许节点重启。要实现这一点,你可以暂时更改 Elasticsearch CR 配置中的升级策略,禁用此类条件,或调整分片的副本数量。
修改 CR 配置示例:
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:name: es-1fe5b379
spec:version: 7.16.2nodeSets:- name: defaultcount: 3config:elasticsearch.yml: |# additional config if necessarypodTemplate:spec:containers:- name: elasticsearchresources:limits:memory: 4Gicpu: "2"requests:memory: 2Gicpu: "1"
保存并应用配置文件后,ECK 将根据新的配置重新进行处理。
6. 等待集群稳定
有时候,在执行升级或扩容操作时,Elasticsearch 集群需要一些时间来稳定,尤其是当数据量较大或集群节点较多时。你可以耐心等待集群完成升级并恢复正常状态。
可以通过以下命令监控集群的状态:
kubectl get elasticsearch <elasticsearch_name> -o yaml
查看 phase 和 conditions 字段,确保集群最终进入了 RunningDesiredVersion 状态,并且健康状况变为 green。
总结
要将 Elasticsearch CR 状态从 ApplyingChanges 或 yellow 状态转为“启动”状态,首先需要解决副本分片未分配的问题,检查并确保集群资源充足,查看并修复升级过程中出现的节点重启问题。如果有必要,可以修改升级策略或暂时调整集群配置,手动触发节点重启,或者等待集群完成自动修复。
phases
在 Elastic Cloud on Kubernetes (ECK) 中,phases 是由 ECK Operator 来控制的。ECK Operator 是一个 Kubernetes 控制器,负责管理 Elasticsearch 集群的生命周期,确保集群的状态符合定义的期望,并协调相关操作如创建、升级、扩展、缩减等。
1. ECK Operator 和 CR 状态
ECK Operator 通过不断监视并管理 Custom Resources (CR)(如 Elasticsearch、Kibana、ApmServer 等),确保这些资源的状态符合配置文件中的要求。当你创建、更新或删除 CR 时,ECK Operator 会根据这些操作自动更新集群状态,并根据需要执行相应的操作。
phase 字段反映了 Elasticsearch 集群当前的生命周期阶段,通常有以下几个常见的状态:
- ApplyingChanges:表示正在应用配置更改,通常是在集群的升级、扩容或缩减过程中。
- Starting:表示集群正在启动。
- Rebalancing:表示集群正在重新平衡分片和节点。
- Ready:表示集群处于稳定状态,所有预定的配置都已应用,集群运行正常。
- Terminating:表示集群正在终止并销毁。
2. 控制 phases 的行为
 
ECK Operator 控制 CR 状态的过渡,主要通过以下几种操作:
-  创建和删除资源:ECK Operator 会根据 CR 中定义的集群配置来创建或删除 Elasticsearch 节点、Pod、PVC(持久化卷声明)等资源。 
-  版本升级:ECK Operator 会自动进行集群的版本升级操作,并根据 CR 中定义的 version字段来决定集群的升级过程。升级过程中,ECK 会将集群的状态从Starting或ApplyingChanges更改为Ready。
-  扩容和缩容:如果你在 CR 中修改了 nodeSets的count字段,ECK Operator 会根据新的节点数来扩展或缩减 Elasticsearch 集群,并控制集群的状态。
-  分片迁移和再平衡:在集群健康状态或配置更改时,ECK Operator 会自动管理分片的迁移和再平衡操作。比如,如果副本分片未分配,ECK 会自动管理分片分配的过程,确保集群健康。 
3. phase 和 status 字段
 
-  phase字段:用于表示集群当前的生命周期状态。它是由 ECK Operator 基于集群的实际操作和条件动态更新的。
-  status字段:包含更多关于集群状态的详细信息,诸如:- availableNodes:表示当前集群中可用节点的数量。
- conditions:包含条件检查的结果,帮助判断集群是否正常运行。例如,“是否达到期望的版本”,“集群是否可以访问”,“是否正在执行某些操作”等。
 
4. 常见操作和触发 phase 变化
 
以下是一些常见的操作及其如何影响 phase 的变化:
-  创建 CR(创建 Elasticsearch 集群): - ECK Operator 会启动集群并通过 phase更新为Starting或ApplyingChanges,直到所有节点和资源都准备好并且集群稳定后,phase将变为Ready。
 
- ECK Operator 会启动集群并通过 
-  升级版本: - 当 ElasticsearchCR 中的version字段更改时,ECK Operator 会触发升级过程,集群的phase会变为ApplyingChanges,然后是Upgrading,最后升级完成后变为Ready。
 
- 当 
-  扩容/缩容: - 修改 nodeSets.count时,ECK Operator 会调整节点数,phase会变化为Rebalancing,然后恢复为Ready。
 
- 修改 
-  发生故障: - 如果节点、Pod 或存储出现故障,ECK Operator 会尝试修复集群,集群的 phase可能会变为ApplyingChanges或Starting,直到问题解决。
 
- 如果节点、Pod 或存储出现故障,ECK Operator 会尝试修复集群,集群的 
5. 控制 phase 的具体行为
 
要直接控制或监控 phase,你通常会通过以下方式操作:
-  查看当前状态: 
 你可以通过kubectl describe或kubectl get命令查看 CR 状态,并查看phase和其他详细信息:kubectl describe elasticsearch <your-es-cluster-name>这将展示集群的当前 phase和status,以及相关的conditions信息。
-  修改配置并触发集群操作: 
 你可以通过修改 CR 来触发新的操作,例如扩容、缩容或升级,从而影响phase的变化。例如,如果你需要升级集群版本,可以修改 version字段,并通过kubectl apply来应用更改:apiVersion: elasticsearch.k8s.elastic.co/v1 kind: Elasticsearch metadata:name: my-es-cluster spec:version: "7.16.3" # 修改为目标版本nodeSets:- name: defaultcount: 3然后执行: kubectl apply -f elasticsearch.yaml这会触发 ECK Operator 进行版本升级, phase由Ready或Starting变为ApplyingChanges,然后根据操作完成后的状态更新为Ready。

总结
phase 是由 ECK Operator 控制的,它通过管理 Elasticsearch CR 对象及其生命周期,动态更新集群的状态。ECK Operator 会根据集群的状态(如创建、升级、扩容、重启等)自动更新 phase 字段,确保集群状态与期望配置保持一致。
conditions
在 Elastic Cloud on Kubernetes (ECK) 中,conditions 字段是 Elasticsearch 和其他自定义资源(CR)状态的一部分,用于描述集群当前的健康状况和是否满足特定的条件。这些条件是在 ECK Operator 内部根据集群的不同状态自动计算和更新的。
1. conditions 字段概述
 
conditions 字段包含一个数组,每个条件项都有以下字段:
- type: 条件的类型,如- ElasticsearchIsReachable、- ReconciliationComplete、- RunningDesiredVersion等。
- status: 条件的状态,通常为- True、- False或- Unknown。
- lastTransitionTime: 条件状态最后一次变化的时间。
- message: 与条件相关的附加信息,帮助理解为什么某个条件未满足或已满足。
2. conditions 是如何计算和更新的?
 
这些条件是由 ECK Operator (位于控制平面中的 elastic-operator)在后台计算和更新的。ECK Operator 会检查 Elasticsearch 集群的健康、版本、节点状态、服务可达性等,生成相应的条件并更新 CR 状态。
具体来说,ECK Operator 在 控制循环(reconciliation loop)中执行以下操作:
- 检查是否所有的 Elasticsearch 节点都在运行并且是最新版本。
- 检查是否所有的集群组件(如 HTTP 服务端点、数据节点等)都可达。
- 检查集群是否处于稳定状态(例如,所有分片都已分配,集群健康等)。
这些检查会更新 CR 的 conditions 字段,并反映在 kubectl describe 或 API 响应中。
3. ECK Operator 相关代码
要查看具体的条件如何被计算和更新,你需要查看 ECK Operator 的源代码,特别是控制器的实现部分。ECK 的源代码托管在 GitHub 上:
 ECK GitHub 仓库
具体的实现逻辑可以在以下几个地方找到:
-  Conditions 计算逻辑:条件的更新通常在 Operator 的 reconcile方法中进行,该方法负责同步集群的期望状态和实际状态。- Controller Reconcile:在 operator的controllers目录下,特别是elasticsearch控制器(elasticsearch_controller.go)中,你可以找到关于条件计算的逻辑。
 例如,在 elasticsearch_controller.go中,条件状态是通过检查集群健康、版本升级状态、服务是否可达等信息来设置的。这个文件可以帮助你理解如何计算和更新条件。
- Controller Reconcile:在 
-  条件类型定义:在 api/v1目录下,conditions的类型定义通常位于自定义资源定义(CRD)文件中,如elasticsearch_types.go。这些定义描述了不同类型的条件及其结构。
4. 查看 ECK 代码中的条件类型定义
如果你对条件的具体实现有兴趣,以下是一些在 ECK 源代码中可能相关的文件和路径:
-  条件类型定义: - 文件路径:pkg/apis/elasticsearch/v1/elasticsearch_types.go或类似的 CRD 文件。
- 在该文件中,conditions通常会定义为一个Condition类型,描述条件的状态和类型。
 示例: type Condition struct {Type string `json:"type"`Status string `json:"status"`LastTransitionTime metav1.Time `json:"lastTransitionTime"`Message string `json:"message"` }
- 文件路径:
-  条件更新逻辑: - 文件路径:pkg/controller/elasticsearch中的elasticsearch_controller.go,其中包括集群状态检查、版本检查、健康检查等。
 示例: // Reconcile Elasticsearch cluster. func (r *ReconcileElasticsearch) Reconcile(req reconcile.Request) (reconcile.Result, error) {// 逻辑:检查集群健康状况并更新条件字段 }
- 文件路径:
5. 如何通过代码修改或调试条件
如果你想修改或调试 conditions 字段的更新逻辑,可以在以下几个步骤中进行:
- 查找 Reconcile函数中更新conditions的部分。
- 在 elasticsearch_controller.go中,找到如何根据集群的健康状况、版本和服务可达性来判断每个条件是否满足。
- 如果你希望修改某个条件的计算方式或增加新的条件类型,你可以直接修改这些控制器逻辑,并重新部署 ECK Operator。
总结
conditions 字段的计算和更新逻辑位于 ECK Operator 的代码中,特别是在 elasticsearch_controller.go 和 elasticsearch_types.go 中。条件的状态帮助用户了解集群的健康、版本状态、服务可达性等信息,所有这些条件都在 ECK 的控制循环中自动计算和更新。