Sign inSign up

jian0209/k8s-post-deploy-task

By jian0209

Updated about 1 year ago

Running a job in kubernetes after your pod event

Image
Monitoring & observability
0

1.6K

jian0209/k8s-post-deploy-task repository overview

RUNNING A JOB AFTER UPDATE A POD?

Here is it!!!

Logic: kopf python to monitor pod create and delete, and scheduler to run a job

scheduler run every 10 seconds, and run a job that pod created after 5 mintues

pre-requisite

  • pod label must have "app" ===> to read your service name, and create a job -- ${app_name}-job
    • .labels.app
  • target pod add annotations
    • kopf.sh/post-deploy: "true"
  • pod apiVersion: v1
  • pod kind: Pod
  • create new {service account}, {cluster role}, {cluster role binding},can view the example below

env

KUBE_ANNOTATIONS      ===> the annotations from your own pod to add env to a job, prefix with 'kopf.sh/{annotations}', Default: '[]': str

JOB_NAMESPACE         ===> the namespace when you create a job and pod, Default: default
JOB_SCRIPT_CONFIG_MAP ===> configmap that include script to mount to a job's pod, Default: test-python-configmap
JOB_SCRIPT_NAME       ===> the script that is named in your configmap, Default: telegram_notify.py
JOB_SCRIPT_MOUNT_PATH ===> the path mount to a pod, Default: /mount/exec
JOB_IMAGE             ===> the image when you create a job's pod, Default: python:3.10.17-alpine3.21
JOB_COMMAND           ===> the command that run container, Default: ["sh", "-c"]
JOB_ARG               ===> the arguments to support command, able to leave blank, Default: [f"pip install requests && python {job_script_mount_path}/{job_script}"])
JOB_ENV               ===> the environment support to create a job or your script, Default: [{"name": "DATA", "value": f"Hello World!! Data Here from {app_name}!!!!"}, {"name": "TELEGRAM_BOT_TOKEN", "secret": {"name": "jian-test", "key": "TELEGRAM_TOKEN"}}, {"name": "TELEGRAM_CHAT_ID", "secret": {"name": "jian-test", "key": "TELEGRAM_CHANNEL"}}]

** To notice
{job_script} == JOB_SCRIPT_NAME
{app_name}   == pod .labels.app

The default example environment is for create a python script to call telegram webhook and send me a message.

Example of kubernetes deployment yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: post-deploy-task
  namespace: default
spec:
  selector:
    matchLabels:
      app: post-deploy-task
  template:
    metadata:
      labels:
        app: post-deploy-task
    spec:
      serviceAccountName: kopf-job-operator
      containers:
        - name: post-deploy-task
          image: docker.io/jian0209/k8s-post-deploy-task:v0.0.1
          ports:
            - containerPort: 8080
          env:
            - name: JOB_NAMESPACE
              value: default
            - name: JOB_SCRIPT_CONFIG_MAP
              value: test-python-configmap
            - name: JOB_SCRIPT_NAME
              value: telegram_notify.py
            - name: JOB_SCRIPT_MOUNT_PATH
              value: /mnt/exec
            - name: JOB_IMAGE
              value: python:3.10.17-alpine3.21
            - name: JOB_COMMAND
              value: >
                ["sh", "-c"]
            - name: JOB_ARGS
              value: >
                ["pip install requests && python /mnt/exec/telegram_notify.py"]
            - name: JOB_ENV
              value: >
                [{"name": "DATA", "value": "Data is Here!!!!"}, {"name": "TELEGRAM_BOT_TOKEN", "secret": {"name": "jian-test", "key": "TELEGRAM_TOKEN"}}, {"name": "TELEGRAM_CHAT_ID", "secret": {"name": "jian-test", "key": "TELEGRAM_CHANNEL"}}]
            - name: KUBE_ANNOTATIONS # Version 1.0.0 or above
              value: >
                ["applied-domain"]
          imagePullPolicy: Always
          resources:
            requests:
              memory: 128Mi
          readinessProbe:
            tcpSocket:
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 180

Example of configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-python-configmap
  namespace: default
spec: {}
data:
  telegram_notify.py: >
    import os
    import requests
    data = os.getenv('DATA')
    print("Hello World")

    headers = {
        'Content-Type': 'application/json'
    }

    bot = os.getenv('TELEGRAM_BOT_TOKEN')
    channel = os.getenv('TELEGRAM_CHAT_ID')
    url = 'https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}'.format(
        bot, channel, f"Hello World {data}")
        
    requests.post(url=url, headers=headers).text

Example of Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kopf-job-operator
  namespace: default

Example of Cluster Role

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kopf-job-operator-role
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "create", "patch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch", "update"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["get", "list", "watch", "create"]
  - apiGroups: ["apiextensions.k8s.io"]
    resources: ["customresourcedefinitions"]
    verbs: ["get", "list", "watch"]

Example of Cluster Role Binding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kopf-job-operator-rolebinding
subjects:
  - kind: ServiceAccount
    name: kopf-job-operator
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kopf-job-operator-role

Version

v1.0

- add annotations to pod, and generate env for job pod

1.0.1
- FIX_BUG: not remove file

1.0.2
- FIX_BUG: container log output

1.0.3
- FIX_BUG: set force string to ANNOTATIONS environment variable

Tag summary

Content type

Image

Digest

sha256:e804dfead

Size

33.8 MB

Last updated

about 1 year ago

docker pull jian0209/k8s-post-deploy-task