CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-fabric8--kubernetes-client

Java client for Kubernetes and OpenShift providing access to the full Kubernetes & OpenShift REST APIs via a fluent DSL

Pending
Overview
Eval results
Files

pod-operations.mddocs/

Pod Operations

The Fabric8 Kubernetes Client provides specialized operations for Pods beyond basic CRUD, including log streaming, command execution, port forwarding, and file operations. These advanced capabilities enable comprehensive Pod management and debugging.

PodResource Interface

Specialized interface for Pod-specific operations.

public interface PodResource extends Resource<Pod> {
    // Log operations
    String log();
    String log(PodLogOptions options);
    InputStream logInputStream();
    InputStream logInputStream(PodLogOptions options);
    LogWatch watchLog();
    LogWatch watchLog(PodLogOptions options);
    
    // Execution operations
    ExecWatch exec(String... command);
    ExecWatch exec(ExecOptions options);
    
    // Port forwarding
    LocalPortForward portForward(int port);
    LocalPortForward portForward(int port, int localPort);
    
    // File operations
    Boolean upload(Path pathToUpload);
    Boolean copy(Path source, Path destination);
    
    // Attach operations
    Pod attach();
    ExecWatch attach(AttachOptions options);
}

Log Operations

Basic Log Retrieval

public interface PodResource {
    String log();
    String log(PodLogOptions options);
    InputStream logInputStream();
    InputStream logInputStream(PodLogOptions options);
}

public class PodLogOptions {
    public String getContainer();
    public void setContainer(String container);
    public Boolean getFollow();
    public void setFollow(Boolean follow);
    public Integer getTailLines();
    public void setTailLines(Integer tailLines);
    public String getSinceTime();
    public void setSinceTime(String sinceTime);
    public Integer getSinceSeconds();
    public void setSinceSeconds(Integer sinceSeconds);
    public Boolean getTimestamps();
    public void setTimestamps(Boolean timestamps);
    public Boolean getPrevious();
    public void setPrevious(Boolean previous);
}

Log Watching

public interface LogWatch extends Closeable {
    OutputStream getOutput();
    void close();
}

Execution Operations

ExecWatch Interface

Interface for executing commands in Pod containers.

public interface ExecWatch extends Closeable {
    OutputStream getInput();
    InputStream getOutput();
    InputStream getError();
    void resize(int cols, int rows);
    void close();
}

public class ExecOptions {
    public String getContainer();
    public void setContainer(String container);
    public String[] getCommand();
    public void setCommand(String[] command);
    public Boolean getStdin();
    public void setStdin(Boolean stdin);
    public Boolean getStdout();
    public void setStdout(Boolean stdout);
    public Boolean getStderr();
    public void setStderr(Boolean stderr);
    public Boolean getTty();
    public void setTty(Boolean tty);
}

Port Forwarding

LocalPortForward Interface

Interface for managing port forwarding sessions.

public interface LocalPortForward extends Closeable {
    int getLocalPort();
    boolean isAlive();
    void close();
}

Usage Examples

Reading Pod Logs

// Get logs from default container
String logs = client.pods().withName("my-pod").log();
System.out.println("Pod logs:\n" + logs);

// Get logs from specific container
String containerLogs = client.pods().withName("my-pod").log(new PodLogOptionsBuilder()
    .withContainer("app-container")
    .withTailLines(100)
    .withTimestamps(true)
    .build());

// Get logs since specific time
String recentLogs = client.pods().withName("my-pod").log(new PodLogOptionsBuilder()
    .withSinceSeconds(3600) // Last hour
    .withFollow(false)
    .build());

// Get previous container logs (useful after restarts)
String previousLogs = client.pods().withName("crashed-pod").log(new PodLogOptionsBuilder()
    .withPrevious(true)
    .build());

Streaming Logs

// Stream logs in real-time
LogWatch logWatch = client.pods().withName("my-pod").watchLog(new PodLogOptionsBuilder()
    .withFollow(true)
    .withTailLines(10)
    .build());

// Read streaming logs
try (BufferedReader reader = new BufferedReader(new InputStreamReader(logWatch.getOutput()))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println("Log: " + line);
        
        // Break on some condition
        if (line.contains("Application started")) {
            break;
        }
    }
} finally {
    logWatch.close();
}

