In Kubernetes, we have the concept of pods as a top-level tier. Further down, a pod can have one or multiple containers running within it. A container usually has commands passed to it. These are part of a YAML configuration file, which can dictate the behavior of the container as a whole. As a result, the container runs the instructions and commands at launch time within a pod.
In this tutorial, we’ll learn about passing multiple commands to a container running under Kubernetes.
2. Single Command Using a YAML Array
To begin with, we can assign a collection of strings to the command field:
$ cat /home/muasif80/k8s/test-job.yml apiVersion: batch/v1 kind: Job metadata: name: my-job spec: template: spec: containers: - name: my-container image: ubuntu:latest command: ["echo", "Hello, Kubernetes!"] restartPolicy: Never
In other words, we passing a command as an element of a collection within an array of strings. In this case, we’re passing the echo shell command and the string Hello, Kubernetes! as an argument of echo.
This results in the string Hello, Kubernetes! being printed to the terminal when the container is launched within the Kubernetes pod.
To test out the above, we can run kubectl apply in a Kubernetes environment with test-job.yaml as the argument to -f:
$ kubectl apply -f test-job.yaml job.batch/my-job created
After creating the pod, we can list all pods using the get subcommand:
$ kubectl get pods NAME READY STATUS RESTARTS AGE my-job-677zv 0/1 Completed 0 38s
Further, to check the logs, we can employ the logs subcommand:
$ kubectl logs -f pods/my-job Hello, Kubernetes!
At this point, we see the expected string in the logs.
3. Multiple Commands Using a Shell Executable
We can also provide multiple commands for the initial container launch. However, to do this, we have to expand on our previous example.
First, we’ll create a new YAML file that uses sh in the command field. Further, the -c argument invokes the shell into a mode that considers the list of arguments after -c as separate commands to run:
cat /home/muasif80/k8s/test-job2.yml apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: ubuntu:latest command: ["sh", "-c"] args: - | echo "Command 1" echo "Command 2" echo "Command 3"
Here, we also employ the args field, where the pipe | operator tells the Kubernetes interpreter to take the following lines as individual arguments to the command in the command field. Thus, we add several commands to run. Of course, we can use other shells with the same effect, as most have a similar switch.
After storing the pod configuration in test-job2.yml, we run it:
$ kubectl apply -f test-job2.yml pod/my-pod created $ kubectl logs -f pod/my-pod Command 1 Command 2 Command 3
As expected, each echo command runs and produces its output, thereby invoking multiple commands at launch.
4. Multiple Commands Using a Script
A shell script consists of multiple commands as a bundle. Since a collection of commands is exactly what we’re after, this approach is systematic and offers several advantages over other methods.
4.1. Benefits of Multiple Commands as Script
Overall, passing multiple commands as a script file to a pod offers many benefits:
- flexibility: write complex scripts separately and without syntax problems
- maintainability: modify and maintain a single script
- reusability: keep the script handy for future use
- code organization: put everything in one file
In short, using scripts enables us to manage and execute complex commands or logic within the containerized environment more efficiently while keeping our codebase clean and maintainable.
4.2. Code Example
We begin with our code in the test-job3.yml file:
$ cat /home/muasif80/k8s/test-job3.yml apiVersion: v1 kind: Pod metadata: name: baeldung-test-pod spec: containers: - name: baeldung-test-container image: ubuntu:latest command: ["/bin/bash", "-c"] args: ["/bin/baeldung-test-script.sh"] volumeMounts: - name: baeldung-script-volume mountPath: /bin/ readOnly: true subPath: baeldung-test-script.sh volumes: - name: baeldung-script-volume configMap: defaultMode: 0700 name: baeldung-script-configmap --- apiVersion: v1 kind: ConfigMap metadata: name: baeldung-script-configmap data: baeldung-test-script.sh: | #!/bin/bash echo "Command 1" echo "Command 2" echo "Command 3"
Now, let’s break down this code:
- ConfigMap baeldung-script-configmap adds the contents of the script file baeldung-test-script.sh inline
- the pod specification includes a container baeldung-test-container running the ubuntu-latest image
- the command field specifies [“/bin/bash”, “-c”] as the shell we use to run the script
- the args field is set to [“/bin/baeldung-test-script.sh”] to run the script file within the container
- we mount a volume baeldung-script-volume at the path /bin/baeldung-test-script.sh inside the container
In this case, we just modify baeldung-test-script.sh in ConfigMap according to our needs. Finally, when the container starts within the pod, it executes the script file baeldung-test-script.sh in the shell. Again, we see the output in the logs.
Let’s run our script and verify this output:
$ kubectl apply -f .\test-job3.yml pod/baeldung-test-pod created configmap/baeldung-script-configmap created $ kubectl logs -f pod/baeldung-test-pod Command 1 Commnad 2 Command 3
Again, we see the same three echo commands running, this time from within the baeldung-test-script.sh script.
In this article, we learned that Kubernetes provides various ways to run and manage pods.
Although we can run a simple command when the pod starts, we also have ways to run multiple commands as well. Further, since pods are the smallest deployable units in the Kubernetes ecosystem, passing multiple commands is available to all of these constructs.