CKAD When to use command vs command + arguments?

I have been doing the Kode Kloud CKAD mock exam series and I have failed a number of questions with the only difference being that I use something like:

command: ["sh"] 
args: ["-c", "echo \"Hi \" > a_file.txt"]

Instead of:

command: ["sh", "-c", "echo \"Hi \" > a_file.txt"] 

The questions don’t specify anything specifically about commands or args, just that the container should output something.

This has left me wondering:

How do I know to use a command + args vs just command on the actual CKAD?

I also got a question wrong because I used:

command: ["sh", "-c", "echo \"Hi \" > a_file.txt"] 

And the answer had:

command: ["/bin/sh", "-c", "echo \"Hi \" > a_file.txt"] 

Will the actual CKAD use the log output from the container for verification or do I need to know when to specify sh vs /bin/sh?

I avoid using /bin/sh because sometimes that symlink is missing inside images.

There will be no container log from that command - assuming it works correctly, since the test is being put to a file, not just printed. Only stuff that is “just printed” goes to the container’s log.

The marking script should be checking that a_file.txt has been created inside the container and that this file contains the word Hi

This also implies that it does not matter if you use /bin/sh or just sh. If the sh executable was not found, then there would be a message in the container log, complaining that it can’t execute sh

1 Like

Hi @Alistair_KodeKloud I’ll come back later today with specific examples as I must have worded this poorly.

I understand the difference between a container log and a file, but my problem is that (at least on the Kode Kloud mock exams) if I don’t write the command/args exactly as the solution expects (despite having many different ways you could do it) I get the question wrong despite having the same result.

I am wondering if that is a kode kloud thing or something I need to watch out for on the actual CKAD.

Please advise which mock exam. If it is one from the course itself, attach the link to the exam lab.
If it is from Ultimate Mocks, paste both the question content and SECTION header so that I may locate it.

1 Like

@Alistair_KodeKloud here is an example from Ultimate Certified Kubernetes Application Developer (CKAD) Mock Exam Series (Mock Exam 1):

SECTION: APPLICATION DESIGN AND BUILD

For this question, please set the context to cluster1 by running:
kubectl config use-context cluster1

In the ckad-multi-containers namespace, create a pod named healthy-server, which consists of 2 containers. One main container and one init-container both are running busybox:1.28 image.
Init container should print this message Initialize application environment! and then sleep for 10 seconds.
Main container should print this message The app is running! and then sleep for 3600 seconds.

Here is the given solution:

apiVersion: v1
kind: Pod
metadata:
  name: healthy-server
  namespace: ckad-multi-containers
  labels:
    app.kubernetes.io/name: healthy-server
spec:
  containers:
    - name: server-container
      image: busybox:1.28
      command:
        - sh
        - -c
        - echo The app is running! && sleep 3600
  initContainers:
    - name: init-myservice
      image: busybox:1.28
      command:
        - sh
        - -c
        - echo Initialize application environment! && sleep 10

Here is my solution:

My solution:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: healthy-server
  name: healthy-server
  namespace: ckad-multi-containers
spec:
  containers:
  - image: busybox:1.28
    name: healthy-server
    command:
      - sh
    args:
      - -c
      - 'echo The app is running! && sleep 3600'
  initContainers:
  - image: busybox:1.28
    name: init-container
    command:
      - sh
    args:
      - -c
      - 'echo Initialize application environment! && sleep 10'
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

When I check the logs of the 2 pods, both have the expected output and both sleep as long as was requested.

When I remove the 2 lines that say args: and just use command, then I pass the question.
The question is not worded in any way to suggest that I can only use command and not args.

On the actual CKAD should I only use command and not args?

There are at least 2 other questions with exactly the same problem, I just haven’t run into them again yet.

You are misunderstanding the relationship between command and args

The command that the question is asking you to run would be entered to a linux terminal like this

sh -c "The app is running! && sleep 3600"

