web-dev-qa-db-fra.com

Cron Jobs dans Kubernetes - se connecter à un pod existant, exécuter un script

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:

  1. Se connecter à un pod existant
  2. Exécuter un script
  3. Déconnecter

J'ai d'autres méthodes pour le faire, mais ils ne se sentent pas bien. 

  1. Planifiez une tâche périodique pour: kubectl exec -it $ (kubectl get pods --selector = un-sélecteur | tête -1)/path/to/script

  2. 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?

http://kubernetes.io/docs/user-guide/cron-jobs/

17
Aeisor

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).

1
Brett Wagner

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
1
Simon I