在本地(on-premise)的Kubernetes(minikube)上运行的Golang Bot,用于 Slash Command

在本地(本地部署)Kubernetes(minikube)上运行的Golang Slash Command机器人

首先

这次为了学习Golang和Kubernetes/Docker,我创建了一个简单的Golang机器人示例,用于响应Mattermost(Slack克隆)的斜杠命令。为了整理自己的思路,我将以下内容整理成一篇文章。

    1. 使用Golang创建一个简单的Bot,可以根据Slash Command的消息做出不同的回应。

 

    1. 构建一个包括Bot的Docker镜像。

 

    1. 使用Kubernetes(minikube)和k8s Manifest文件来配置Bot、Mattermost的服务和部署。

 

    在Mattermost上设置Slash Command并确认Bot的回应。

由于仍在努力学习中,我觉得可能会有不完善或冗长的地方,请您如果有任何建议,请在评论中告知。

此外,机器人的运行环境可以选择Kubernetes/Docker/Golang。
并且它还支持Mattermost(类似Slack),因此可以在本地或本地环境中运行。

关于Bot的测试,我们考虑在本地或私有环境中进行操作验证。
如果需要对外公开等情况,请另外实施包括安全措施在内的数据检查功能。
另外,关于在 k8s 上的 Mattermost(类似于 Slack)关于Bot的测试目的,并未进行数据持久化等操作。

希望您可以将ChatOps演示以及模拟环境用来参考和练习。

此外,本文中使用的源代码也在Github上公开。
https://github.com/tbuchi888/golang-slashcommand-k8s.git

运行环境等不同 factors such as operating environment.

環境 – (Environment)

以下是我们假设的环境设置:
– minikube 版本:v0.17.1
– VirtualBox 版本:5.0.16 r105871
– mac OSX Yosemite

Kubernetes正在使用minikube。
有关安装,请参考Kubernetes官方网站或者”使用minikube在本地快速创建Kubernetes集群的方法”。

1.2. 组成

我以以下形式进行了确认。

k8s.png
    • Mattermostは動作確認用途なので、データの永続化などは行わずに、単純にreplicas: 1としてhttps://hub.docker.com/r/mattermost/platform/ を動かします。

 

    tbuchi888/gobotblue:v1は後述しますローカルでビルドしたDockerイメージで、ここでGolangのBotを動かします。

2. 代码 (Mandarin: / Simplified Chinese: 代码)

2.1. Golang 机器人

根据”Slack的使用App Engine运行Slash Commands”进行参考,我们在switch语句中进行了分支处理,以便根据Slash Command的消息进行回复。请根据您的使用需求适当进行修改。
另外,我们还进行了从环境变量中获取Token、确认Method和Token以及指定监听端口号(3000号)等操作。

package main

import (
        "bytes"
        "encoding/json"
        "net/http"
        "os"

        "github.com/favclip/ucon"
)

func main() {
        ucon.Orthodox()

        ucon.HandleFunc("POST", "/", func(w http.ResponseWriter, r *http.Request) {
                if err := r.ParseForm(); err != nil {
                        w.Write([]byte(err.Error()))
                        return
                }

                w.Header().Set("Content-Type", "application/json")

                // Check method and token
                if r.Method != "POST" {
                    w.WriteHeader(http.StatusBadRequest)
                    return
                }
                if r.PostFormValue("token") != os.Getenv("GOBOTTOKEN") {
                    w.WriteHeader(http.StatusUnauthorized)
                    return
                }
                w.WriteHeader(http.StatusOK)

                data := map[string]string{
                        "response_type": "in_channel",
                        "username": "gobot",
                        "icon_url": "https://golang.org/doc/gopher/gophercolor.png",
                }

                // Switch by text
                t := r.PostFormValue("text")
                switch t {
/*--------------------------------------------------------------------------------
                        ここへ追記
                        case "条件となる文字列を指定" :
                やらせたい処理などを記載しMD記法で応答メッセージをセット。
                                data["text"] = "## 応答メッセージ"
--------------------------------------------------------------------------------*/
                        case "" :
                                data["text"] = "## メッセージが設定されていません。"
                        case "今日の天気は?" :
                                data["text"] = "## わかりません。。。"
                        default:
                                data["text"] = "## " + t + "gobotより自動返信しています。"
                }

                var buf bytes.Buffer
                json.NewEncoder(&buf).Encode(data)
                w.Write(buf.Bytes())
        })

        ucon.ListenAndServe(":3000")
        ucon.DefaultMux.Prepare()
        http.Handle("/", ucon.DefaultMux)
}

2.2 Dockerfile
2.2 Dockerfile

Docker文件是基于golang:1.8,进行了以下操作:安装了额外的模块github.com/favclip/ucon,并复制和编译了本次创建的Bot main.go文件。

Dockerfile 墨西哥人

FROM golang:1.8

RUN go get -u github.com/favclip/ucon

COPY ./main.go /go/src/main/
RUN go install main

ENTRYPOINT /go/bin/main

2.3. Kubernetes:
2.3. Kubernetes:

为GolangBot定义的Service,创建一个k8s的Manifest文件。

apiVersion: v1
kind: Service
metadata:
  name: gobotsv
  labels:
    name: app
    app: gobot
spec:
  ports:
    - name: gobot
      port: 3000
      targetPort: 3000
  selector:
    name: app
    app: gobot
    color: blue
  type: LoadBalancer

GolangBot使用的Deployment定义k8s清单文件是为了实现蓝绿部署等的功能而将部署定义分离出来。图像指定为从上述Dokcerfile构建的内容。对于环境变量GOBOTOTOKEN的value:Your_slashcommand_token,请将其替换为Mattermost(Slack)方面在配置SlashCommand时生成的令牌,或者在创建部署后使用kubectl apply -f或kubectl edit deployment命令进行单独更改。如果不更改此项,则令牌检查会导致401错误。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: gobotblue
  labels:
    name: app
    app: gobot
    color: blue
