2020年9月,Coding Sans 联合其9个合作伙伴,发布了 Serverless 2020 年度状态报告。
这篇报告中有个观点: Debug 是 Serverless 最大的挑战,因为这个是由架构的复杂性引起的。
那么 在 Kubeless 中如何对函数进行 Debug 呢?本文将介绍在函数部署过程函数中可能的错误以及如何 Debug 来定位问题并解决问题。
操作系统:macOS
Kubernetes 版本:v1.15.5
Kubeless 版本:v1.0.7
部署出错的原因可能有很多。要想学习如何成功调试函数,最重要的是要了解部署 Kubeless 函数的过程。
在本文中,我们假设你使用 kubeless CLI 工具部署函数。这种情况下,函数的部署过程如下:
完成上述所有操作后,你就可以调用函数了。让我们看看一些常见的错误以及如何解决它们。
可能出现的第一个错误是我们赋予 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 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。
最常见的错误是发现 Deployment 成功生成了,但函数仍保持状态 0/1 Not ready。这通常是由函数或我们指定的依赖项中的语法错误引起的。
如果我们的函数没有启动,我们应该检查 pod 的状态,命令如下:
$ kubectl get pods -l function=hello
如果我们的函数因为 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 保持该状态的情况下,我们应该检索运行时容器的日志:
$ 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。
在某些情况下,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>'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 频道沟通。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。