Repository: rothgar/bashScheduler Branch: main Commit: f676d8048578 Files: 3 Total size: 4.1 KB Directory structure: gitextract_mu2czho1/ ├── README.md ├── nginx.deploy.yaml └── scheduler.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ ![](img/banner.png) Kubernetes bash scheduler ============ ### This is a really bad idea I made it because it was helpful for me to learn :bowtie: I hope you learn something too. ## How to run it Please don't ever use this on a production kubernetes cluster!!! Run it against a local [kind](https://kind.sigs.k8s.io/) cluster. ``` kind create cluster ``` Create pods that use the custom scheduler. ``` kubectl apply -f https://raw.githubusercontent.com/rothgar/bashScheduler/main/nginx.deploy.yaml ``` You should see nginx pods with Pending status ``` NAME READY STATUS RESTARTS AGE nginx-56dcc974bc-8ss4m 0/1 Pending 0 49m nginx-56dcc974bc-94ltw 0/1 Pending 0 49m nginx-56dcc974bc-tnz6s 0/1 Pending 0 49m ``` Then proxy your localhost to the kubernetes api server ``` kubectl proxy Starting to serve on 127.0.0.1:8001 ``` Now in a new terminal run ``` curl -sL https://raw.githubusercontent.com/rothgar/bashScheduler/main/scheduler.sh | bash ``` You should see similar output to ``` Assigned nginx-56dcc974bc-8ss4m to kind-control-plane Assigned nginx-56dcc974bc-94ltw to kind-control-plane Assigned nginx-56dcc974bc-tnz6s to kind-control-plane ``` Look at the code and see what it's doing. Uncomment `set -x` to see all the commands run. Have fun :shipit: ================================================ FILE: nginx.deploy.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: schedulerName: bashScheduler containers: - name: nginx image: nginx resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 80 ================================================ FILE: scheduler.sh ================================================ #!/usr/bin/env bash # # A kubernetes scheduler written in bash # dependencies: kubectl, curl # Runs against localhost:8001 by default # Use `kubectl proxy` to proxy to master without https # # Author: Justin Garrison # justingarrison.com # @rothgar set -eo pipefail # uncomment to see all commands in stdout # set -x SERVER="${SERVER:-localhost:8001}" SCHEDULER="${SCHEDULER:-bashScheduler}" while true; do # Get a list of all our pods in pending state for POD in $(kubectl --server ${SERVER} get pods \ --output jsonpath='{.items..metadata.name}' \ --all-namespaces \ --field-selector=status.phase==Pending); do SCHEDULER_NAME=$(kubectl get pod ${POD} \ --output jsonpath='{.spec.schedulerName}') if [ "${SCHEDULER_NAME}" == "${SCHEDULER}" ]; then # Get the pod namespace NAMESPACE=$(kubectl get pod ${POD} \ --output jsonpath='{.metadata.namespace}') # Get an array for all of the nodes # We could optionally check if the nodes are ready NODES=($(kubectl --server ${SERVER} get nodes \ --output jsonpath='{.items..metadata.name}')) # Store a number for the length of our NODES array NODES_LENGTH=${#NODES[@]} # Randomly select a node from the array # $RANDOM % $NODES_LENGTH will be the remainder # of a random number divided by the length of our nodes # In the case of 1 node this is always ${NODES[0]} NODE=${NODES[$[$RANDOM % $NODES_LENGTH]]} # Bind the current pod to the node selected curl --silent --fail \ --header "Content-Type:application/json" \ --request POST \ --data '{"apiVersion":"v1", "kind": "Binding", "metadata": { "name": "'${POD}'" }, "target": { "apiVersion": "v1", "kind": "Node", "name": "'${NODE}'" } }' \ http://${SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${POD}/binding/ >/dev/null \ && echo "Assigned ${POD} to ${NODE}" \ || echo "Failed to assign ${POD} to ${NODE}" fi done echo "Nothing to do...sleeping." sleep 6s done