Kubernetes Exec
Execute commands inside a container in a Kubernetes Cluster, this
type is useful when there’s a necessity to change the state of a running
system. It’s possible to pass any kind of command to a container through
Runops. The command can be run in two modes:
- Script Mode
This is the default mode - the script mode allows controlling which
resource to target when running a script inside a container, it’s useful
when you need more flexibility to execute commands over several
resources (deployments, statefulsets or pods) It must
have the format:
deploy/{deployment_name} {shell_command}
,
where shell_command will be executed inside one of the
pods of deployment_name.- Stdin Mode
The input of the script is passed directly to the container, this
mode is useful when running full fledged scripts
Type:
k8s-exec
Configuration
Name | Required | Description |
KUBE_CONFIG_DATA | yes | A base64 encoded Kubeconfig
file. |
K8S_EXEC_COMMAND | no | The command that will be used to execute the script from stdin. |
K8S_EXEC_RESOURCE | no | The name of the kubernetes resource: POD or TYPE/NAME. Must be used
only when K8S_EXEC_COMMAND is set. |
K8S_EXEC_CONTAINER | no | The name of the container, it will follow the kubectl exec default
behavior if this option isn’t set. |
NAMESPACE | no | The name of the namespace, it will default to the namespace set in
the KUBE_CONFIG_DATA . |
Examples
Script Mode
shellrunops tasks create --target k8s-exec-type --script 'deploy/rails-app rails runner "puts User.first.to_json"'# execute find inside the containerrunops tasks create --target k8s-exec-type --script 'deploy/rails-app find /tmp/ -type f -exec echo '{}' \;'
It’s important to notest that using sub shell calls are not allowed,
hence the example below will not work
shellrunops tasks create -t k8s-exec-type --script 'deploy/myapp ls -l && echo foo'
Some trick examples
plain text# this will work, but not the way you expected, the subshell here is being evaluated in your current bash # thus the command will output the files of your local /tmp/ directory runops tasks create -t k8s-exec-type --script 'deploy/myapp echo "$(ls -l /tmp/)"'
In order to use subshell, use a
/bin/bash -c
callplain textrunops tasks create --target k8s-exec-type --script 'deploy/myapp /bin/bash -c "ls -l && echo FOO"'
Let’s say you want to execute a command to dinamically call a python
script, using kubectl this would be
plain textkubectl exec deploy/myapp -- /bin/bash -c "python3 -c 'import os;print(os.environ)'"
However, with Runops cli things works differently, because of how the
current shell interpret commands, to make this example to work the
double quotes need to be escaped
plain textrunops tasks create -t k8s-exec-type --script "deploy/myapp /bin/bash -c \"python3 -c 'import os;print(os.environ)'\""
The next example things become more cumbersome, because of multiple
quotes to escape
plain text# this example won't work because of your local shell runops tasks create -t k8s-exec --script "deploy/myapp /bin/bash -c \"python3 -c 'print(\"foo\")'\"" # this command needs to be passed down to a script and then executed in order to work properly cat - > /tmp/task.sh <<EOF deploy/myapp /bin/bash -c "python3 -c 'print(\"foo\")'" EOF runops tasks create -t k8s-exec --file /tmp/tasks.sh
Stdin Mode
This mode solves the limitations explained above.
Executing commands directly from stdin is powerful because it allows
creating targets that interact directly with the semantics of any
commands available in the container.
To configure such behavior the
K8S_EXEC_COMMAND
and
K8S_EXEC_RESOURCE
are required.K8S_EXEC_COMMAND=rails runner -
shell# print all environment variables on rubyrunops tasks create -t k8s-exec-rails --script 'pp ENV'
K8S_EXEC_COMMAND=doppler run -- rails runner -
shell# if you use doppler, get the project env variablerunops tasks create -t k8s-exec-rails -s 'print ENV["DOPPLER_PROJECT"]'
K8S_EXEC_COMMAND=python -
shellrunops tasks create -t k8s-exec-python -s 'print("Hello World from Python Container")'
The only requirement is that the command support reading content from
the stdin, otherwise it will fail, in practice this option is analogous
to:
shellecho 'print("Hello World")' | kubectl exec -n <namespace> -i <k8s-exec-resource> -- <k8s-exec-command>