spec:
  minReadySeconds: 30
  strategy:
    type: RollingUpdate
  replicas: 4
  template:
    metadata:
      name: gobotblue
      labels:
        name: app
        app: gobot
        color: blue
    spec:
      containers:
      - image: tbuchi888/gobotblue:v1
        name: gobot
        ports:
          - containerPort: 3000
        env:
          - name: GOBOTTOKEN
            value: Your_slashcommand_token

以下是用于Mattermost的Service和Deployment定义的k8s清单文件。
考虑到机器人的测试目的,我们将简单地在k8s上运行,而不涉及数据持久化等处理。具体而言,我们将单纯地设置replicas: 1。
此外,我们使用的容器镜像如下所示:
https://hub.docker.com/r/mattermost/platform/

apiVersion: v1
kind: Service
metadata:
  name: mattermostsv
  labels:
    name: app
    app: mattermost
spec:
  ports:
    - name: mattermost
      port: 8065
      targetPort: 8065
  selector:
    name: app
    app: mattermost
    color: blue
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mattermostdep
  labels:
    name: app
    app: mattermost
    color: blue
spec:
  minReadySeconds: 30
  strategy:
    type: RollingUpdate
  replicas: 1
  template:
    metadata:
      name: mattermostdep
      labels:
        name: app
        app: mattermost
        color: blue
    spec:
      containers:
      - image: mattermost/mattermost-preview:latest 
        name: mattermost
        ports:
          - containerPort: 8065

3. 使用方法

从以下链接中克隆git仓库或参考这篇文章准备源代码文件。

Git clone https://github.com/tbuchi888/golang-slashcommand-k8s.git
cd golang-slashcommand-k8s.git

以下是目录结构(git clone 时)。

golang-slashcommand-k8s
    ├── Dockerfile
    ├── LICENSE
    ├── README.md
    ├── k8s
    │   ├── gobotblue.yml
    │   ├── gobotsv.yml
    │   ├── mattermost.yml
    │   └── readme.md
    └── main.go

無论是使用Kubernetes/Docker还是golang,都需要将环境变量GOBOTOTOKEN的值替换为在Mattermost(Slack)的Slash Command设置时提供的Token。

3.1. 在 Kubernetes(Minikube)上

以下是在Kubernetes(Minikube)上使用的案例。

# use Docker on Kubernetes(minikube)
# macからminikube上のdockerにアクセスするために以下コマンドを実行します。
eval $(minikube docker-env)

# create docker image
docker build -t tbuchi888/gobotblue:v1 ./

# check image
docker images

# create k8s service and deploymnet
kubectl create -f k8s/gobotsv.yml --record
kubectl create -f k8s/gobotblue.yml --record

# get url of service on minikube 
# Mattermost側Slash Command登録時にRequestURLとして利用するので控えておきます。
minikube service gobotsv --url

# below mattermost is for testing
# create k8s service and deploymnet
kubectl create -f k8s/mattermost.yml --record

# get url of service on minikube 
# MattermostのURLのため控えておきます。
minikube service mattermostsv --url

在后续的Mattermost(Slack)侧的SlashCommand注册中,将minikube service gobotsv –url的结果设定为RequestURL。
此外,在设置SlashCommand时,使用分配的Token值来更改k8s侧gobotblue deployment的Token值。

kubectl apply -f k8s/gobotblue.yml --record
#️ または以下で直接編集
kubectl edit deployment gobotblue

# 新しいpodsに切り替わることを確認(少し時間がかかります)
kubectl get pods

3.2. 对于Docker的参考资料。

以下是在Dockerfile和main.go所在的目录下构建为tbuchi888/gobotblue:v1镜像,并将其命名为golang-bot容器,在3000端口上运行的示例。请注意,需要事先安装Docker。

docker build -t tbuchi888/gobotblue:v1 ./
docker run --name golang-bot -d -p 3000:3000 -e GOBOTTOKEN=Your_slashcommand_token tbuchi888/gobotblue:v1

3.3. Golang (Reference) – Golang(参考)

以下是一个在具有 main.go 的目录中以3000端口侦听的示例。
*请注意,需要先安装和设置 Golang 环境。

export GOBOTTOKEN="Your_slashcommand_token"
go get -u github.com/favclip/ucon
go install main
./main

4.(参考)Mattermost的设置和执行结果

以下是在Mattermost中设置和执行Slash Command的示例和结果,仅供参考。

matt01.png
matt02.png
matt03.png
matt04.png
matt05.png

将以下内容更改为true,即在“INTEGRATIONS-Custom Integrations”设置中。

    • Enable Custom Slash Commands:

 

    • Enable integrations to override usernames:

 

    Enable integrations to override profile picture icons:

从左上团队名称旁边的菜单(…)中选择切换到团队名称,以退出SystemConsole。

matt06.png
matt07.png

在左上方的菜单中选择Integrations

matt09.png
matt10.png
matt11.png
matt12.png
matt13.png
matt14.png
matt15.png
matt16.png

其他

除了本文中的引用外,我还参考了以下内容。

– https://docs.mattermost.com/developer/slash-commands.html :Mattermost官方文档中有关斜线命令的介绍。
– https://github.com/favclip/ucon :favclip开源项目中的ucon库的GitHub链接。
– Kubernetes 速習会:关于Kubernetes的初学者培训活动。
– Kubernetes: Deployment 的仕組み:详解Kubernetes中的Deployment机制。

广告
将在 10 秒后关闭
bannerAds