I have a webapp running in a Docker-container in a Kubernetes cluster. The app has an endpoint I want to be called periodically. The app runs at multiple nodes/pods, and it is important that only one node performs the task initiated by the endpoint. I have looked at Kubernetes Cron Jobs, but have not found any documentation on calling endpoints from a Kubernetes Cron Job. Does anybody have any proposal for a solution of this problem? How do you handle scheduling in a cluster where it is crucial that only one node performs the task?
Asked
Active
Viewed 2.3k times
22
-
Do you mean only 1 node concurrently? Only 1 node ever? Does the 1 node need to be the node calling the endpoint or is the 1 node the endpoint being called? Is it important to only call 1 Pod and it doesn't matter what node it is on, or is it any Pod on one node? – coreypobrien Nov 10 '17 at 17:36
-
It is important to only call 1 pod each day at a certain time and it doesn't matter what node it is on. The 1 pod is the endpoint beeing called. – user1119371 Nov 11 '17 at 08:13
1 Answers
45
CronJob
s are a good choice. Here's a quick layout that runs 3 nginx pods accepting all traffic. Every minute, a Job
curls 1 of the 3 pods (always the same pod).
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: main
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: singleton
labels:
app: nginx
special: singleton
spec:
replicas: 1
selector:
matchLabels:
app: nginx
special: singleton
template:
metadata:
labels:
app: nginx
special: singleton
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: allpods
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: singleton
spec:
selector:
special: singleton
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: callout
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: callout
image: buildpack-deps:curl
args:
- /bin/sh
- -ec
- curl http://singleton
restartPolicy: Never

coreypobrien
- 1,921
- 17
- 17
-
may i ask why do u need the second service? hasn't the first service already covered what the second service's doing? (forgive me if that's a stupid question. i'm new to kubernetes) – anniex Sep 09 '20 at 04:17
-
1The `allpods` service targets `Pods` from both services by using the `app: nginx` label that both `Deployments` include. The `singleton` `Service` only targets the `singleton` `Deployment`. The `allpods` `Service` would be the one most users would target. The `singleton` `Service` is specifically the use case of `it is important that only one node performs the task` from the original question. You can see the `Cronjob` targets `http://singleton` so that the same single `Pod` handles that task. – coreypobrien Sep 09 '20 at 13:44
-
@coreypobrien is it necessary to have two services to achieve this? For instance: If you have 3 pods and one service targeting the 3 of them, if a request is sent to the service, the service will redirect it to only one of the pods, as far as I understand – brunochaina May 26 '21 at 14:21