// Stream logs with InputStream
try (InputStream logStream = client.pods().withName("my-pod").logInputStream(new PodLogOptionsBuilder()
    .withFollow(true)
    .withContainer("web-server")
    .build())) {
    
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = logStream.read(buffer)) != -1) {
        String logChunk = new String(buffer, 0, bytesRead);
        System.out.print(logChunk);
    }
}

Executing Commands

// Execute simple command
ExecWatch execWatch = client.pods().withName("my-pod").exec("ls", "-la", "/app");

// Read command output
try (BufferedReader reader = new BufferedReader(new InputStreamReader(execWatch.getOutput()))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println("Output: " + line);
    }
}

// Read any errors
try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(execWatch.getError()))) {
    String line;
    while ((line = errorReader.readLine()) != null) {
        System.err.println("Error: " + line);
    }
}

execWatch.close();

// Execute interactive command with input
ExecWatch interactiveExec = client.pods().withName("my-pod").exec("sh");

// Send commands to the shell
try (PrintWriter writer = new PrintWriter(interactiveExec.getInput())) {
    writer.println("echo 'Hello from pod'");
    writer.println("pwd");
    writer.println("exit");
    writer.flush();
}

// Read output
try (BufferedReader reader = new BufferedReader(new InputStreamReader(interactiveExec.getOutput()))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println("Shell output: " + line);
    }
}

interactiveExec.close();

Advanced Execution with Options

// Execute in specific container with TTY
ExecOptions execOptions = new ExecOptionsBuilder()
    .withContainer("sidecar")
    .withCommand("bash", "-c", "cat /proc/meminfo | head -5")
    .withStdin(false)
    .withStdout(true)
    .withStderr(true)
    .withTty(false)
    .build();

ExecWatch execWatch = client.pods().withName("my-pod").exec(execOptions);

// Process output and errors
CompletableFuture<String> outputFuture = CompletableFuture.supplyAsync(() -> {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(execWatch.getOutput()))) {
        return reader.lines().collect(Collectors.joining("\n"));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
});

CompletableFuture<String> errorFuture = CompletableFuture.supplyAsync(() -> {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(execWatch.getError()))) {
        return reader.lines().collect(Collectors.joining("\n"));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
});

try {
    String output = outputFuture.get(30, TimeUnit.SECONDS);
    String errors = errorFuture.get(30, TimeUnit.SECONDS);
    
    System.out.println("Command output:\n" + output);
    if (!errors.isEmpty()) {
        System.err.println("Command errors:\n" + errors);
    }
} finally {
    execWatch.close();
}

Port Forwarding

// Forward pod port to local port
LocalPortForward portForward = client.pods().withName("web-pod").portForward(8080);

try {
    System.out.println("Port forwarding active on localhost:" + portForward.getLocalPort());
    System.out.println("Access the service at: http://localhost:" + portForward.getLocalPort());
    
    // Keep port forward alive
    while (portForward.isAlive()) {
        Thread.sleep(1000);
    }
} finally {
    portForward.close();
}

// Forward to specific local port
LocalPortForward specificPortForward = client.pods().withName("database-pod")
    .portForward(5432, 15432); // Forward pod:5432 to localhost:15432

System.out.println("Database accessible at localhost:15432");

