Sitelet https://github.com/kubernetes/kops/pull/18657
Skip to content

fix(channels): only treat known ready conditions as health signals - #18657

Merged
kubernetes-prow[bot] merged 2 commits into
kubernetes:masterfrom
argoyle:fix/applyset-ready-condition-types
Aug 2, 2026
Merged

kubernetes-prow[bot] merged 2 commits into
kubernetes:masterfrom
argoyle:fix/applyset-ready-condition-types

Conversation

@argoyle

@argoyle argoyle commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

isHealthy() marked an object unhealthy on any status.conditions entry with a "False" status, regardless of the condition type — the code carried a // TODO: Check conditionType? at exactly that spot.

Plenty of controllers publish conditions where "False" carries no readiness meaning:

  • KEDA sets Paused: "False" on every ScaledObject/ScaledJob it is actively scaling, plus Active: "False" while idle and Fallback: "False" when no fallback is configured.
  • A perfectly healthy Node reports MemoryPressure, DiskPressure and PIDPressure as "False".

Objects like these are permanently unhealthy, so any addon containing one can never be applied successfully:

health.go:110] status.conditions indicates object ScaledJob.keda.sh:gitea-runner/gitea-actions-runner is not ready: {"status":"False","type":"Paused"}
apply_channel.go:119] error in apply iteration (will retry in 5s): applying "s3://.../addon.yaml": updating "gitea-actions-runner": error applying update: not all objects were healthy

Since #18433 the kops-channels pod derives its readiness from the result of the last apply iteration, so this now also leaves the pod permanently not ready and kops validate cluster failing:

Pod  kube-system/kops-channels-i-04575c45245649442  system-node-critical pod "kops-channels-i-04575c45245649442" is not ready (kops-channels)

This PR only considers condition types whose "True" status means the object is healthy (Available, Ready, Established, …) and ignores everything else.

Abnormal-true conditions (Degraded, ReplicaFailure, the Node pressure conditions) are deliberately not interpreted as failures. That matches the current behaviour — a "True" status has never marked an object unhealthy — and keeps this change to fixing the false negatives rather than introducing new ways for an apply to fail.

The // TODO: Replace with kstatus library above isHealthy() still stands; this is a targeted fix, not that replacement.

Which issue(s) this PR fixes:

Special notes for your reviewer:

Adds health_test.go, which the package did not have. The table covers the KEDA and Node cases above, plus the existing behaviours worth pinning down: deletion timestamp, absent and null status.conditions, the kinds short-circuited by GVK, an unavailable Deployment, and a CRD with NamesAccepted: "False". Reverting the type check turns 3 of the cases red.

isHealthy() marked an object unhealthy on any status condition with a
"False" status, regardless of the condition type. Controllers routinely
publish conditions that carry no readiness meaning: KEDA sets "Paused" to
"False" on every ScaledObject and ScaledJob it is actively scaling, and a
healthy Node reports "MemoryPressure", "DiskPressure" and "PIDPressure" as
"False". Such objects were permanently unhealthy, so an addon containing
one could never be applied successfully.

Since kops 1.36 the kops-channels pod reports readiness from the result of
the last apply iteration, so this also leaves the pod permanently not ready
and cluster validation failing.

Only consider condition types whose "True" status means the object is
healthy, and ignore the rest. Abnormal-true conditions are deliberately not
interpreted, matching the previous behaviour for those.

Signed-off-by: Joakim Olsson <joakim@unbound.se>
@kubernetes-prow kubernetes-prow Bot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Aug 1, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

Welcome @argoyle!

It looks like this is your first PR to kubernetes/kops 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kops has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@kubernetes-prow kubernetes-prow Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 1, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

Hi @argoyle. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@kubernetes-prow
kubernetes-prow Bot requested review from hakman and olemarkus August 1, 2026 09:22
@hakman hakman changed the title fix: only treat known ready conditions as health signals fix(channels): only treat known ready conditions as health signals Aug 1, 2026

@hakman hakman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the KEDA and Node cases, but it can hide known resource-specific failures. A Deployment may have Available=True while Progressing=False/ProgressDeadlineExceeded; Gateways use Accepted and Programmed.

Could we add a small GroupKind-specific condition map for:

  • apps/Deployment: Progressing
  • Gateway: Accepted, Programmed
  • GatewayClass: Accepted

