Kubeless 函数部署遇到了问题,如何 Debug? | 玩转 Kubeless

用户头像
donghui2020
关注
发布于: 2020 年 10 月 14 日
Kubeless  函数部署遇到了问题,如何 Debug? | 玩转 Kubeless

2020年9月,Coding Sans 联合其9个合作伙伴,发布了 Serverless 2020 年度状态报告。

这篇报告中有个观点: Debug 是 Serverless 最大的挑战,因为这个是由架构的复杂性引起的。

那么 在 Kubeless 中如何对函数进行 Debug 呢?本文将介绍在函数部署过程函数中可能的错误以及如何 Debug 来定位问题并解决问题。

 

环境说明

操作系统:macOS

Kubernetes 版本:v1.15.5

Kubeless 版本:v1.0.7

 

了解函数部署过程

部署出错的原因可能有很多。要想学习如何成功调试函数,最重要的是要了解部署 Kubeless 函数的过程。

在本文中,我们假设你使用 kubeless CLI 工具部署函数。这种情况下,函数的部署过程如下:

  1. kubeless CLI 读取你给它的参数,并产生一个函数对象,将它提交给 Kubernetes API 服务器。

  2. Kubeless 函数控制器检测到一个新的 Function 被创建并读取其内容。它从函数中生成这些:一个 ConfigMap 附带函数代码和依赖项,一个 Service 以便可以通过 HTTP访问该函数,一个附带基础镜像的 Deployment ,以及安装和运行函数的所有必须步骤。知道这个顺序非常重要,因为如果控制器无法创建 ConfigMap 或 Service,那么将永远不会创建 Deployment。任何步骤失败都会终止该过程。

  3. 一旦 Deployment 创建了一个你函数生成的 Pod,Pod 启动的时候会动态读取函数内容(在解析型语言的情况下)。



完成上述所有操作后,你就可以调用函数了。让我们看看一些常见的错误以及如何解决它们。

"kubeless function deploy" 失败

可能出现的第一个错误是我们赋予 kubeless function deploy 命令的参数错误。这些错误很容易 debug:

$ kubeless function deploy --runtime python2 --from-file test.py --handler test.hello hello
FATA[0000] Invalid runtime: python2. Supported runtimes are: ballerina0.981.0, dotnetcore2.0, dotnetcore2.1, dotnetcore2.2, dotnetcore3.1, go1.13, go1.14, java1.8, java11, nodejs6, nodejs8, nodejs10, nodejs12, php7.2, php7.3, python2.7, python3.4, python3.6, python3.7, ruby2.3, ruby2.4, ruby2.5, ruby2.6, jvm1.8, nodejs_distroless8, nodejsCE8, vertx1.8

从上面的报错日志中我们可以看出 runtime 参数不对,应该将 python2 改为 python2.7。

"kubeless function ls" 返回 "MISSING: Check controller logs”

在某些情况下,在 CLI 中进行的验证不足以发现给定参数中的问题。如果是这种情况,该函数 Deployment 将永远不会出现。要 debug 此类问题,必须检查控制器日志中的错误是什么。要检索这些日志,请执行:

$ kubeless function deploy hello --runtime python2.7 --from-file test.py --handler test,hello
INFO[0000] Deploying function...                        
INFO[0000] Function hello submitted for deployment      
INFO[0000] Check the deployment status executing 'kubeless function ls hello'
donghuideMBP:kubeless_demo donghui$ kubeless function ls hello
NAME     NAMESPACE    HANDLER       RUNTIME      DEPENDENCIES    STATUS                        
hello    default      test,hello    python2.7                    MISSING: Check controller logs
$  kubectl logs -n kubeless -l kubeless=controller
Error from server (BadRequest): a container name must be specified for pod kubeless-controller-manager-cd68f56c4-cjbnz, choose one of: [kubeless-function-controller http-trigger-controller cronjob-trigger-controller]
$ kubectl logs -n kubeless -l kubeless=controller -c kubeless-function-controller
time="2020-10-01T01:38:42Z" level=info msg="Processing change to Function default/hello" pkg=function-controller
time="2020-10-01T01:38:42Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller

从日志中我们可以看到 handler 参数存在问题:我们应该将 test,hello 修改为 test.hello。



函数 pod crash

最常见的错误是发现 Deployment 成功生成了,但函数仍保持状态 0/1 Not ready。这通常是由函数或我们指定的依赖项中的语法错误引起的。

如果我们的函数没有启动,我们应该检查 pod 的状态,命令如下:

$ kubectl get pods -l function=hello

 

函数 pod crash 之  Init:CrashLoopBackOff