So in a pod definition that is

      command:
        - sh
        - -c
        - echo The app is running! && sleep 3600

Now, if you know that the docker image being used in the pod was built with an ENTRYPOINT instruction, then that is the command. That command may or may not require some additional arguments. This is when args is used, to pass more arguments to the command which is already present in the image.

You may have seen the image kodekloud/webapp-color in the labs. This has a dockerfile that looks like this. Note that it has an ENTRYPOINT. This means that without you having to specify it in the pod definition, it is implicitly

      command:
        - python
        - app.py

Now let’s suppose that python program could accept additional arguments on the command line (it doesn’t but it would be easy to change it so it does), i.e

python app.py --color blue

then the pod definition would have no command, but would have

    args:
    - --color
    - blue

Get it yet?

In terms of images that you’re using for these challenges, know that all base images - those which are simply a Linux distro without any specific software (nginx, redis etc), do not have an embedded ENTRYPOINT. So that’s images like busybox, alpine, ubuntu etc. - these require a command otherwise they’ll immediately exit and go into crashloop.

If you put a command, then use only command. Do not additionally put args.

1 Like

I see your point, but I copied the basis for my answer straight from the documentation:

command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]

That is the example given in the docs at:

I used sh for the command (entrypoint) and then -c ... for my arguments (command) just like in the documentation.

Can you help me understand why that isn’t correct in this case?

If I were designing a docker container I would likely choose an entrypoint of /bin/sh or sh as that seems common practice from the images I have seen, so to me it makes sense to use that for the command of the container.

It is not common to do it that way. Like many things in kube there is more than one way to achieve the same result.
Which ultimate mock question is it?
Please paste the SECTION header and the question content

Here it is:

SECTION: APPLICATION DESIGN AND BUILD

For this question, please set the context to cluster1 by running:
kubectl config use-context cluster1

In the ckad-multi-containers namespace, create a pod named healthy-server, which consists of 2 containers. One main container and one init-container both are running busybox:1.28 image.
Init container should print this message Initialize application environment! and then sleep for 10 seconds.
Main container should print this message The app is running! and then sleep for 3600 seconds.

Thanks for taking the time to go through all of this!

I think there are issues with the question. It does not give enough information to provide exactly what the marking script is looking for,

I am discussing this internally.

The real exams are usually unambiguous.

1 Like

Ok great, thanks for clarifying!

I have had a great experience overall with Kode Kloud, and appreciate all the help.

On the topic of the Ultimate Exams, here are 2 other issues I noticed:

  1. ~/.vimrc does not have the same settings as in the exam, or other KodeKloud content.
  2. The given solution to the following question doesn’t run:

SECTION: APPLICATION DESIGN AND BUILD

For this question, please set the context to cluster1 by running:
kubectl config use-context cluster1

In the ckad-job namespace, create a cronjob named simple-python-job to run every 30 minutes to list all the running processes inside a container that used python image (the command needs to be run in a shell).

Here is the given solution:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: simple-python-job
  namespace: ckad-job
spec:
  schedule: "*/30 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: simple-python-job
            image: python
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - ps –eaf
          restartPolicy: OnFailure

If you change the cron job to run once a minute, you will see it actually doesn’t run successfully and goes into CrashLoopBackOff.

I spent a bit of time trying to figure out what the command should be to get it to actually run, but eventually gave up.

Thanks again for taking a look at these issues!

Upon this Cronjob question, I think there is something wrong with solutions or checks.
the - in solution is \342\200\223. Refer Answer 1 in bash - "ssh: Could not resolve hostname \342\200\223" for command line 'ssh -T [email protected]' - Stack Overflow

ps -eaf

And it can be verified to copy the solution to terminal and run 'cat cronjob.yaml | sed -n “l” ’

I think you’re using the wrong type of quote mark. In the shell, you can use plain single quotes (') or plain double quotes ("), but you appear to be using a fancy double quote (), which the shell does not understand. This would be an error on your part and not the question grader :slight_smile: