kubectl: execute command in all containers of multiple multi-container pods

1/29/2022

I have the following pods,

root@sea:scripts# kubectl get pods -l app=mubu7 -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
mubu71   2/2     Running   0          51m   10.244.1.215   spring   <none>           <none>
mubu72   2/2     Running   0          51m   10.244.2.17    island   <none>           <none>

and each one has 2 containers:

root@sea:scripts# kubectl get pods mubu71 -o jsonpath='{.spec.containers[*].name}' | \
> tr " " "\n" | uniq
mubu711
mubu712
root@sea:scripts# kubectl get pods mubu72 -o jsonpath='{.spec.containers[*].name}' | \
> tr " " "\n" | uniq
mubu721
mubu722

I want to pass a command to both pods and all their (4) containers, but the best I can come up with is

kubectl get pods \
-l app=mubu7 \
-o jsonpath='{.items[*].metadata.name}' | \
tr " " "\n" | uniq | \
xargs -I{} kubectl exec {} -- bash -c \
"service ssh start"

which outputs

Defaulted container "mubu711" out of: mubu711, mubu712
 * Starting OpenBSD Secure Shell server sshd
   ...done.
Defaulted container "mubu721" out of: mubu721, mubu722
 * Starting OpenBSD Secure Shell server sshd
   ...done.

How can I modify the above code to run the command in all pod-containers and not just the first one or is there a preferable alternative approach?

Any help will be much appreciated.

-- Alexander Sofianos
bash
exec
kubectl
kubernetes

2 Answers

1/29/2022

You can try maybe tmux-exec? There is an explanation here.

For Linux users: Download the latest .tar.gz from the Github Release.

Unzip the .tar.gz and move the bin/kubectl-tmux_exec to one of your bin directory, /usr/local/bin for example.

Run kubectl tmux-exec --help .

-- Shalkds Sdlkfdm
Source: StackOverflow

1/29/2022

Following code would iterate over all the pods with the label app=mubu7. Later it would grab their pod name and all the container's name. The list of container names is converted into an array and iterated for each pod. So it does not matter how many containers are in the pod(Eg:1,2,3..etc) this code would work.

#JSON-path expression to extract the pod name and the list of containers
#{range .items[*]}{.metadata.name} {.spec.containers[*].name}{"\n"} {end}


#note that the pod name is stored in 1st variable(pod)
# container(s) name is stored in 2nd variable(containers)
kubectl get pods -l app=mubu7 -o jsonpath='{range .items[*]}{.metadata.name} {.spec.containers[*].name}{"\n"} {end}' |while read -r pod containers; do
     # 2nd variable consist of space seprated container lists, converting it to array
     array=($containers);
     #inner loop to iterate over containers for each pod(outer loop)
     for container in "${array[@]}";do
         kubectl exec -i ${pod} -c "$container" </dev/null -- service ssh start
     done
done
-- P....
Source: StackOverflow