我确定我错过了一些明显的东西。我查看了Kubernetes上的ScheduledJobs / CronJobs文档,但我找不到按计划执行以下操作的方法:
我有其他方法可以做到这一点,但他们感觉不对。
安排一个cron任务:kubectl exec -it $(kubectl get pods --selector = some-selector | head -1)/ path / to / script
创建一个具有" Cron Pod"它还包含应用程序,以及许多非Cron Pods"这只是应用程序。 Cron Pod将使用不同的图像(一个安排了cron任务)。
如果可能的话,我宁愿使用Kubernetes ScheduledJobs来防止同一个Job同时运行多次,也因为它让我感觉更合适。
有没有办法通过ScheduledJobs / CronJobs执行此操作?
答案 0 :(得分:2)
据我所知,没有“官方”方式以你想要的方式做到这一点,我相信这是设计的。 Pod应该是短暂的,可以横向扩展,而Jobs则可以退出。将cron作业“附加”到现有pod不适合该模块。调度程序不知道作业是否完成。
相反,作业可以专门用于运行作业的应用程序实例,然后在作业完成后将其删除。为此,您可以使用与部署相同的作业图像,但可以通过设置command:
使用不同的“入口点”。
如果他们的工作需要访问您的应用程序创建的数据,那么该数据将需要在应用程序/ Pod之外保留,您可以这样做一些方法,但显而易见的方法是数据库或持久卷。 例如,使用数据库看起来像这样:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: APP
spec:
template:
metadata:
labels:
name: THIS
app: THAT
spec:
containers:
- image: APP:IMAGE
name: APP
command:
- app-start
env:
- name: DB_HOST
value: "127.0.0.1"
- name: DB_DATABASE
value: "app_db"
一个连接到同一个数据库但具有不同“入口点”的作业:
apiVersion: batch/v1
kind: Job
metadata:
name: APP-JOB
spec:
template:
metadata:
name: APP-JOB
labels:
app: THAT
spec:
containers:
- image: APP:IMAGE
name: APP-JOB
command:
- app-job
env:
- name: DB_HOST
value: "127.0.0.1"
- name: DB_DATABASE
value: "app_db"
或者持久卷方法看起来像这样:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: APP
spec:
template:
metadata:
labels:
name: THIS
app: THAT
spec:
containers:
- image: APP:IMAGE
name: APP
command:
- app-start
volumeMounts:
- mountPath: "/var/www/html"
name: APP-VOLUME
volumes:
- name: APP-VOLUME
persistentVolumeClaim:
claimName: APP-CLAIM
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: APP-VOLUME
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /app
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: APP-CLAIM
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
selector:
matchLabels:
service: app
通过这样的工作,附加到相同的卷:
apiVersion: batch/v1
kind: Job
metadata:
name: APP-JOB
spec:
template:
metadata:
name: APP-JOB
labels:
app: THAT
spec:
containers:
- image: APP:IMAGE
name: APP-JOB
command:
- app-job
volumeMounts:
- mountPath: "/var/www/html"
name: APP-VOLUME
volumes:
- name: APP-VOLUME
persistentVolumeClaim:
claimName: APP-CLAIM
答案 1 :(得分:1)
这似乎是一种反模式。为什么不能只将工作人员吊舱作为工作吊舱运行?
尽管您似乎非常确信您需要执行此操作。这就是我要做的。
带您的工作人员吊舱并将您的Shell执行包装在一个简单的Web服务中,几乎可以使用任何一种语言工作10分钟。露出港口,并在该名工人前布置服务。然后,您的工作窗格可以简单地卷曲..svc.cluster.local:/(除非您对dns感到困惑)。
答案 2 :(得分:1)
这应该有所帮助。
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/30 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
kubectl exec -it <podname> "sh script.sh ";
restartPolicy: OnFailure
答案 3 :(得分:0)
创建一个计划的容器,该容器使用Kubernetes API通过exec
函数在目标容器上运行所需的命令。容器图片应包含client libraries才能访问API-其中许多可用,或者您可以构建自己的API。
例如,这是一个使用Python客户端的解决方案,该解决方案对每个ZooKeeper容器执行并运行数据库维护命令:
import time
from kubernetes import config
from kubernetes.client import Configuration
from kubernetes.client.apis import core_v1_api
from kubernetes.client.rest import ApiException
from kubernetes.stream import stream
import urllib3
config.load_incluster_config()
configuration = Configuration()
configuration.verify_ssl = False
configuration.assert_hostname = False
urllib3.disable_warnings()
Configuration.set_default(configuration)
api = core_v1_api.CoreV1Api()
label_selector = 'app=zk,tier=backend'
namespace = 'default'
resp = api.list_namespaced_pod(namespace=namespace,
label_selector=label_selector)
for x in resp.items:
name = x.spec.hostname
resp = api.read_namespaced_pod(name=name,
namespace=namespace)
exec_command = [
'/bin/sh',
'-c',
'opt/zookeeper/bin/zkCleanup.sh -n 10'
]
resp = stream(api.connect_get_namespaced_pod_exec, name, namespace,
command=exec_command,
stderr=True, stdin=False,
stdout=True, tty=False)
print("============================ Cleanup %s: ============================\n%s\n" % (name, resp if resp else "<no output>"))
和相关的Dockerfile:
FROM ubuntu:18.04
LABEL maintainer "reDock Inc."
ADD ./cleanupZk.py /
RUN apt-get update \
&& apt-get install -y python-pip \
&& pip install kubernetes \
&& chmod +x /cleanupZk.py
CMD /cleanupZk.py
请注意,如果您具有启用了RBAC的群集,则可能需要创建服务帐户和适当的角色才能进行此API调用。像下面这样的角色足以列出pod并运行exec,例如上面的示例脚本所要求的:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-list-exec
namespace: default
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""] # "" indicates the core API group
resources: ["pods/exec"]
verbs: ["create", "get"]
相关的cron作业示例:
apiVersion: v1
kind: ServiceAccount
metadata:
name: zk-maint
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: zk-maint-pod-list-exec
namespace: default
subjects:
- kind: ServiceAccount
name: zk-maint
namespace: default
roleRef:
kind: Role
name: pod-list-exec
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: zk-maint
namespace: default
labels:
app: zk-maint
tier: jobs
spec:
schedule: "45 3 * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: zk-maint
image: myorg/zkmaint:latest
serviceAccountName: zk-maint
restartPolicy: OnFailure
imagePullSecrets:
- name: azure-container-registry
答案 4 :(得分:0)
我设法通过使用doctl(DigitalOcean的命令行界面)和kubectl创建自定义图像来做到这一点。 CronJob对象将使用这两个命令来下载集群配置并针对容器运行命令。
以下是CronJob示例:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: drupal-cron
spec:
schedule: "*/5 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: drupal-cron
image: juampynr/digital-ocean-cronjob:latest
env:
- name: DIGITALOCEAN_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: api
key: key
command: ["/bin/bash","-c"]
args:
- doctl kubernetes cluster kubeconfig save drupster;
POD_NAME=$(kubectl get pods -l tier=frontend -o=jsonpath='{.items[0].metadata.name}');
kubectl exec $POD_NAME -c drupal -- vendor/bin/drush core:cron;
restartPolicy: OnFailure
这是CronJob使用的Docker映像:https://hub.docker.com/repository/docker/juampynr/digital-ocean-cronjob
如果您不使用DigitalOcean,请弄清楚如何下载群集配置,以便kubectl
可以使用它。例如,对于Google Cloud,您必须下载gcloud
。
这是我实施此https://github.com/juampynr/drupal8-do的项目存储库。