P4: hardening and beta readiness#34
Merged
Merged
Conversation
Expose MacVz node and workload resource usage to Kubernetes through the Virtual Kubelet kubelet server, so operators and metrics-server can observe capacity, usage, and runtime health. - runtime.Stater: optional capability returning per-workload CPU/memory; the apple/container driver implements it via `container stats --format json`, with missing/stopped VMs mapped to ErrStatsUnavailable for graceful degrade. - pkg/metrics.Collector: assembles the kubelet Summary (/stats/summary) and Prometheus resource metrics (/metrics/resource), derives nanocore rates across samples, and sources node memory from the host (darwin sysctl/vm_stat). - Provider.StatsSummary / MetricsResource wired into the kubelet PodHandler. - Recognize "no such container" as ErrNotFound in the driver error mapping. - docs/METRICS.md documents metric names, units, endpoints, and limitations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mount a beta-scoped set of Kubernetes volumes into Pod micro-VMs over apple/container's VirtioFS shares, with a secure-by-default policy. - types.Mount + ContainerSpec.Mounts; the apple/container driver emits --volume source:target[:ro] for bind mounts and --tmpfs for guest-local scratch, before the image argument. - Supported sources: emptyDir (per-Pod host dir under node.volumes.root, or guest tmpfs for medium: Memory) and hostPath. hostPath is disabled unless an operator allowlists absolute prefixes; sources are cleaned and prefix-checked (segment-aware, so /srv does not admit /srvother), and only directory types are accepted. subPath and unsupported sources fail with a clear status. - Provider materializes emptyDir backing dirs on CreatePod and removes them on DeletePod/rollback; volume resolution is wired through translatePod. - node.volumes config (root + hostPathAllowedPrefixes) with absolute-path validation; provider option threaded from main.go. - docs/VOLUMES.md documents supported types, config, security model, and limitations. Live integration test verifies ro read, rw host persistence, and tmpfs writes end-to-end. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make guest architecture handling explicit and add opt-in amd64 support via
Rosetta-for-Linux translation on Apple Silicon.
- Refactor the driver's arm64 check into selectPlatform: prefer native
linux/arm64, fall back to linux/amd64 via Rosetta when enabled, else reject
with an actionable ErrIncompatibleArch that names what was found and points at
the runtimeRosetta opt-in.
- Pull validates a bootable variant under the policy; Create pins the platform
explicitly when Rosetta is on (--platform linux/{arm64,amd64}[ --rosetta]),
since the runtime defaults to the host arch and will not auto-select amd64.
Rosetta-disabled Create is unchanged (no inspect, no platform pin).
- container.Config.Rosetta + config.runtimeRosetta (default off), threaded from
main.go.
- docs/IMAGES.md documents architecture behavior, the Rosetta opt-in, failure
messages, and multi-arch guidance. Live integration test boots an amd64 image
under Rosetta and asserts uname -m == x86_64.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Close the main pre-beta security gaps and document the model. - Kubelet serving endpoint (logs/exec/portforward/stats) gains mutual TLS: node.servingClientCAFile makes the server RequireAndVerifyClientCert against the API-server client CA, so only the API server can reach it. It now binds to node.internalIP instead of all interfaces when known, and logs a loud warning when left unauthenticated. Config validation requires serving TLS when a client CA is set. - Tighten RBAC to exactly the verbs the VK node/pod/lease controllers invoke (verified against upstream source): drop nodes/leases delete, narrow pods to status writes + delete, and justify each rule inline. Secret read is retained for the upstream informer and called out as a documented limitation. - docs/SECURITY.md documents trust boundaries, the mTLS/RBAC posture, runtime socket locality, conservative secret/env/registry-credential handling (no valueFrom injection, no imagePullSecrets, no credential logging), and an operator checklist. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Provide a reproducible darwin/arm64 release pipeline for macvz-kubelet. - scripts/macos-release.sh: build (version-stamped) -> codesign with the hardened runtime + entitlements -> verify -> package a tarball + SHA256 -> optionally notarize via notarytool (keychain profile or Apple ID/team/ app-password). Ad-hoc signing is the default fallback for local dev. - build/macvz-kubelet.entitlements: empty hardened-runtime entitlements; macvz-kubelet drives the apple/container CLI and does not link Virtualization.framework, so it needs no virtualization entitlement (that lives in apple/container's signed binaries). - Makefile: `make release` (full pipeline) and `make sign` (ad-hoc local). - .github/workflows/release.yml: tag-triggered (v*) signed+notarized release on a macOS runner, importing a Developer ID cert from secrets and publishing artifacts; signing/notarization activate only when secrets are present so forks still build. - docs/RELEASE.md: signing identity + entitlement requirements, packaging, the codesign/notarization steps, local ad-hoc fallback, and install/verification commands. Verified locally: build->sign->verify->package works ad-hoc, and the hardened-runtime signing path produces flags=runtime with a full Apple certificate chain. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prove the runtime, provider, networking, and operational paths work together across 2+ Macs, gated for release. - test/e2e/e2e.sh: env-gated harness covering node registration (Ready, arm64, provider taint, capacity), Pod lifecycle (schedule/Ready/logs/exec/exit-code/ delete), a Service load-balanced across both nodes, and port-forward. It auto-creates/tears down its namespace, captures diagnostics (describes, endpoints, events) on failure, and exits non-zero so it can gate releases. With a single node it runs every single-node phase and reports the cross-node check as SKIP — the documented hardware-limited fallback. - test/e2e/e2e_test.go: `e2e`-tagged, MACVZ_E2E-gated Go wrapper so the suite plugs into `go test` and CI without affecting the default build. - Makefile `e2e` target; .github/workflows/e2e.yml (manual, self-hosted runner) uploading diagnostics on failure. - docs/E2E.md: topology, coverage, run/config, manual fallback, and the P4 acceptance-evidence table. Marks #30 closed in MASTER_TASKS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Review fix
Validation
Closes #25
Closes #26
Closes #27
Closes #28
Closes #29
Closes #30