// Use in try-with-resources
try (LocalPortForward pf = client.pods().withName("api-pod").portForward(3000)) {
    // Make HTTP requests to localhost:pf.getLocalPort()
    // Port forward automatically closed when leaving try block
    
    // Example HTTP request (requires HTTP client library)
    // HttpClient httpClient = HttpClient.newHttpClient();
    // HttpRequest request = HttpRequest.newBuilder()
    //     .uri(URI.create("http://localhost:" + pf.getLocalPort() + "/health"))
    //     .build();
    // HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}

File Operations

// Upload file to pod
Path localFile = Paths.get("/local/path/config.yaml");
Boolean uploadSuccess = client.pods().withName("my-pod").upload(localFile);

if (uploadSuccess) {
    System.out.println("File uploaded successfully");
} else {
    System.out.println("File upload failed");
}

// Copy files between local and pod
Path source = Paths.get("/local/source/data.txt");
Path destination = Paths.get("/pod/destination/data.txt");

Boolean copySuccess = client.pods().withName("my-pod").copy(source, destination);

if (copySuccess) {
    System.out.println("File copied successfully");
} else {
    System.out.println("File copy failed");
}

// Copy directory
Path sourceDir = Paths.get("/local/config/");
Path destDir = Paths.get("/pod/app/config/");

Boolean dirCopySuccess = client.pods().withName("my-pod").copy(sourceDir, destDir);

Attach Operations

// Attach to pod (similar to kubectl attach)
Pod attachedPod = client.pods().withName("interactive-pod").attach();

// Attach with options
AttachOptions attachOptions = new AttachOptionsBuilder()
    .withContainer("main")
    .withStdin(true)
    .withStdout(true)
    .withStderr(true)
    .withTty(true)
    .build();

ExecWatch attachWatch = client.pods().withName("interactive-pod").attach(attachOptions);

// Send input to attached process
try (PrintWriter writer = new PrintWriter(attachWatch.getInput())) {
    writer.println("Hello from attached session");
}

// Read output
try (BufferedReader reader = new BufferedReader(new InputStreamReader(attachWatch.getOutput()))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println("Attached output: " + line);
    }
}

attachWatch.close();

Multi-Container Pod Operations

// Get pod with multiple containers
Pod multiContainerPod = client.pods().withName("multi-container-pod").get();

if (multiContainerPod != null) {
    List<Container> containers = multiContainerPod.getSpec().getContainers();
    
    for (Container container : containers) {
        String containerName = container.getName();
        System.out.println("Processing container: " + containerName);
        
        // Get logs from each container
        String containerLogs = client.pods().withName("multi-container-pod")
            .log(new PodLogOptionsBuilder()
                .withContainer(containerName)
                .withTailLines(50)
                .build());
        
        System.out.println("Logs from " + containerName + ":\n" + containerLogs);
        
        // Execute command in each container
        ExecWatch exec = client.pods().withName("multi-container-pod")
            .exec(new ExecOptionsBuilder()
                .withContainer(containerName)
                .withCommand("ps", "aux")
                .build());
        
        // Process exec output
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getOutput()))) {
            System.out.println("Processes in " + containerName + ":");
            reader.lines().forEach(line -> System.out.println("  " + line));
        } finally {
            exec.close();
        }
    }
}

Error Handling

try {
    // Try to get logs from a pod that might not exist
    String logs = client.pods().withName("non-existent-pod").log();
} catch (KubernetesClientException e) {
    if (e.getCode() == 404) {
        System.out.println("Pod not found");
    } else {
        System.out.println("Error getting logs: " + e.getMessage());
    }
}

try {
    // Try to execute command with timeout
    ExecWatch exec = client.pods().withName("slow-pod").exec("sleep", "300");
    
    // Set up timeout
    CompletableFuture<Void> execFuture = CompletableFuture.runAsync(() -> {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getOutput()))) {
            reader.lines().forEach(System.out::println);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    });
    
    try {
        execFuture.get(10, TimeUnit.SECONDS); // 10 second timeout
    } catch (TimeoutException e) {
        System.out.println("Command execution timed out");
        exec.close(); // Force close
    }
    
} catch (KubernetesClientException e) {
    System.out.println("Execution failed: " + e.getMessage());
}

// Handle port forwarding errors
try {
    LocalPortForward pf = client.pods().withName("my-pod").portForward(8080);
    
    if (!pf.isAlive()) {
        System.out.println("Port forwarding failed to start");
    }
    
    // Monitor port forward health
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            if (!pf.isAlive()) {
                System.out.println("Port forwarding died, cleaning up");
                timer.cancel();
            }
        }
    }, 0, 5000); // Check every 5 seconds
    
} catch (KubernetesClientException e) {
    System.out.println("Port forwarding failed: " + e.getMessage());
}

Install with Tessl CLI

npx tessl i tessl/maven-io-fabric8--kubernetes-client

docs

api-groups.md

client-configuration.md

core-resources.md

custom-resources.md

exception-handling.md

index.md

pod-operations.md

utilities.md

watch-informers.md

tile.json