我有kubernetes作业定义如下:
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
当pod启动并运行时,redis为空:
/deploy/base$ kubectl exec -it -n box redis-master-mbhrk -- /bin/sh
# redis-cli lrange codes 0 -1
(empty array)
#
这个pod应该在队列代码为空时杀死他自己。
也,我得到一个错误在pod控制台
can't access tty; job control turned off
如何加载代码到redis ??
一个容器只能执行一个命令。您已经将该命令设置为/bin/sh -c
,并将其传递给要运行的命令字符串(redis-server
),以及两个附加参数,这些参数将在该命令字符串中显示为$0
和$1
。
你需要做的第一件事是将Redis服务器拆分到一个单独的容器中,可能由StatefulSet管理(或者可能是Deployment,如果持久化被禁用)。您可以使用预打包的Helm图表来简化部署。我们假设这个已经存在:
apiVersion: v1
kind: Service
metadata:
name: redis-server
...
现在您的作业需要,只需运行redis-cli RPUSH
命令。由于使用命令替换的方式,这里确实需要一个shell。然而,因为你不是在这里运行Redis服务器,你不需要各种各样的机器。
你可以这样写作业:
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
你可能需要设置标签,这样它们就不会被主服务拾取(因为pod没有运行Redis服务器)。我还将重启策略设置为OnFailure
:如果pod由于某种原因失败,可能是因为Redis服务器还不可用,这将自动重启它,但如果成功,作业将标记为"完成"。
问题在
args:
- redis-server
- sleep 10
命令redis-server是启动redis服务器的命令。所以下一个命令不能执行,因为redis-server还在运行。