Shell-operator是用于在Kubernetes集群中运行事件驱动脚本工具。Shell-operator通过脚本作为事件触发的钩子(hook),在Kubernetes集群事件和Shell脚本之间提供了一个转化层。触发钩子包含add, update和delete。以pod add为例通俗的话说,当新创建了一个pod时,会自动触发脚本中else部分。

Shell-operator特点:

  • 轻松管理Kubernetes集群:可以是bash,python和kubectl。
  • Kubernetes对象事件:钩子触发包含add, update或delete事件。
  • 对象选择器和属性过滤器:可以监视一组特定的对象并检测其属性的变化。
  • 配置简单:钩子绑定语法格式为yaml/json输出。

1、环境准备(只要Kubernetes环境即可)

Kubernetes: v1.18.3

2、快速开始(包含bash和python实例)

目录结构

[root@node1 shell-operator]# tree
.
├── Dockerfile
├── hooks
│   └── pods-hook.sh
└── shell-operator-pod.yaml

2.1、Shell-operator最简设置步骤为:

  • 用钩子(脚本)构建的镜像。
  • 在Kubernetes集群中创建必要的RBAC对象。
  • 使用构建的镜像运行一个pod/deployment。

2.2、用钩子脚本构建镜像

  • 钩子是一个脚本,当执行–config选项时,配置将以yaml/json格式输出。
  • 以下创建一个简单的operator将来监视所有namespaces下的所有pod,并记录新pod的名字。
  • 包含pods-hook.sh和Dockerfile

以bash脚本为例

  • pods-hook.sh
#!/usr/bin/env bash

if [[ $1 == "--config" ]] ; then
  cat <<EOF
configVersion: v1
kubernetes:
- apiVersion: v1
  kind: Pod
  executeHookOnEvent: ["Added"]
EOF
else
  podName=$(jq -r .[0].object.metadata.name $BINDING_CONTEXT_PATH)
  echo "Pod '${podName}' added"
fi
  • 添加执行权限。

chmod +x pods-hook.sh

  • 基于flant/shell-operator:latest的基础镜像构建新的Dockerfile。
FROM flant/shell-operator:latest
ADD pods-hook.sh /hooks
  • 构建一个新的镜像。

docker build -t lilinlinlin/shell-operator:monitor-pods

  • 推镜像至dockerhub, 仓库名根据自身的情况而定,也可以不操作此步骤。

docker push lilinlinlin/shell-operator:monitor-pods

2.3、创建RBAC对象

需要监视所有namespaces下的pods,意味着我们需要shell-operator的特定RBAC定义。

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

2.4、在集群中部署shell-operator

shell-operator-pod.yaml文件为

apiVersion: v1
kind: Pod
metadata:
  name: shell-operator
spec:
  containers:
  - name: shell-operator
    image: lilinlinlin/shell-operator:monitor-pods
    imagePullPolicy: IfNotPresent
  serviceAccountName: monitor-pods-acc
  • 部署shell-operator时,pods-hook.sh脚本中if的部分就会被执行。新创建pod时,else部分就会被执行。

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

3、测试验证效果

部署一个nginx服务,查看日志。会出现Pod nginx-****** added字样,说明监视生效了。

kubectl run nginx --image=nginx
kubectl -n example-monitor-pods logs pod/shell-operator -f
...
INFO[0027] queue task HookRun:main                       operator.component=handleEvents queue=main
INFO[0030] Execute hook                                  binding=kubernetes hook=pods-hook.sh operator.component=taskRunner queue=main task=HookRun
INFO[0030] Pod 'nginx-775dd7f59c-hr7kj' added  binding=kubernetes hook=pods-hook.sh output=stdout queue=main task=HookRun
INFO[0030] Hook executed successfully                    binding=kubernetes hook=pods-hook.sh operator.component=taskRunner queue=main task=HookRun
...

4、python实例

实例中直接运行else部分。

1、hooks/00-hook.py
#!/usr/bin/env python

import sys

if __name__ == "__main__":
    if len(sys.argv)>1 and sys.argv[1] == "--config":
        print '{"configVersion":"v1", "onStartup": 10}'
    else:
        print "OnStartup Python powered hook"

2、Dockerfile
FROM flant/shell-operator:latest-alpine3.11
RUN apk --no-cache add python
ADD hooks /hooks

3、shell-operator-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: shell-operator
spec:
  containers:
  - name: shell-operator
    image: registry.mycompany.com/shell-operator:startup-python
    imagePullPolicy: IfNotPresent

4、运行

docker build -t "registry.mycompany.com/shell-operator:startup-python" .
kubectl create ns example-startup-python
kubectl -n example-startup-python apply -f shell-operator-pod.yaml
kubectl -n example-startup-python logs -f po/shell-operator

5、清理环境

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

6、参考

shell-operator