I’d also remove or reword the stale kstatus TODO.

"PodScheduled", // Pod
"Ready", // Pod, Node, and the convention for custom resources
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+var readyConditionTypesByGroupKind = map[schema.GroupKind]sets.Set[string]{
{Group: "apps", Kind: "Deployment"}: sets.New("Progressing"),
{Group: "gateway.networking.k8s.io", Kind: "Gateway"}: sets.New("Accepted", "Programmed"),
{Group: "gateway.networking.k8s.io", Kind: "GatewayClass"}: sets.New("Accepted"),
}

Comment thread pkg/applylib/applyset/health.go Outdated
}

// TODO: Check conditionType?
if !readyConditionTypes.Has(conditionType) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !readyConditionTypes.Has(conditionType) {
if !readyConditionTypes.Has(conditionType) &&
!readyConditionTypesByGroupKind[gvk.GroupKind()].Has(conditionType) {

Comment thread pkg/applylib/applyset/health.go Outdated
)

// isHealthy reports whether the object should be considered "healthy"
// TODO: Replace with kstatus library

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// TODO: Replace with kstatus library

A Deployment can report "Available" as "True" while "Progressing" is
"False" with reason ProgressDeadlineExceeded, and Gateway API resources
signal readiness through "Accepted" and "Programmed" rather than through a
"Ready" condition. Reading only the kind-independent conditions would report
all of those as healthy.

Add a GroupKind-keyed map of extra readiness conditions, consulted on top of
the kind-independent set, and reword the stale kstatus TODO.

Signed-off-by: Joakim Olsson <joakim@unbound.se>
@argoyle

argoyle commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — the Deployment case is a real hole, Available genuinely does stay True across a ProgressDeadlineExceeded.

Added readyConditionTypesByGroupKind, consulted on top of the kind-independent set:

var readyConditionTypesByGroupKind = map[schema.GroupKind]sets.Set[string]{
	{Group: "apps", Kind: "Deployment"}:                        sets.New("Progressing"),
	{Group: "gateway.networking.k8s.io", Kind: "Gateway"}:      sets.New("Accepted", "Programmed"),
	{Group: "gateway.networking.k8s.io", Kind: "GatewayClass"}: sets.New("Accepted"),
}

Keyed on the full GroupKind rather than the kind alone, so an unrelated Gateway (Istio's networking.istio.io/Gateway, say) is not held to Gateway API conditions. Lookups of an absent kind yield a nil set, and Has on that is false, so there is no extra branch on the hot path.

The kstatus TODO is gone, replaced by a note on the doc comment that kstatus is the fuller implementation if this ever needs to grow beyond the kinds kops applies.

New test cases: a Deployment with Available=True/Progressing=False, gateway programmed and not-programmed, gateway class accepted and rejected, plus a custom resource carrying Progressing=False that stays healthy — that one pins the scoping, so the map cannot quietly leak to other kinds. Emptying the map turns 3 of them red.

@hakman

hakman commented Aug 2, 2026

Copy link
Copy Markdown
Member

/ok-to-test

@kubernetes-prow kubernetes-prow Bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 2, 2026
@hakman

hakman commented Aug 2, 2026

Copy link
Copy Markdown
Member

/test pull-kops-aws-upgrade-k135-ko135-to-k136-kolatest-many-addons

@hakman

hakman commented Aug 2, 2026

Copy link
Copy Markdown
Member

Thanks for the report and for the fix.
/lgtm
/approve

@kubernetes-prow kubernetes-prow Bot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 2, 2026
@hakman

hakman commented Aug 2, 2026

Copy link
Copy Markdown
Member

/hold

@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: hakman

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow kubernetes-prow Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Aug 2, 2026
@hakman

hakman commented Aug 2, 2026

Copy link
Copy Markdown
Member

/unhold

@kubernetes-prow kubernetes-prow Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 2, 2026
@kubernetes-prow
kubernetes-prow Bot merged commit 362646c into kubernetes:master Aug 2, 2026
27 checks passed
@argoyle
argoyle deleted the fix/applyset-ready-condition-types branch August 2, 2026 09:53
kubernetes-prow Bot added a commit that referenced this pull request Aug 2, 2026
…-upstream-release-1.36

Automated cherry pick of #18657: fix(channels): only treat known ready conditions as health signals
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants