I would like to create a kubernetes CronJob scheduler which can invoke .netcore console application every minute.
CronJob Spec [cronjob-poc.yml]:
kind: CronJob
metadata:
name: cronjob-poc
spec:
schedule: "*/1 * * * *" #Every Minute
jobTemplate:
spec:
template:
spec:
containers:
- name: cronjob-poc
image: cronjobpoc:dev
command: ["/usr/local/bin/dotnet", "/app/CronJobPoc.dll"]
restartPolicy: OnFailureKind Commands:
kind create cluster --name=cronjob-poc
kind load docker-image cronjobpoc:dev --name=cronjob-poc
kubectl apply -f .\cronjob-poc.yml
.netcore is a very simple app which just prints hello
using System;
namespace CronJobPoc{
class Program{
static void Main(string[] args)
{
Console.WriteLine(quot;{DateTime.Now} - Hello World!");
}
}
}
Docker File:
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["CronJobPoc/CronJobPoc.csproj", "CronJobPoc/"]
RUN dotnet restore "CronJobPoc/CronJobPoc.csproj"
COPY . .
WORKDIR "/src/CronJobPoc"
RUN dotnet build "CronJobPoc.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "CronJobPoc.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CronJobPoc.dll"]When I do kubectl get pods I see below information.
NAME READY STATUS RESTARTS AGE
cronjob-poc-1589463060-9dp8p 0/1 CrashLoopBackOff 4 2m51sWhen I try to see logs using kubectl logs cronjob-poc-1589463060-9dp8p I do not see anything. The command returns empty.
Not sure how to see the logs. There is something wrong but not sure what?
I am expecting to see the output " - Hello World!" somewhere in the log. Not sure how to check what went wrong and where can the logs with proper error messages can be seen.
Any quick help on this would be highly appreciated.
I also tried using command argument as shown below in cronjob-poc.yml. I get CrashLoopBackOff status for the pod
command:
- /bin/sh
- -c
- echo Invoking CronJobPoc.dll ...; /usr/local/bin/dotnet CronJobPoc.dllWhen I try to check the log using kubectl logs , I see /bin/sh: 1: /usr/local/bin/dotnet: not found
You could simplify the Dockerfile a bit. Here's an example I use in my cron job netcore apps:
# Copy csproj and restore as layer 1
FROM microsoft/dotnet:2.1-sdk-alpine AS build
ARG NUGET=https://api.nuget.org/v3/index.json
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore --source $NUGET
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/dotnet:2.1-runtime-alpine AS final
WORKDIR /app
COPY --from=build /app/out .
CMD ["dotnet", "Custom.MetricScraper.dll"]It's 3 steps, slightly easier to read. You'll notice the difference is that instead of ENTRYPOINT I'm using CMD at the end. You can modify this to fit your project name and netcore 3.1.
Here's the corresponding YAML:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: metric-scraper-job
labels:
app: metric-scraper
spec: # Cron job wrapper around a job
schedule: "* * * * *"
jobTemplate:
spec: # Job definition
template:
metadata:
labels:
app: metric-scraper
is-cron: "true"
spec: # Pod definition
containers:
- name: metric-scraper
image: metricscraper:latest
imagePullPolicy: IfNotPresent
env:
- name: ASPNETCORE_ENVIRONMENT
value: Production
restartPolicy: Never
backoffLimit: 2This YAML definition will run the image metricscraper:latest every minute.
One thing I noticed though about cron jobs in k8s is that the pods don't get cleaned up (at least on my 1.14 cluster). A workaround is setting a pod limit on a namespace via resourcequotas and sticking the cron jobs in there. Hope this helps!
The issue was, I was trying to docker this dotnetcore app using Visual Studio which was not installing sdk. When I dockered it manually using command 'docker build -t cronjobpoc .', it worked. Also in the command I simply used 'dotnet CronJobPoc.dll' as dotnet was already there in the path
command: - /bin/sh - -c - echo Invoking CronJobPoc.dll ...; dotnet CronJobPoc.dl