redis / docker-library-redis

Docker Official Image packaging for Redis
http://redis.io
BSD 3-Clause "New" or "Revised" License
1.12k stars 561 forks source link

fix: zombie process. #325

Closed breakliu closed 1 year ago

breakliu commented 1 year ago

redis:6-alpine for K8s, readiness or liveness probe call 'timeout' ( busybox ) would cause zombie process.

livenessProbe:
  exec:
    command:
    - sh
    - -c
    - |-
      response=$(timeout -s 3 5 redis-cli --no-auth-warning -a $REDIS_PASSWORD -h localhost -p $REDIS_PORT ping)
      if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then
        echo "$response"
        exit 1
      fi
  failureThreshold: 5
  initialDelaySeconds: 5
  periodSeconds: 5
  successThreshold: 1
  timeoutSeconds: 5
readinessProbe:
  exec:
    command:
    - sh
    - -c
    - |-
      response=$(timeout -s 3 5 redis-cli --no-auth-warning -a $REDIS_PASSWORD -h localhost -p $REDIS_PORT ping)
      if [ "$response" != "PONG" ]; then
        echo "$response"
        exit 1
      fi
  failureThreshold: 5
  initialDelaySeconds: 5
  periodSeconds: 5
  successThreshold: 1
  timeoutSeconds: 1

It is the same when I use docker.

alpine version docker run --rm -it --name redis redis:6-alpine, docker exec -it redis sh:

image

but debian version docker run --rm -it --name redis redis:6 timeout is ok:

image

so I think coreutils instead of busybox's timeout, could solve this issue?

yosifkit commented 1 year ago

Interesting, it seems that the BusyBox provided timeout is not well behaved without a process reaper. This is then a general issue with using busybox's timeout in any container that isn't using a reaper (like tini) and not something specific to running redis. timeout is not something we expect redis to ever run on it's own and so is outside the scope of the image. 

breakliu commented 1 year ago

Yes. So redis alpine version is not recommanded? Now we use debian version instead.

tao12345666333 commented 1 year ago

I don't think Alpine-based images are not recommanded here.

Just because your particular use case uses timeout, which is not the point of this image.

If you want the zombie process to be recycled, the best way is to have a program that manages process recycling.

➜  ~ docker run --init --rm -d --name redis redis:6-alpine 
be3d814b9eaf0664710b2662f40a42758334077b9a80bbd6a3c6e2527bddccd2
➜  ~ docker exec -it redis sh
/data # timeout 5 ls
/data # timeout 5 ls
/data # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /sbin/docker-init -- docker-entrypoint.sh redis-server
    7 redis     0:00 redis-server *:6379
   15 root      0:00 sh
   27 root      0:00 ps -ef
/data # exit
➜  ~ docker stop -t1 redis   
redis
breakliu commented 1 year ago

@tao12345666333 👍

And How to solve in K8s livenessProbe and readinessProbe? thx

tianon commented 1 year ago

Creating a custom image that installs a zombie-reaping init like tini and running it as PID1 in your container is what I'd recommend, but doing so is out of scope here.