Skip to content

Add a --publish option to container k8s create - #2122

Open
mikluko wants to merge 2 commits into
apple:mainfrom
mikluko:k8s-create-publish
Open

Add a --publish option to container k8s create#2122
mikluko wants to merge 2 commits into
apple:mainfrom
mikluko:k8s-create-publish

Conversation

@mikluko

@mikluko mikluko commented Aug 14, 2026

Copy link
Copy Markdown

Closes #2121.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

container k8s create publishes only the internally allocated API server port; NodePort services are reachable solely via the node's vmnet IP, which is dynamic across recreations. Anything wanting a stable host endpoint (an ingress controller on fixed NodePorts, a local dev domain resolving to loopback) has no supported path, while the runtime's publish machinery already carries the capability. Details in #2121.

This adds a repeatable -p/--publish [host-ip:]host-port:container-port[/protocol] option to k8s create:

  • Specs are parsed by the runtime's existing Parser.publishPorts — no new format or parser.
  • K8sHelper.clusterPort() is split into reservedHostPorts() + clusterPort(excluding:): the API server allocation now excludes user-requested host ports, user specs that collide with another cluster's published host port fail legibly at create time, and the internal API spec stays first so the kubeconfig transform keeps selecting it.
  • User publishes apply in both DNS-domain modes; the API server publish keeps its existing fqdn-conditional behavior.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

make test green (763 tests, 82 suites), including 7 new swift-testing cases for spec parsing/composition in Tests/K8sPluginTests/K8sPublishPortsTests.swift. Verified live on macOS: a cluster created with --publish 8080:30080 --publish 8443:30443 lists 6446->6443,8080->30080,8443->30443 (allocator correctly skipping another cluster's 6445), and traffic through the published host port reaches the NodePort. docs/command-reference.md updated.

Publishes node ports to the host, so NodePort services get a stable host
endpoint instead of the node's vmnet IP, which changes across recreations.
Specs go through the runtime's existing `Parser.publishPorts`, so the format
matches `container run --publish`.

`clusterPort()` becomes `reservedHostPorts()` + `clusterPort(excluding:)`: the
API server allocation skips user-requested host ports, and the internal API
spec stays first so the kubeconfig transform keeps selecting it.

Host port claims are keyed by (port, protocol), the granularity
`[PublishPort].hasOverlaps()` collides on, and carry the container holding
them along with its runtime status. A running holder is a hard error naming
it; a stopped holder is a warning, since nothing is listening on the port yet
that container cannot start again while the cluster owns it. The scan covers
plain containers as well as clusters, so a port held by `container run -p` is
reported at create time rather than as a bind failure at node boot.

The PORTS column renders the host address and non-TCP protocol it previously
dropped, and collapses ranges, so specs differing only in address or protocol
no longer print identically.
@mikluko
mikluko force-pushed the k8s-create-publish branch from 99b1fd2 to 227959f Compare August 18, 2026 21:24
@gigovich

gigovich commented Aug 21, 2026

Copy link
Copy Markdown

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: --publish option for container k8s create

2 participants