Is this a FEATURE REQUEST
/kind feature
Description
Podman pod has no exec command. It would be handy to have a podman pod exec -it my-pod command to be able to access an interactive shell session in a pod.
Furthermore, the kubctl command has a exec sub command.
The exec command is handy to get a shell in a pod. This is useful for debugging and developing pods.
My initial impression would be to use podman exec on the pod's infra container, but that has a major problem - the infra container has nothing except a pause binary by default, so we have no shell, no tools, etc.
We could launch a sidecar container in the pod with an image including common tools (busybox might be sufficient) and give a shell into that.
Is the shell within the pod, actually in the primary (first) container?
I don't think kubernetes pod's have a shell, so it must be launched in the first container.
Hm, it seems k8s just shells into a container. If the pod has two containers, you can specify which. I'm not sure how it's decided which container is exec'd into if there are multiple but none specified, but following k8s logic could be done here.
Edit: that logic is it chooses the first container in the pod: https://www.mankier.com/1/kubectl-exec which for us would mean the second (first non-infra)
The sidecar idea is a neat one. Should it then be cleaned up after the session?
Dibs
If we go with a sidecar, I think it'd basically act like a container with --rm set - remove on termination.
Things to think about: Do we spawn a separate sidecar per exec session? I'd lean towards yes - it's more complicated, but it lets us use normal container attach instead of exec, which simplifies things quite a bit, and each exec session gets to be actually independent - no taking out all of them if the container goes down.
I'm thinking start following kubectl exec's lead, then maybe add a sidecar as an option as a future. It could look something like
podman pod exec -l --image=image-to-run /bin/bash as opposed to --container=container-that-exists
SGTM
@Jeeppler can you please take a minute and write a little more of a justification on why you need this? i think in general, we all understand but it would be helpful to write up a good use case so we have something to code against?
also, given we can add a container to a pod, why couldn't a user just do this manually?
As I mentioned in the original feature request:
The exec command is handy to get a shell in a pod. This is useful for debugging and developing pods.
To develop containers, I start with a stock image from Ubuntu, Debian, Fedora, Alpine etc. Then I add a simple shell script as the first program. The shell script looks like this:
run.sh
#!/usr/bin/env bash
echo "Container is running"
while true
do
sleep 120
echo "CTRL + C to stop"
done
the corresponding initial Dockerfile would look like this:
Dockerfile
FROM debian:stretch
# the lines to be added
COPY run.sh /run.sh
RUN chmod +x /run.sh
CMD ["/run.sh"]
I then figure out what I need to add to the Dockerfile. At the end I have a functioning container with only the needed dependencies for my project.
In many cases I do not know all the dependencies up-front, therefore I shell into the container and work with the package management tool, until I have the dependencies I really need and want.
Docker allows me to shell in the container (e. g. podman exec -it mypod bash) and add those dependencies. This makes the development process fast. Especially, since I am able to search for the package name in the container itself. Once, I know what I need and want, I add the packages to the container. Here is an example for Guile, an interpreted scripting language:
FROM debian:stretch
RUN apt-get update && apt-get dist-upgrade --yes
RUN apt-get install --yes \
guile-2.0
RUN useradd developer
RUN mkdir -p /usr/src/code
RUN chown -R developer /usr/src/code
WORKDIR /usr/src/code
ADD run.sh /
RUN chmod +x /run.sh
USER developer
CMD ["/run.sh"]
While developing, I work on the files outside the container mounting the source code using docker-compose:
version: '2'
services:
container:
build: .
container_name: guile
volumes:
- ./code:/usr/src/code
_Note_: Not sure how you can achieve the volume mount with podman.
However, you can also simply restart the container, copy the files in the container and run your application. Let us say you have the following Guile (Scheme) script:
hello.scm
#!/usr/bin/env guile
!#
(display "Hello, world!")
(newline)
In case podman has an interactive shell command you could shell into the container and execute the script in the container.
host $ podman exec -it guile bash
container $ $ guile --no-auto-compile hello.scm
Hello, world!
I demonstrated this with a scripting language, but you the same approach works for compiled languages as well. Compiled languages like C, Rust, Go etc.
To summarize this scenario. The podman exec -it <mypod> <shell> would allow one to develop container interactively and therefore more rapidly. While later adding the necessary commands to build the container into the Dockerfile.
Furthermore, it is possible to run and/or compile applications inside the container using an interactive shell. This allows developers to develop and run their applications even before committing code changes to a the git, svn etc. repositories.
In addition, a developer can add tests to the code and run the tests inside the container by getting an interactive shell through podman.
As demonstrated the podman exec -it <mypod> <shell> would have many benefits for developers.
Let us assume something went wrong and your container crashes quite often. However, you are unable to pinpoint the issue for the crash.
Let us further assume you have a web server running and the web server + your application crashes. That means, everytime your application crashes the entire pod crashes and all the relevant information to pinpoint the problem are gone.
To pinpoint the issue you can change the entrypoint from your webserver start command to a simple bash loop. A bash loop like this:
run.sh
#!/usr/bin/env bash
echo "Container is running"
while true
do
sleep 120
echo "CTRL + C to stop"
done
An alternative approach would be to use a simple init system like s6 overlay.
Eitherway, once you have s6 overlay or the bash loop running, you can login into the container using podman exec -it <mypod> <shell>. Start your web server + application manually, wait until it crashes and inspect log files and other relevant information.
@baude can you explain your sentence below?
also, given we can add a container to a pod, why couldn't a user just do this manually?
Maybe the text below answers your question:
In my post above I assumed a pod with only one container. In a setup with multiple pods I still want to access directly a specific container. kubectl exec has a option -c to access a specific container. If the option -c is omitted, kubectl exec will choose the first container in the pod. That behaviour makes sense.
I want to have direct access to the container both for debugging and development. I do not want to have a sidecar container in the pod and to access my target container. I really want to have direct access to the container I either develop or debug. Extra constructs like sidecar container make the development and debugging more difficult.
@Jeeppler you already can achieve what you're talking about by either adding a container to the pod (podman run --pod PODNAME -it sh) or exec'ing in a container in a pod (podman exec -ti CONTAINERINPODNAME sh). A dedicated command (podman pod exec...) would be syntatic sugar for one of those options, so i guess a question is why is the sugar needed, besides kubectl conformance (which we don't really shoot for)
@Jeeppler @haircommander basically explains what I was asking.
This issue had no activity for 30 days. In the absence of activity or the "do-not-close" label, the issue will be automatically closed within 7 days.