I want to write a utility that would spawn kubectl port-forward
subprocesses and cancel and restart later. I'm currently on windows but would like this to work cross-platform.
Problem
kubectl port-forward service/<service> <port>
creates another kubectl
subprocess which binds a port:
❯ : ps | where name == "kubectl.exe"
╭───┬───────┬─────────────┬──────┬─────────┬─────────╮
│ # │ pid │ name │ cpu │ mem │ virtual │
├───┼───────┼─────────────┼──────┼─────────┼─────────┤
│ 1 │ 34712 │ kubectl.exe │ 0.00 │ 17.2 MB │ 16.1 MB │ # parent
│ 2 │ 52016 │ kubectl.exe │ 0.00 │ 33.3 MB │ 28.0 MB │ # child (binding port 5434)
╰───┴───────┴─────────────┴──────┴─────────┴─────────╯
❯ : netstat -ano | findstr :5434
TCP 127.0.0.1:5434 0.0.0.0:0 LISTENING 52016
TCP [::1]:5434 [::]:0 LISTENING 52016
When pressing Ctrl+C
in a terminal, both parent and child kubectl
programs exit, freeing the port.
When I run the same program with std::process::Command
the kill
function only kills the parent process, the child kubectl
keeps the port open. The same when I kill the parent manually:
❯ : taskkill /PID 34712 /F
SUCCESS: The process with PID 34712 has been terminated.
❯ : ps | where name == "kubectl.exe"
╭───┬───────┬─────────────┬──────┬─────────┬─────────╮
│ # │ pid │ name │ cpu │ mem │ virtual │
├───┼───────┼─────────────┼──────┼─────────┼─────────┤
│ 1 │ 52016 │ kubectl.exe │ 0.00 │ 35.0 MB │ 30.3 MB │
╰───┴───────┴─────────────┴──────┴─────────┴─────────╯
❯ : netstat -ano | findstr :5434
TCP 127.0.0.1:5434 0.0.0.0:0 LISTENING 52016
TCP [::1]:5434 [::]:0 LISTENING 52016
Interestingly, when I exit the rust program the child process is killed too, so the OS does have the capability to clean up orphaned "grandchildren" processes.
Remark
At least on windows you can query child processes:
Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq 34712 } | Select-Object ProcessId, Name
ProcessId Name
--------- ----
52016 kubectl.exe
On Linux you should be able to run ps --ppid <parent_pid>
(haven't tested yet).
However I would prefer to rely on the OS to clean up "zombie" child processes if possible.
Shells are somehow able to do this and I don't think that all of them do this kind of process querying directly.
Question
I would like to know if there is a standard approach for this. This is a problem that every shell has had to solve but I am not able to find relevant info.