WRY

Where Are You?
You are on the brave land,
To experience, to remember...

0%

在集群中调试Fission 源代码

本文介绍

为了寻找Fission的mqtrigger组件发生bug的原因,需要我们能在集群中运行Fission的源代码进行debug,寻找bug发生的原因。此篇文章将会记录,如何运行起Fission的源代码并且将运行环境迁移到集群中,与Fission的其他组件协同工作。

环境搭建

下载源码 & 依赖

Fission的源码地址或者这里,依赖的环境都在go.mod文件中。值得注意的是其中的一个依赖是k8s.io/client-go v12.0.0+incompatible最高使用的go语言版本是v12,所以在Goland里面需要先配置兼容的Go解释器版本。整个项目结构参考了之前改Portainer时的结构,下图是GO目录下src文件夹的内容,通过这种文件组织形式,只需要指定Go的GLOBAL GOPATH就可以正确配置整个项目。

image-20200605200843038

下载依赖:

1
2
3
$ export GO111MODULE=on
$ export GOPROXY=https://goproxy.io # 配置代理
$ go mod download

vscode remote ssh

在Extension中选择安装Go的工具包,注意要安装在远程的环境中。

image-20200620211117616

在国内会因为网络的问题,无法在服务端自动完成go的工具环境配置,需要手动进行配置,也可以在~/.bashrc 中配置代理,vscode也可以完成安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# GOROOT 和GOPATH 需要正确的配置
export GOROOT=~/go/go-1.12.17
export GOPATH=~/go
# 配置下载代理,否则下载很有可能会失败
export GO111MODULE=on
export GOPROXY=https://goproxy.io # 配置代理
# 上述配置可以写在 ~/.bashrc中,vscode也可以自动下载
################################################
# 下载工具包
go get -v github.com/mdempsky/gocode
go get -v github.com/uudashr/gopkgs/v2/cmd/gopkgs
go get -v github.com/ramya-rao-a/go-outline
go get -v -d github.com/stamblerre/gocode
go get -v github.com/rogpeppe/godef
go get -v github.com/sqs/goreturns
go get -v golang.org/x/lint/golint
go get -v github.com/go-delve/delve/cmd/dlv
# 安装工具包
go install github.com/mdempsky/gocode
go install github.com/uudashr/gopkgs/v2/cmd/gopkgs
go install github.com/ramya-rao-a/go-outline
go install github.com/stamblerre/gocode
go install github.com/rogpeppe/godef
go install github.com/sqs/goreturns
go install golang.org/x/lint/golint
go install github.com/go-delve/delve/cmd/dlv

配置文件目前还是存在问题,因为实际上使用的是Octeto集群调试环境。这个以后有需求再修改完善。

配置文件已修改完善,主要是args部分的书写方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "start from a file",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${file}",
"env": {
"GOPROXY": "https://goproxy.io",
"GO111MODULE": "on"
},
"args": [
"--mqt",
"--routerUrl",
"http://func.fission.huxiang.pro"
]
}
]
}

Okteto 集群调试环境

  • 第一个问题:Okteto暂时不支持指定的serviceAccount(2020.06.18),有人提过issue,希望Okteto尽快支持。此处使用Fission第二种授权获取k8s资源的方式:定义KUBECONFIG环境变量指向k8s的配置文件。

  • Okteto使用私有仓库中镜像的方式

  • Okteto 配置文件(此处调试的是mqtrigger的Kafka组件)okteto.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    name: dev-jingtao-fission-bundle
    image: golang:1.12-alpine # 可以使用私有定制好环境的镜像
    workdir: /go/src/github.com/fission/fission
    volumes:
    environment:
    - TRACING_SAMPLING_RATE=0.5
    - MESSAGE_QUEUE_URL=kafka-dev.kafka-dev:9092
    - MESSAGE_QUEUE_TYPE=kafka
    - MESSAGE_QUEUE_KAFKA_VERSION=5.0.1
    - DEBUG_ENV=true
    securityContext:
    capabilities:
    add:
    - SYS_PTRACE

  • 启动脚本 init.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/usr/bin/env sh
    set -eux
    set -o pipefail
    # -u 表示遇到不存在的变量的时候,报错
    # -e 只要脚本有错误,就终止执行
    # -x 表示执行命令之前,先输出执行的命令
    # -o pipefail 只要一个子命令失败,整个管道命令就失败,脚本就会终止执行

    # 预装环境,这些步骤可以放到定制的镜像中去完成
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
    apk add git gcc g++ curl

    # 配置go mod
    export GO111MODULE=on
    export GOPROXY=https://goproxy.io
    export KUBECONFIG=$(pwd)/kubectl-config # 连接k8s的配置文件

    # 下载依赖
    go mod download

    # 运行代码
    go run -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH \
    cmd/fission-bundle/main.go --mqt --routerUrl http://func.fission.huxiang.pro
  • 开始调试

    1
    2
    $ okteto up -n fission
    /go/src/github.com/fission/fission $ ./init.sh

调试结果

打印http请求的返回具体结果,错误码: 400,错误详情如下

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>SyntaxError: Unexpected token a in JSON at position 4<br> &nbsp; &nbsp;at JSON.parse (&lt;anonymous&gt;)<br> &nbsp; &nbsp;at createStrictSyntaxError (/usr/src/app/node_modules/body-parser/lib/types/json.js:158:10)<br> &nbsp; &nbsp;at parse (/usr/src/app/node_modules/body-parser/lib/types/json.js:83:15)<br> &nbsp; &nbsp;at /usr/src/app/node_modules/body-parser/lib/read.js:121:18<br> &nbsp; &nbsp;at invokeCallback (/usr/src/app/node_modules/raw-body/index.js:224:16)<br> &nbsp; &nbsp;at done (/usr/src/app/node_modules/raw-body/index.js:213:7)<br> &nbsp; &nbsp;at IncomingMessage.onEnd (/usr/src/app/node_modules/raw-body/index.js:273:7)<br> &nbsp; &nbsp;at emitNone (events.js:111:20)<br> &nbsp; &nbsp;at IncomingMessage.emit (events.js:208:7)<br> &nbsp; &nbsp;at endReadableNT (_stream_readable.js:1064:12)</pre>
</body>
</html>

通过检索,发现错误原因是请求的内容不合法,再具体对比自己的测试时和消息队列中的内容,发现队列中的消息都是随意的字符,自己请求的内容都是json结构的,修改了队列的输入之后,整个流程正常。

至于我为什么给队列和直接函数调用的内容不同,emmmmm,本人不想解释,太蠢了。

后续

之后的fission组件的调试开发,转到了Goland+minikube+kt-connect的方式进行。部署脚本参考

追加一下Goland本地调试时使用的环境变量

1
KUBECONFIG=/home/jingtao/.kube/config;http_proxy=socks5://127.0.0.1:2223