# Errbot 入门（3）

## 通过 Errbot 控制 Kubernetes

前面两篇分别讲了 Errbot 的简单启动和 Slack 的集成。这一篇做个结尾，用 Errbot 来查询 Kubernetes 的状态。

之前使用的 Docker 镜像中，已经集成了 Kubernetes 的 Python 客户端，所以这里只要在 Python 中引用，就可以操作了。

这里实现两个功能，第一个是列出 kubeconfig 文件中的 context，第二个是列出集群 Node 的健康状况。

## 准备工作

首先在 Errbot 的加载卷目录中新建目录`kubeconfig`，并在其中放置一个可用的 kubeconfig 文件。例如：

\*\* /usr/local/var/volumes/errbot/kubeconfig/config \*\*

```yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority: ca-dummy/ca.pem
    server: https://10.211.55.11:6443
  name: default
users:
- name: default
  user:
    client-certificate: ca-dummy/admin.pem
    client-key: ca-dummy/admin-key.pem
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
```

当然，要确保 Errbot 到 Kubernetes 的网络连接是有效的。

## Context 列表

```python
from errbot import BotPlugin, botcmd, re_botcmd
import re
from kubernetes import config, client


class Kube(BotPlugin):
  @botcmd
  def context_list(self, msg, args):
      """ List all contexts in the kubeconfig file.
      """
      yield("Context in the kubeconfig:")
      for context_name in list_context():
          yield(context_name)


def list_context():
    (context_list, context_current) = config.list_kube_config_contexts(
        "/errbot/kubeconfig/config")
    result = []
    for context in context_list:
        result.append(context["name"])
    return result
```

`import` 部分引入了几个常用的 Bot 开发支持库，以及 Kubernetes API 库。

接下来创建新的 Bot 插件 `Kube`。

`@botcmd` 修饰其中的方法 `context_list`，也就是生成了一个 `!context list` 命令。

注释内容会出现在命令列表的说明中。

内容很简单，调用 kubernetes API 的 `config.list_kube_config_contexts` 方法，列出其中所有的 context。

`yield` 在这里用于输出多行数据到聊天室。

使用 `!restart` 命令重启 Bot 之后，输入 `!help` 查看我们的插件，会看到列表中多出这样的内容：

Kube This is a simple plugin example to get you started. • !context list - List all contexts in the kubeconfig file.

执行 `!context list`，Bot 读取配置文件，返回了其中的 Context 名称列表：

Context in the kubeconfig: default

接下来加入列出 Node，并查看健康状态代码

```python
@botcmd(split_args_with=None)
def cluster_health(self, msg, args):
    """Simpler checker nodes, pods and workload controllers.
    """
    if len(args) != 1:
        yield("This command need context name as the only parameter.")
        yield("Here is the context list:")
        for context_name in list_context():
            yield(context_name)
        return

    context_name = args[0]
    api_instance = get_instance(context_name)
    node_list = api_instance.list_node()
    # Node
    yield("Checking Nodes...")
    for node in node_list.items:
        name = node.metadata.name
        status = "NotReady"
        last_condition = node.status.conditions[-1:][0]
        if (last_condition.type == "Ready" and
                last_condition.status == "True"):
            status = "Ready"
        if status != "Ready":
            yield("{} {}\n".format(name, status))

def get_instance(context_name, api_version="core_v1"):
    api_client = config.load_kube_config(
        config_file="/errbot/kubeconfig/config",
        context=context_name)
    api_instance = client.CoreV1Api(api_client)
    return api_instance
```

`@botcmd(split_args_with=None)`，这一注解的意思是对聊天内容进行分拆，分拆产生的列表保存在`args` 之中。

对 Node 的 Status 对象的 Conditions 列表进行解析，如果最后一个状态不是 Ready，则输出不健康 Node。

## 打完收工

在我们常见的工作场景中，结合各种系统的 API，可以利用 Errbot 在同一个聊天室中做很多操作，例如：

1. 触发 Jenkins 构建
    
2. 对 ElasticSearch、Zabbix、Prometheus 进行查询
    
3. 管理 Kubernetes 负载。
    
4. 等等等等。
    

实际上除了这两种看起来比较古板的交流方式之外，还有看起来舒服一点的正则表达式匹配方式，然而，目前更大的热点是 AI，有了这种支持，个人觉得就不必挖空心思的琢磨分词和模式的问题了，做好和第三方的链接就可以了。
