How can I run a cli app in a pod inside a Kubernetes cluster?

Viewed 52

I have a cli app written in NodeJS [not by me].

I want to deploy this on a k8s cluster like I have done many times with web servers.

I have not deployed something like this before, so I am in a kind of a loss.

I have worked with dockerized cli apps [like Terraform] before, and i know how to use them in a CICD.

But how should I deploy them in a pod so they are always available for usage from another app in the cluster?

Or is there a completely different approach that I need to consider?

#EDIT#

I am using this in the end of my Dockerfile ..

# the main executable
ENTRYPOINT ["sleep", "infinity"]
# a default command
CMD ["mycli help"]

That way the pod does not restart and the cli inside is waiting for commands like mycli do this

Is it a hacky way that is frowned upon or a legit solution?

2 Answers

Your edit is one solution, another one if you do not want or cannot change the Docker image is to Define a Command for a Container to loop infinitely, this would achieve the same as the Dockerfile ENTRYPOINT but without having to rebuild the image.

Here's an example of such implementation:

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: debian
    command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
  restartPolicy: OnFailure

As for your question about if this is a legit solution, this is hard to answer; I would say it depends on what your application is designed to do. Kubernetes Pods are designed to be ephemeral, so a good solution would be one that is running until the job is completed; for a web server, for example, the job is never completed because it should be constantly listening to requests.

If your pods are in the same cluster they are already available to other pods through Core-DNS. An internal DNS service which allows you to access them by their internal DNS name. Something like my-cli-app.my-namespace.svc.cluster. DNS for service and pods

You would then create a deployment file with all your apps. Note this doesn't need ports to work and also doesn't include communication through the internet.

#deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
Related