如果我们的函数因为 Init 错误而失败,则可能意味着:

  • 它无法检索函数内容

  • 它无法安装依赖项

  • 它无法编译我们的函数(使用编译型语言)



对于上述任何一种情况,我们应该首先确定哪个容器失败了(因为每个步骤都在不同的容器中执行):

$ kubectl get pods -l function=hello
NAME                    READY   STATUS                  RESTARTS   AGE
hello-b46455654-v2bs9   0/1     Init:CrashLoopBackOff   5          5m2s
$ kubectl get pods -l function=hello -o yaml
...
      name: install
      ready: false
      restartCount: 5
...      

从上面我们可以看到,容器 install 就是有问题的容器。根据运行时间,还将显示容器的日志,因此我们可以直接发现问题。不幸的是,事实并非如此,因此让我们手动检索 install 容器的日志:

$ kubectl logs hello-b46455654-v2bs9 -c install --previous
/kubeless/requirements.txt: OK
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
WARNING: The directory '/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
ERROR: Could not find a version that satisfies the requirement jenkinsapi-2020 (from -r /kubeless/requirements.txt (line 1)) (from versions: none)
ERROR: No matching distribution found for jenkinsapi-2020 (from -r /kubeless/requirements.txt (line 1))
WARNING: You are using pip version 20.0.2; however, version 20.2.3 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.

现在我们可以发现问题是我们 requirements.txt 中模块名不对,应该将 jenkinsapi-2020 改为 jenkinsapi。

函数 pod crash 之  CrashLoopBackOff

在 Pod 保持该状态的情况下,我们应该检索运行时容器的日志:

$ kubectl logs -l function=hello
Traceback (most recent call last):
  File "/kubeless.py", line 17, in <module>
    '/kubeless/%s.py' % os.getenv('MOD_NAME'))
  File "/kubeless/test.py", line 1
    import requests123
                   ^
SyntaxError: invalid syntax

我们可以看到我们有一个语法错误:import requests123,应该修改为:import requests。

函数返回 "Internal Server Error”

在某些情况下,pod 不会 crash,但是函数返回错误:

$ kubectl get pods -l function=hello
NAME READY STATUS RESTARTS AGE
hello-c6946586b-thb8b 1/1 Running 0 29s
$ kubeless function call hello --data '{"username": "test"}'
ERRO[0000]
FATA[0000] an error on the server ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<html>
<head>
<title>Error: 500 Internal Server Error</title>
<style type=\"text/css\">
html {background-color: #eee; font-family: sans;}
body {background-color: #fff; border: 1px solid #ddd;
padding: 15px; margin: 15px;}
pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
</style>
</head>
<body>
<h1>Error: 500 Internal Server Error</h1>
<p>Sorry, the requested URL <tt>&#039;http://kubernetes.docker.internal:6443/'</tt>
caused an error:</p>
<pre>Internal Server Error</pre>
</body>
</html>") has prevented the request from succeeding



这通常意味着该函数在语法上是正确的,但存在错误。再次检查问题,我们应该检查函数日志:

$ kubectl logs -l function=hello
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 862, in _handle
return route.call(**args)
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 1740, in wrapper
rv = callback(*a, **ka)
File "/kubeless.py", line 91, in handler
raise res
KeyError: 'user'
{'event-time': '2020-10-01T03:04:27Z', 'extensions': {'request': <LocalRequest: POST http://kubernetes.docker.internal:6443/>}, 'event-type': 'application/json', 'event-namespace': 'cli.kubeless.io', 'data': {u'username': u'test'}, 'event-id': 'fltxfHu2hF5M2TQ'}
10.1.0.1 - - [01/Oct/2020:03:04:27 +0000] "POST / HTTP/1.1" 500 758 "" "kubeless/v0.0.0 (darwin/amd64) kubernetes/$Format" 0/23723
10.1.0.1 - - [01/Oct/2020:03:04:57 +0000] "GET /healthz HTTP/1.1" 200 2 "" "kube-probe/1.15" 0/142

 

查看引起错误的函数代码:

def hello(event, context):
print event
return event['data']['user']['name'];

这里将 event['data']['user']['name'] 改为 event['data']['username']  即可。

结论

上面这些是一些可以快速定位函数出了什么问题的技巧。如果检查控制器和函数日志(或任何其他 Kubernetes 可提供的信息)后,不能够发现错误,可以去 github 仓库提 issue 或在官方 slack 频道沟通。

参考

https://kubeless.io/docs/debug-functions/

 



发布于: 2020 年 10 月 14 日 阅读数: 12
用户头像

donghui2020

关注

还未添加个人签名 2018.01.01 加入

还未添加个人简介

评论

发布
暂无评论
Kubeless  函数部署遇到了问题,如何 Debug? | 玩转 Kubeless