Skip to content

CRUD Operations ​

CRUD operations (Create, Read, Update, Delete) are available once you have configured authentication to your Kubernetes cluster.

Retrieving All Resources ​

Get all resources of a specific type from a namespace:

php
// Using the resource method
$namespaces = $cluster->namespace()->all();

// Using the convenience method (recommended)
$namespaces = $cluster->getAllNamespaces();

// For namespaced resources, specify the namespace
$stagingServices = $cluster->getAllServices('staging');
$defaultPods = $cluster->getAllPods('default');

Result Type

The result is an RenokiCo\PhpK8s\ResourcesList instance, which extends \Illuminate\Support\Collection, giving you access to all Laravel collection methods.

Collection Methods ​

Since results are collections, you can use powerful filtering and transformation methods:

php
$pods = $cluster->getAllPods('production');

// Filter running pods
$runningPods = $pods->filter(fn($pod) =>
    $pod->getPodPhase() === \RenokiCo\PhpK8s\Enums\PodPhase::RUNNING
);

// Get pod names
$podNames = $pods->map(fn($pod) => $pod->getName());

// Count pods by phase
$podsByPhase = $pods->groupBy(fn($pod) => $pod->getPodPhase()->value);

Retrieving Resources from All Namespaces ​

Get resources across all namespaces:

php
// Using the resource method
$allPods = $cluster->pod()->allNamespaces();

// Using the convenience method (recommended)
$allPods = $cluster->getAllPodsFromAllNamespaces();
$allServices = $cluster->getAllServicesFromAllNamespaces();

Retrieving a Specific Resource ​

Get a single resource by name:

php
// Method 1: Using whereNamespace and whereName
$service = $cluster->service()
    ->whereNamespace('staging')
    ->whereName('nginx')
    ->get();

// Method 2: Using getByName (shorter)
$service = $cluster->service()
    ->whereNamespace('staging')
    ->getByName('nginx');

// Method 3: Using the convenience method (recommended)
$service = $cluster->getServiceByName('nginx', 'staging');

// Default namespace example
$pod = $cluster->getPodByName('my-pod'); // Uses 'default' namespace

Default Namespace

By default, the namespace is default and can be omitted from function calls.

Creating Resources ​

Create a new resource in the cluster:

php
// Create a namespace
$ns = $cluster->namespace()
    ->setName('staging')
    ->setLabels(['environment' => 'staging'])
    ->create();

// Check if resource is synced
$ns->isSynced(); // true

// Create a ConfigMap
$cm = K8s::configMap($cluster)
    ->setName('app-config')
    ->setNamespace('production')
    ->setData([
        'APP_NAME' => 'MyApp',
        'APP_ENV' => 'production',
    ])
    ->create();

// Create a Pod
$pod = K8s::pod($cluster)
    ->setName('nginx-pod')
    ->setNamespace('default')
    ->setContainers([
        K8s::container()
            ->setName('nginx')
            ->setImage('nginx:latest')
            ->setPorts([K8s::containerPort()->setContainerPort(80)])
    ])
    ->create();

Checking Resource State ​

After creating a resource:

php
$pod->isSynced(); // true - resource has been synced with cluster
$pod->exists(); // true - resource exists in cluster
$pod->getName(); // Returns the pod name
$pod->getNamespace(); // Returns the namespace

Updating Resources ​

Update an existing resource using the REPLACE method:

php
// Get the resource
$cm = $cluster->getConfigmapByName('env', 'default');

// Modify it
$cm->addData('API_KEY', '123')
    ->addData('API_SECRET', 'xyz')
    ->update();

// Update a deployment's replica count
$deployment = $cluster->getDeploymentByName('my-app');
$deployment->setReplicas(5)->update();

// Update pod labels
$pod = $cluster->getPodByName('my-pod');
$pod->setLabels([
    'app' => 'myapp',
    'version' => 'v2.0',
    'environment' => 'production'
])->update();

Update Method

