Skip to content
Shell-operator is a tool for running event-driven scripts in a Kubernetes cluster
Go Shell Other
Branch: master
Clone or download
Latest commit 10cf159 Jan 24, 2020
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci feat: add unit and integration tests as Github Actions Dec 4, 2019
.github/workflows test: add coverage upload to codeclimate Dec 6, 2019
cmd/shell-operator feat: Synchronization mode, snapshots, multi-queues, yaml config Jan 17, 2020
docs docs: logo image May 23, 2019
examples Add documentation of environment variables (#89) Dec 9, 2019
frameworks/shell
pkg fix: delay between tasks Jan 24, 2020
scripts/ci test: add coverage upload to codeclimate Dec 6, 2019
test feat: Synchronization mode, snapshots, multi-queues, yaml config Jan 17, 2020
.dockerignore ci: use go modules in Dockerfile Aug 16, 2019
.gitignore Initial commit Mar 22, 2019
Dockerfile Add shell framework for hooks to image (#102) Jan 23, 2020
Dockerfile-alpine3.9 Add shell framework for hooks to image (#102) Jan 23, 2020
HOOKS.md Add documentation of environment variables (#89) Dec 9, 2019
LICENSE Initial commit Mar 22, 2019
METRICS.md docs: METRICS lang fix May 7, 2019
README.md Add documentation of environment variables (#89) Dec 9, 2019
go.mod feat: Synchronization mode, snapshots, multi-queues, yaml config Jan 17, 2020
go.sum feat: Synchronization mode, snapshots, multi-queues, yaml config Jan 17, 2020
logo-shell.png docs: add logo Apr 17, 2019

README.md

Addon-operator logo

docker pull flant/shell-operator Slack chat EN Telegram chat RU

Shell-operator is a tool for running event-driven scripts in a Kubernetes cluster.

This operator is not an operator for a particular software product as prometheus-operator or kafka-operator. Shell-operator provides an integration layer between Kubernetes cluster events and shell scripts by treating scripts as hooks triggered by events. Think of it as an operator-sdk but for scripts.

Shell-operator is used as a base for more advanced Addon-operator that supports helm charts and value storages.

Shell-operator provides:

  • Ease the management of a Kubernetes cluster: use the tools that Ops are familiar with. It can be bash, python, kubectl, etc.
  • Kubernetes object events: hook can be triggered by add, update or delete events. Learn more about hooks.
  • Object selector and properties filter: Shell-operator can monitor only particular objects and detect changes in their properties.
  • Simple configuration: hook binding definition is a JSON structure on stdout.

Quickstart

You need to have a Kubernetes cluster, and the kubectl must be configured to communicate with your cluster.

Steps to setup Shell-operator in your cluster are:

  • build an image with your hooks (scripts)
  • create necessary RBAC objects (for kubernetes bindings)
  • run Pod or Deployment with a built image

Build an image with your hooks

A hook is a script that, when executed with --config option, returns configuration in JSON. Learn more about hooks.

Let's create a small operator that will watch for all Pods in all Namespaces and simply log a name of a new Pod.

"kubernetes" binding is used to tell Shell-operator about objects that we want to watch. Create the pods-hook.sh file with the following content:

#!/usr/bin/env bash

if [[ $1 == "--config" ]] ; then
  cat <<EOF
  {
    "configVersion":"v1",
    "kubernetes": [
      {
        "apiVersion": "v1",
        "kind": "Pod",
        "watchEvent": ["Added"]
      }
    ]
  }
EOF
else
  podName=$(jq -r .[0].object.metadata.name $BINDING_CONTEXT_PATH)
  echo "Pod '${podName}' added"
fi

Make the pods-hook.sh executable:

chmod +x pods-hook.sh

You can use a prebuilt image flant/shell-operator:latest with bash, kubectl, jq and shell-operator binaries to build you own image. You just need to ADD your hook into /hooks directory in the Dockerfile.

Create the following Dockerfile in the directory where you created the pods-hook.sh file:

FROM flant/shell-operator:latest
ADD pods-hook.sh /hooks

Build image (change image tag according your Docker registry):

docker build -t "registry.mycompany.com/shell-operator:monitor-pods" .

Push image to the Docker registry accessible by Kubernetes cluster:

docker push registry.mycompany.com/shell-operator:monitor-pods

Install shell-operator in a cluster

We need to watch for Pods in all Namespaces. That means that we need specific RBAC definitions for shell-operator:

kubectl create namespace example-monitor-pods &&
kubectl create serviceaccount monitor-pods-acc \
  --namespace example-monitor-pods &&
kubectl create clusterrole monitor-pods --verb=get,watch,list --resource=pods &&
kubectl create clusterrolebinding monitor-pods \
  --clusterrole=monitor-pods \
  --serviceaccount=example-monitor-pods:monitor-pods-acc

Shell-operator can be deployed as a Pod. Put this manifest into the shell-operator-pod.yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: shell-operator
spec:
  containers:
  - name: shell-operator
    image: registry.mycompany.com/shell-operator:monitor-pods
    imagePullPolicy: Always
  serviceAccountName: monitor-pods-acc

Start shell-operator by applying a shell-operator-pod.yaml file:

kubectl -n example-monitor-pods apply -f shell-operator-pod.yaml

For instance, deploy kubernetes-dashboard to trigger kubernetes hook:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml

Run kubectl -n example-monitor-pods logs po/shell-operator and see that the hook will print dashboard pod names:

...
INFO     : QUEUE add TASK_HOOK_RUN@KUBERNETES pods-hook.sh
INFO     : TASK_RUN HookRun@KUBERNETES pods-hook.sh
INFO     : Running hook 'pods-hook.sh' binding 'kubernetes' ...
Pod 'kubernetes-dashboard-769df5545f-99xsb' added
...

To delete created objects execute:

kubectl delete ns example-monitor-pods &&
kubectl delete clusterrole monitor-pods &&
kubectl delete clusterrolebinding monitor-pods

This example is also available in /examples: monitor-pods.

Environment variables

You can configure the operator with the following environment variables:

Env-Variable name Default Description
SHELL_OPERATOR_DEBUG 'no' Set to yes to turn on debug messages
SHELL_OPERATOR_WORKING_DIR '' A path to a hooks file structure
SHELL_OPERATOR_TMP_DIR '/tmp/shell-operator' A path to store temporary files with data for hooks
SHELL_OPERATOR_KUBE_CONTEXT '' The name of the kubeconfig context to use.
SHELL_OPERATOR_KUBE_CONFIG '' Path to the kubeconfig file..
SHELL_OPERATOR_LISTEN_ADDRESS '0.0.0.0:9115' Address and port to use for HTTP serving.
JQ_LIBRARY_PATH '' Prepend directory to the search list for jq modules (-L flag).
JQ_EXEC '' Set to 'yes' to use jq as executable — it is more for developing purposes.
LOG_LEVEL 'info' Logging level: debug, info, error.
LOG_TYPE 'text' Logging formatter type: json, text or color.
LOG_NO_TIME false Disable timestamp logging if flag is present. Useful when output is redirected to logging system that already adds timestamps.

Hook binding types

onStartup

This binding has only one parameter: order of execution. Hooks are loaded at start and then hooks with onStartup binding are executed in order defined by parameter. Read more about onStartup bindings here.

Example hook --config:

{
  "configVersion": "v1",
  "onStartup":10
}

schedule

This binding is for periodical running of hooks. Schedule can be defined with granularity of seconds. Read more about schedule bindings here.

Example hook --config with 2 schedules:

{
  "configVersion": "v1",
  "schedule": [
    {
      "name": "every 10 min",
      "crontab": "0 */10 * * * *",
      "allowFailure": true
    },
    {
      "name": "Every Monday at 8:05",
      "crontab": "5 8 * * 1"
    }
  ]
}

kubernetes

This binding defines a subset of Kubernetes objects that Shell-operator will monitor and a jq expression to filter their properties. Read more about onKubernetesEvent bindings here.

Example of hook --config:

{
  "configVersion": "v1",
  "kubernetes": [
    {
      "name":"Execute on changes of namespace labels",
      "kind": "namespace",
      "watchEvent":["Modified"],
      "jqFilter":".metadata.labels"
    }
  ]
}

Note: it is possible to watch custom resources, just use proper values for apiVersion and kind fields.

Prometheus target

Shell-operator provides /metrics endpoint. More on this in METRICS document.

Examples

More examples can be found in examples directory.

License

Apache License 2.0, see LICENSE.

You can’t perform that action at this time.