How to kill a container using kubernetes API?

529 Views Asked by At

I am trying to kill a container using client-go and e2e framework in Golang but not able to do it successfully. Example of the full implementation can be accessed e2e apart from this I am using kind image as "kindest/node:v1.26.6"

I have tried the following commands but none using the following pieces of code.

args := []string{"kill", "1"}
var stdout, stderr bytes.Buffer
err := cfg.Client().Resources().ExecInPod(ctx, namespace, podName, containerName, args, &stdout, &stderr)
args = []string{"/bin/sh", "-c", "'kill", "1'"}
err = cfg.Client().Resources().ExecInPod(ctx, namespace, podName, containerName, args, &stdout, &stderr)
args = []string{"/bin/sh", "-c", "\"kill 1\""}
err = cfg.Client().Resources().ExecInPod(ctx, namespace, podName, containerName, args, &stdout, &stderr)

But all of them are giving error. Some are giving

exec failed: unable to start container process: exec: "kill": executable file not found in $PATH: unknown"

while some are giving

"command terminated with exit code 127" or "command terminated with exit code 2"

I have also tried the following and it is working but in this case I have a dependency on kubectl which I want to avoid.

cmdString := fmt.Sprintf("/c kubectl exec -it %s -n %s -c %s -- bash -c 'kill 1'", podName, namespace, containerName)
    args := strings.Split(cmdString, " ")
    cmd := exec.Command("powershell", args...)
    err := cmd.Run()
2

There are 2 best solutions below

1
larsks On

Your first attempt looks okay at first glance, although I don't see an ExecInPod method in the client-go package. Because you haven't provided a reproducible example I haven't tried building and running your code.

There's no guarantee that the kill command is available inside a particular container. If you update your question to include details about your deployment manifests -- so we can see what image you're using -- we can provide you with a better answer.


Your second two examples are simply invalid:

1

args = []string{"/bin/sh", "-c", "'kill", "1'"}

Here you're trying to run the command 'kill, which doesn't exist. You need to pass a single string to sh -c, so this would need to look like:

args = []string{"/bin/sh", "-c", "kill 1"}

The argument to -c is the script to run; any additional parameters are provided as arguments to that script (so in this example, the shell would see 1' in $0).

You could avoid the shell altogether and just run:

args = []string{"kill", "1"}

But again, both of these solutions require that the target container have the kill command available.

2

args = []string{"/bin/sh", "-c", "\"kill 1\""}

Here you're trying to run the command "kill 1", which against doesn't exist; if you were to run this from the command line you would see:

$ "kill 1"
bash: kill 1: command not found...

The correct syntax would be as shown in the previous section.

0
Vasilii Angapov On

AFAIK it's generally not possible to kill a container from within a container. That's because PID 1 inside container ignores any signal.

From Docker documentation:

A process running as PID 1 inside a container is treated specially by Linux: it ignores any signal with the default action. As a result, the process will not terminate on SIGINT or SIGTERM unless it is coded to do so.

Instead you should rely on kubectl delete pod functionality.