The update() method uses Kubernetes REPLACE operation, which replaces the entire resource. For partial updates, use JSON Patch instead.

Deleting Resources ​

Delete a resource from the cluster:

php
// Simple delete
$cm = $cluster->getConfigmapByName('settings');

if ($cm->delete()) {
    echo 'ConfigMap deleted! 🎉';
}

// Delete a pod
$pod = $cluster->getPodByName('old-pod');
$pod->delete();

Delete Options ​

The delete() method accepts optional parameters for fine-grained control:

php
public function delete(
    array $query = ['pretty' => 1],
    ?int $gracePeriod = null,
    string $propagationPolicy = 'Foreground'
): bool

Example with options:

php
// Delete with 30-second grace period
$pod->delete(
    query: ['pretty' => 1],
    gracePeriod: 30,
    propagationPolicy: 'Foreground'
);

Propagation Policies:

  • Foreground - Waits for dependents to be deleted first
  • Background - Deletes immediately, dependents deleted in background
  • Orphan - Leaves dependents orphaned

Creating or Updating Resources ​

Create a resource if it doesn't exist, or update it if it does:

php
$cluster->configmap()
    ->setName('app-config')
    ->setNamespace('default')
    ->setData(['RAND' => mt_rand(0, 999)])
    ->createOrUpdate();

This is useful for idempotent operations:

php
// Will create on first run, update on subsequent runs
K8s::secret($cluster)
    ->setName('api-credentials')
    ->setNamespace('production')
    ->setData('api-key', base64_encode('secret-value'))
    ->createOrUpdate();

Batch Operations ​

Process multiple resources efficiently:

php
// Create multiple namespaces
$namespaces = ['dev', 'staging', 'production'];

foreach ($namespaces as $ns) {
    K8s::namespace($cluster)
        ->setName($ns)
        ->setLabels(['managed-by' => 'php-k8s'])
        ->createOrUpdate();
}

// Delete old pods
$pods = $cluster->getAllPods('default');

$pods
    ->filter(fn($pod) => $pod->getAge() > 86400) // Older than 1 day
    ->each(fn($pod) => $pod->delete());

Error Handling ​

Always wrap CRUD operations in try-catch blocks:

php
use RenokiCo\PhpK8s\Exceptions\KubernetesAPIException;

try {
    $pod = $cluster->getPodByName('my-pod', 'production');
    $pod->setReplicas(3)->update();
} catch (KubernetesAPIException $e) {
    echo "API Error: " . $e->getMessage();
    echo "Status Code: " . $e->getCode();
    echo "Payload: " . json_encode($e->getPayload());
}

Best Practices ​

  1. Use convenience methods - getAllPods() is clearer than pod()->all()
  2. Always specify namespace in production - Don't rely on defaults
  3. Use createOrUpdate for idempotency - Safe for repeated operations
  4. Check existence before deleting - Avoid unnecessary API calls
  5. Handle errors gracefully - Always wrap in try-catch blocks
  6. Use collection methods - Filter and transform results efficiently

Examples ​

Complete CRUD Workflow ​

php
use RenokiCo\PhpK8s\K8s;
use RenokiCo\PhpK8s\KubernetesCluster;

$cluster = new KubernetesCluster('http://127.0.0.1:8080');

// CREATE
$cm = K8s::configMap($cluster)
    ->setName('app-settings')
    ->setNamespace('default')
    ->setData(['DEBUG' => 'true'])
    ->create();

echo "Created: {$cm->getName()}\n";

// READ
$cm = $cluster->getConfigmapByName('app-settings');
echo "Data: " . json_encode($cm->getData()) . "\n";

// UPDATE
$cm->setData(['DEBUG' => 'false', 'LOG_LEVEL' => 'info'])->update();
echo "Updated\n";

// DELETE
$cm->delete();
echo "Deleted\n";

Next Steps ​


Originally from renoki-co/php-k8s documentation, adapted for cuppett/php-k8s fork

Released under the Apache-2.0 License. Originally from renoki-co/php-k8s.