Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php K8S Laravel Package

krymosoftware/php-k8s

A PHP package for integrating Kubernetes into your applications, providing convenient access to Kubernetes APIs for querying clusters, managing resources, and automating common cluster operations from PHP code.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require krymo/php-k8s:^3.9

Before anything else, check your PHP version. 3.9.0 drops PHP 8.2 and fixes PHP 8.4 deprecations, so the supported floor is now 8.3. If your Laravel app still runs 8.2 (common on Laravel 9/10 images), composer update will fail — pin ^3.8 until you upgrade PHP.

Start reading at KubernetesCluster (src/KubernetesCluster.php) — it is the single entry point. From there everything funnels into KubernetesClient, and each verb (pods, deployments, jobs, …) is a resource class under src/Kubernetes/. You rarely need to touch the client directly.

Connect to a cluster:

use KrymoSoftware\PhpK8s\KubernetesCluster;

$cluster = KubernetesCluster::fromKubeConfig(
    path: base_path('kubeconfig'),
    context: 'minikube',
);

In-cluster (running inside a pod with a service account) use the service-account constructor, and for CI/remote use the token variant — both accept named arguments as of 3.9.0, so KubernetesCluster::fromKubeConfig(path: ..., context: ...) reads far better than positional args.

First use case: an artisan command or queued job that lists pods in a namespace and reports their age using the newly exposed creation timestamp — this exercises connect → list → inspect metadata, which is 80% of what you'll do daily.

$cluster->namespace('default')
    ->pods()
    ->all()
    ->each(fn ($pod) => $this->line($pod->name.' '.$pod->createdAt()));

Implementation Patterns

Register the cluster as a container singleton. With Laravel support removed in 3.9.0 there is no auto-registered service provider or Kubernetes facade, so wire it yourself in AppServiceProvider::register():

$this->app->singleton(KubernetesCluster::class, fn () => KubernetesCluster::fromKubeConfig(
    path: config('services.kubernetes.kubeconfig'),
    context: config('services.kubernetes.context'),
));

Then inject KubernetesCluster into commands, jobs, and actions. If you run multi-cluster, use a small factory that caches one cluster instance per context name rather than re-parsing the kubeconfig on every call.

Keep cluster calls out of the request path. Every call is a network round-trip with its own TLS handshake cost. Listing pods during a page render is fine for a dashboard; anything that creates, patches, or deletes belongs in a queued job with retries, so a flaky API server doesn't turn into a 500.

Use the creation timestamp for lifecycle logic. createdAt() on a resource is the natural key for:

  • "age" columns and TTL dashboards (now()->diffInMinutes($pod->createdAt()))
  • pruning completed Jobs / failed Pods older than N minutes
  • cache keys and idempotency guards ("did this deployment exist before my apply?")

Parse it as a date — it's an RFC3339 string from the API server, not a Carbon instance.

Deletion is asynchronous — always wait. ->delete() returns as soon as the API server accepts the request. If a subsequent step creates a resource with the same name, poll ->get() until it 404s, or you'll hit AlreadyExists intermittently.

Streaming (exec, attach, follow-logs, watch) is a different execution model. These run through the ReactPHP/pawl stack, are long-lived, and block. Wrap them in a dedicated command, never a web request, and always pass a timeout.

Testing: bind a stub KubernetesCluster in the container and assert against recorded calls, or point the suite at kind/k3d in CI via a KUBECONFIG fixture. Don't mock the resource classes themselves — they're thin and you'll end up testing your mocks.

Gotchas and Tips

"Remove Laravel support" is the headline breaking change. Before upgrading, run composer show krymo/php-k8s and grep your app for the Kubernetes facade, a published config/php-k8s.php, or a service provider registration. If any of those exist, you have two options: stay on ^3.8 until you migrate, or register the singleton yourself as shown above. Do the grep before bumping — the failure mode is a BindingResolutionException at boot, or worse, a silently stale config file left on disk.

Check what actually changed for you. If your app never used the Laravel integration (just KubernetesCluster directly), 3.9.0 is a low-risk upgrade gated only on the PHP version.

PHP 8.2 removal cascades. Your CI matrix, Dockerfile base image, and any platform.php setting in composer.json all need to move together. A config.platform.php pinned to 8.2 will keep the resolver on 3.8.x even after you upgrade the runtime.

The ratchet/pawl bump is easy to miss. It affects exec/attach/streaming paths only — a plain list/create/delete smoke test will pass while the interesting code paths are broken. If you use exec, test it explicitly after upgrading, and watch for React event-loop version conflicts with other packages you've pulled in (broadcasters, websocket clients).

Timestamp quirks. Newly created resources may not have a populated timestamp on the response object you just built locally — re-fetch with ->get() if you need it immediately. Fake API servers and some test harnesses omit the field entirely, so treat it as nullable.

Named parameters apply to KubernetesCluster functions only. Resource builders still take positional arguments; don't assume the whole API got nicer in 3.9.0.

Debugging connection failures in this order: KUBECONFIG / in-cluster service-account token presence → token expiry (in-cluster tokens rotate) → TLS verification (self-signed CAs need to be passed explicitly, not skipped) → RBAC (Forbidden on list looks identical to an empty result if you're swallowing exceptions). Log the full error body; the API server's message is usually precise.

Extension points. For custom resources, extend KubernetesResource, declare the API version and kind, and register it — don't hand-roll raw() requests, because you lose the query/label-selector ergonomics. For anything genuinely unsupported, KubernetesClient exposes the raw request path as an escape hatch.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package