skip to Main Content

I have kubernetes job defined as following:

apiVersion: batch/v1
kind: Job
metadata:
  name: redis-master
  namespace: sandbox
  labels:
    app: redis
spec:
  parallelism: 1
  ttlSecondsAfterFinished: 10
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: master
          image: redis
          command: ["sh", "-c"]

          args:
          - redis-server
          - sleep 10
          - redis-cli RPUSH codes $(cat /data/codes)
          env:
            - name: MASTER
              value: "true"
          ports:
            - containerPort: 6379
          volumeMounts:
            - name: codes
              mountPath: /data/codes
              subPath: codes
              readOnly: true
      volumes:
        - name: codes
          configMap:
            name: codes
      restartPolicy: Never

when pod is up and running redis is empty:

/deploy/base$ kubectl exec -it -n box redis-master-mbhrk -- /bin/sh
# redis-cli lrange codes 0 -1
(empty array)
#

this pod should kill him self when the queue codes is empty.

also, i get an error in pod console

can't access tty; job control turned off

how can I load a codes to redis ???

2

Answers


  1. Chosen as BEST ANSWER

    The issue was in

    args:
      - redis-server
      - sleep 10
    

    Command redis-server is command which brings redis server up. So next command can not be executed because redis-server is still running.


  2. A container only runs one command. You’ve set that command to /bin/sh -c and passed it a command string to run (redis-server), along with two additional parameters which would be visible inside that command string as $0 and $1.

    The first thing you need to do is split the Redis server proper into a separate container, probably managed by a StatefulSet (or perhaps a Deployment if persistence is disabled). You might use something like a prepackaged Helm chart to simplify deploying this. We’ll assume this already exists:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-server
    ...
    

    Now your Job needs to only run the redis-cli RPUSH command. Because of the way you use a command substitution, you do need a shell here. However, since you’re not running the Redis server here, you don’t need various bits of machinery around that.

    You could probably write the Job as:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: load-codes
      namespace: sandbox
      # labels:
      #   app: redis
    spec:
      template:
        # metadata:
        #   labels:
        #     app: redis
        spec:
          containers:
            - name: loader
              image: redis
              command: 
                - /bin/sh
                - -c
                - redis-cli -h redis-server RPUSH codes $(cat /data/codes)
              volumeMounts:
                - name: codes
                  mountPath: /data
                  readOnly: true
          volumes:
            - name: codes
              configMap:
                name: codes
          restartPolicy: OnFailure
    

    You’ll probably need to set the labels so that they’re not picked up by the main Service (since the pod isn’t running a Redis server). I’ve also set the restart policy to OnFailure: if the pod does fail for some reason, maybe because the Redis server isn’t available yet, this will automatically restart it, but if it succeeds, the Job will be marked "completed".

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search