Creating a simple Kubernetes
Today, I am learning how to add a simple cron job to a kubernetes environment. The Cron job will ‘ping’ an endpoint of one of the hosted services every 5 minutes.
What's a Cron job?
A cron job a utility program that lets users schedule tasks to run at a specific time.
Users can determine what kind of task they want to automate and when it should be executed.
Help! I’m new to Kubernetes!
So am I, where to start? This looks like as good a place as any.
OK, so do I even have kubernetes installed? I thought I did when I installed DockerDesktop (Windows 11 machine). But it turns out - I missed the checkbox in the docker settings
Then run the following command
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE * docker-desktop docker-desktop docker-desktop
Hello World from K8
Let’s just get a simple hello world working…
Lets run the
kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4
This next line then exposes the echoserver to port 8080
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
Now you can browse to the service using
Where’s the YAML?
BUT, this isn’t quite what I was expecting… Where is the YAML? Ok, fair enough. We need to recreate this using YAML this time.
This is a great video “Kubernetes Tutorial for Beginners” which helped me understand how to get things working.
First we define the
myapp.deployment.yaml file. This is the template for what we are deploying into k8.
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment labels: app: myapp spec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: k8s.gcr.io/echoserver:1.4 ports: - containerPort: 8080
The file defines what we are deploying called “myapp-deployment”. It is using the container image “k8s.gcr.io/echoserver”. This is being exposed via the port 8080 (via containerPort). The specification is telling kubernetes to spin up 2 replicas (aka Pods).
Next, we need to create the
myapp.service.yaml file. This definies how the deployed container is wired up in Kubernetes.
apiVersion: v1 kind: Service metadata: name: myapp spec: selector: app: myapp type: LoadBalancer allocateLoadBalancerNodePorts: true externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ports: - nodePort: 30000 port: 8080 protocol: TCP targetPort: 8080
This service definition exposes the service to localhost:8080. I had to play around for a bit to get this actually working. The missing bit was around the
LoadBalancer and the targetPort. Internally the Pods are listening to port 8080.
Let’s execute these files.
kubectl apply -f .myapp.deployment.yaml kubectl apply -f .myapp.service.yaml
OK, so we now have kubernetes running a very simple service across two Pods!
Let’s add a Cron Job
I started with this config from the kubernetes website. This original script just starts a cron job and the task itself just logs to the console.
I changed the original script to use the “buildpack-deps:curl” image. The cron job itself is just a simple curl script with some noise suppression (-sS)
- This runs every minute (* * * * *)
- It simply hits the myapp service on port 8080 with a GET request.
apiVersion: batch/v1 kind: CronJob metadata: name: ping spec: schedule: "* * * * *" concurrencyPolicy: Forbid jobTemplate: spec: template: metadata: labels: app: cronjob spec: containers: - name: ping image: buildpack-deps:curl imagePullPolicy: IfNotPresent command: - /bin/sh - -ec - curl -sS http://myapp:8080 restartPolicy: OnFailure
Let’s test the cron job
kubectl apply -f .ping.cron.yaml
From the console we can list the jobs running using
kubectl get jobs
kubectl get jobs --watch NAME COMPLETIONS DURATION AGE ping-27587963 1/1 5s 2m45s ping-27587964 1/1 5s 105s ping-27587965 1/1 5s 45s
From the logs I can see the request being recieved by the myapp service and I can see the ping job printing out the raw http response.
Well, that was the first time I have played with Kubernetes. I think it is quite amazing what you can do with just some simple scripts. I wonder what real production scripts look like? I can imagine that this would get quite horrible quite quickly if rushed and learning on the job.
All in all? I’m impressed.