fix(probe): named-port resolution + IntOrString port deserialization#49
Open
indyjonesnl wants to merge 5 commits into
Open
fix(probe): named-port resolution + IntOrString port deserialization#49indyjonesnl wants to merge 5 commits into
indyjonesnl wants to merge 5 commits into
Conversation
EmptyDir conformance tests [Conformance].*EmptyDir.*(mode|0644|0666|0777) rely on the volume directory being mode 0o777 on the host. The chmod was already in create_volume but inlined and untested, so a silent regression would only surface during a full conformance run. - Extract the create_dir_all + chmod 0o777 path into a pure setup_emptydir_dir helper, idempotent for stale dirs. - Add four unit tests covering new dir, stale-perms re-chmod, nested parents, and the full Linux rwx bit pattern. The 4 failing macOS conformance tests are a virtiofs limitation (host mode bits not propagated through Podman Machine / Docker Desktop shared FS); on Linux CI the chmod path verified here is sufficient. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WebSocket exec now implements v5.channel.k8s.io protocol with stdin (channel 0), stdout (1), stderr (2), error (3), resize (4), plus v5 close-stream control. Kubelet runtime captures container exit code via bollard inspect for lastState.terminated.exitCode. PreStop lifecycle handler invoked before SIGTERM and respects terminationGracePeriodSeconds. Closes conformance gap (Unit 12): preStop, container exit status, exec over websockets.
Persist init container status updates between actions so watches observe each transition (Running, Terminated, CrashLoopBackOff). Without these updates, a failing init container's Terminated state was never written before container removal, so get_init_container_statuses fell back to the Running prev state on retry. That suppressed CrashLoopBackOff reporting and pinned restart_count at 0, hanging the K8s conformance tests that wait for restart_count >= 3 and for the failed-init pod to reach Failed. - Publish Running state after start_container, Terminated after a successful wait, Terminated/error before remove_container on failure. - Extract refresh_init_container_statuses helper to eliminate four near-identical pod-read / get_init_container_statuses / pod-write blocks. - RestartPolicy=Never still propagates the error immediately, so remaining init containers do not run and the pod transitions to Failed via the existing kubelet.rs error handler. Targets Kubernetes v1.35 conformance: - [Conformance] InitContainer should not start app containers if init containers fail on a RestartNever pod - [Conformance] InitContainer should restart with CrashLoopBackOff on a RestartAlways pod
Probe action types hard-coded port as i32. K8s spec defines these as IntOrString — int port OR named port from container.ports[].name. Any pod YAML using named-port probes (e.g. `port: http`) failed at deserialization with "invalid type: string, expected i32", blocking a core K8s feature. - Change HTTPGetAction.port, TCPSocketAction.port, GRPCAction.port to IntOrString. - Add resolve_probe_port(&IntOrString, &Container) helper that looks up named ports against the container's declared ports[].name; ints pass through with u16 range check; unknown named ports fall back to parsing the string as a number, else return None. - Derive PartialEq/Eq on IntOrString so tests can assert ports directly. - Update test sites + lifecycle-hook helper to wrap with IntOrString::Int. - Add three unit tests pinning the YAML/JSON parse contract + the resolver semantics. Probe execution sites in runtime.rs still pass IntOrString through Display in format!() — that produces "http" for named ports, which fails at connect time but no longer crashes pod creation. Resolving named ports through container.ports is a follow-up at the call sites.
…ites Follow-up to f7bb64e — wires the resolve_probe_port helper through check_http_probe / check_tcp_probe / check_grpc_probe and the lifecycle handler (postStart / preStop hooks). Named ports referenced from probes or lifecycle handlers now look up the container's declared ports[].name to obtain a u16 at connect time. Unresolvable named ports cause the probe to fail (Ok(false)) or the lifecycle hook to error out, both matching K8s kubelet behavior. - check_probe now takes &Container in addition to container_name; the four callers (startup + liveness in two reconcile paths) pass it through. - execute_lifecycle_handler now takes &Container; both call sites updated. - stop_pod_for builds a name -> Container lookup from the pod spec so the preStop hook futures carry the matching spec for each container. Probe execution end-to-end now respects K8s IntOrString port semantics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Probe action types (`HTTPGet`, `TCPSocket`, `GRPC`) hard-coded `port` as `i32`. The K8s spec says `port` is `IntOrString` — either a numeric port or a named port from `container.ports[].name`. Any pod YAML using named-port probes (e.g. `port: http`) failed at deserialization with "invalid type: string, expected i32", blocking a core Kubernetes feature.
Fix
Two commits:
`fix(probe): make HTTPGet/TCPSocket/GRPC port IntOrString per K8s spec`
Change the `port` field on each probe action type from `i32` to `IntOrString`. Deserialization now accepts both numeric and named ports.
`feat(probe): resolve named ports via container.ports[].name at call sites`
At every probe call site in the kubelet, resolve named ports against the container's `ports[]` definition before dialing. Falls back to error if a named port isn't declared on the container.
Stacking note
This PR is stacked on top of #47 (`kubelet-improvements`) — both touch `crates/kubelet/src/runtime.rs` and cherry-picking onto raw `main` produces context-overlap conflicts in the preStop hook region. Once #47 lands, the diff on this PR collapses to just the two probe commits. Please review #47 first.
Verification
`cargo build --workspace --locked` clean. Depends on #32 + #47 for green CI.