Parsing Docker and Kubernetes JSON output in C#
Posted: (EET/GMT+2)
In my previous posts (here and here), I called docker and kubectl from C# and printed/processed their normal text output.
That works for quick checks, but JSON output is better when the application needs to inspect the result programmatically.
For Docker, you can format each container as JSON:
docker ps --format "{{json .}}"
This returns one JSON object per line.
{"Command":"\"/opt/mssql/bin/perm...\"","CreatedAt":"2023-01-20 09:15:01 +0200 EET","ID":"abc123","Image":"mcr.microsoft.com/mssql/server:2022-latest","Labels":"","LocalVolumes":"0","Mounts":"","Names":"sql-server","Networks":"bridge","Ports":"0.0.0.0:1433->1433/tcp","RunningFor":"2 hours ago","Size":"0B","State":"running","Status":"Up 2 hours"}
A small C# helper can read each line and deserialize it.
using System.Diagnostics;
using System.Text.Json;
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "docker",
Arguments = "ps --format \"{{json .}}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
using Process process = Process.Start(startInfo)!;
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode != 0)
{
Console.WriteLine(error);
return;
}
foreach (string line in output.Split(Environment.NewLine,
StringSplitOptions.RemoveEmptyEntries))
{
DockerContainer? container =
JsonSerializer.Deserialize<DockerContainer>(line);
if (container is not null)
{
Console.WriteLine($"{container.Names}: {container.Status}");
}
}
public class DockerContainer
{
public string? Names { get; set; }
public string? Image { get; set; }
public string? Status { get; set; }
public string? State { get; set; }
}
For Kubernetes, kubectl can return a full JSON document:
kubectl get pods --all-namespaces -o json
That output is easier to parse as one document:
using System.Diagnostics;
using System.Text.Json;
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "kubectl",
Arguments = "get pods --all-namespaces -o json",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
using Process process = Process.Start(startInfo)!;
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode != 0)
{
Console.WriteLine(error);
return;
}
using JsonDocument document = JsonDocument.Parse(output);
JsonElement items = document.RootElement.GetProperty("items");
foreach (JsonElement item in items.EnumerateArray())
{
string name =
item.GetProperty("metadata").GetProperty("name").GetString() ?? "";
string ns =
item.GetProperty("metadata").GetProperty("namespace").GetString() ?? "";
string phase =
item.GetProperty("status").GetProperty("phase").GetString() ?? "";
Console.WriteLine($"{ns}/{name}: {phase}");
}
This prints a compact status list:
default/web-api-7c9fd4d5c8-8xq2m: Running default/worker-6f458bb7d4-r9q2p: Running kube-system/coredns-787d4945fb-h7x28: Running
It's a good idea to prefer JSON when the result is used by code (as we are doing here). The default text output is fine for humans, but it can change in ways that break simple string parsing.
For small internal tools, calling docker and kubectl may be simpler than adding full client libraries. For larger applications, use proper APIs and
libraries instead.
This gives you a useful middle ground: quick C# diagnostics with structured output and no heavy monitoring stack.