Je suis certain qu'il me manque quelque chose d'évident. J'ai parcouru la documentation de ScheduledJobs/CronJobs sur Kubernetes, mais je ne trouve pas le moyen de procéder comme suit:
J'ai d'autres méthodes pour le faire, mais ils ne se sentent pas bien.
Planifiez une tâche périodique pour: kubectl exec -it $ (kubectl get pods --selector = un-sélecteur | tête -1)/path/to/script
Créez un déploiement comportant un "Cron Pod" contenant également l'application et de nombreux "Non Cron Pods", qui ne sont que l'application. Le pod Cron utiliserait une image différente (une image avec des tâches cron programmées).
Je préférerais si possible utiliser les tâches planifiées de Kubernetes pour empêcher le même travail de s'exécuter plusieurs fois à la fois et aussi parce que cela me semble être le moyen le plus approprié de le faire.
Existe-t-il un moyen de faire cela avec ScheduledJobs/CronJobs?
Cela semble être un anti-modèle. Pourquoi ne pouvez-vous pas simplement gérer votre poste de travail en tant que poste de travail?
Peu importe, vous semblez assez convaincu de la nécessité de le faire. Voici ce que je ferais.
Prenez votre module de travail et enveloppez votre exécution de Shell dans un simple service Web, c’est 10 minutes de travail avec n’importe quelle langue. Exposer le port et mettre un service devant ce travailleur/ces travailleurs. Ensuite, vos modules de travail peuvent simplement curl ..svc.cluster.local:/(à moins que vous n’ayez été avec dns).
Celui-ci devrait aider.
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
Autant que je sache, il n’existe pas de moyen "officiel" de procéder de la manière que vous souhaitez, et c’est ce que je crois intentionnellement. Les pods sont supposés être éphémères et évolutifs horizontalement, tandis que Jobs est conçu pour sortir. Le fait de "joindre" un travail cron à un pod existant ne convient pas à ce module. Le planificateur n'aurait aucune idée si le travail était terminé.
Au lieu de cela, un travail peut faire apparaître une instance de votre application spécifiquement pour l'exécution du travail, puis le supprimer une fois le travail terminé. Pour ce faire, vous pouvez utiliser la même image pour le travail que pour votre déploiement, mais utilisez un autre "Entrypoint" en définissant command:
.
Si leur travail a besoin d'accéder aux données créées par votre application, ces données devront être conservées en dehors de l'application/du module, vous pouvez le faire de différentes manières, mais les méthodes les plus évidentes seraient une base de données ou un volume persistant. utiliser une base de données ressemblerait à ceci:
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"
Et un travail qui se connecte à la même base de données, mais avec un "Entrypoint" différent:
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"
Ou l'approche du volume persistant ressemblerait à ceci:
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
Avec un travail comme celui-ci, se rattachant au même volume:
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