Journey of Magnum to Production

Monday 01 October 2018 Magnum, Fedora-Atomic, Cloud-init, Kubernetes

在上一篇Magnum 入坑指南之一Magnum 入坑指南之二里 已经介绍了Magnum的基本安装和使用。这篇文章主要用来记录我们在将Magnum部署到生产环境时所遇到的问题,也好作为今年Berlin Summit的presentation 材料。

到目前为止,我们在上prod/preprod的过程中遇到了两个问题。

anti-affinity policy

这个其实是我去年做的一个feature, 简单来说就是在创建k8s cluster时,将master节点和node节点放到一个server group里,然后设置server group的affinity policy 为soft-anti-affinity或者 anti-affinity, 从而使各个节点在schedule时能够被创建到不同的物理机上,避免node节点拥挤到一个节点上。

但是我们的环境里暂时还不支持soft-anti-affinity, 这个我们实现没有测试到,还好可以直接在Magnum cluster show里面看到所以并没有浪费时间。

Cloud-init 的奇怪问题

接下来,我们遇到了cloud-init的问题。root cause说来也简单,就是我们的preprod太慢了,慢导致了很多问题,只不过各种问题的表象没有看起来那么直观。 回到我们所遇到的问题,Magnum所创建的instance无法注入keypair, 导致无法ssh到instance内debug。当然问题看起来很简单,公钥没有成功注入。接下来我们发现公钥没有注入的原因就是 cloud-init初始化就失败了。不得已,我又专门build了一个带用户名密码的 Fedora Atomic 镜像。重新创建 k8s cluster, 然后登录虚机,查看cloud-init.log 发现问题的根源在于 当 cloud-init 在试图和 Nova的metadata API连接时出现了超时,默认的timeout是5秒钟。通过查阅文档发现,可以通过更改/etc/cloud/cloud.cfg, 更改timeout时间,具体修改如下:

datasource:
OpenStack:
metadata_urls: [ 'http://169.254.169.254:80' ]
dsmode: net
timeout: 50
max_wait: 120


然而,这种方式并不能完全解决问题,具体看下面的log

2018-09-30 09:34:16,875 - handlers.py[DEBUG]: start: init-network/search-OpenStack: searching for network data from DataSourceOpenStack
2018-09-30 09:34:16,875 - __init__.py[DEBUG]: Seeing if we can get any data from <class 'cloudinit.sources.DataSourceOpenStack.DataSourceOpenStack'>
2018-09-30 09:34:16,876 - url_helper.py[DEBUG]: [0/1] open 'http://169.254.169.254:80/openstack' with {'url': 'http://169.254.169.254:80/openstack', 'allow_redirects': True, 'method': 'GET', 'timeout': 50.0, 'headers': {'User-Agent': 'Cloud-Init/0.7.9'}} configuration
2018-09-30 09:34:28,873 - url_helper.py[DEBUG]: Read from http://169.254.169.254:80/openstack (200, 50b) after 1 attempts
2018-09-30 09:34:28,874 - DataSourceOpenStack.py[DEBUG]: Using metadata source: 'http://169.254.169.254:80'
2018-09-30 09:34:28,874 - url_helper.py[DEBUG]: [0/6] open 'http://169.254.169.254:80/openstack' with {'url': 'http://169.254.169.254:80/openstack', 'allow_redirects': True, 'method': 'GET', 'timeout': 5.0, 'headers': {'User-Agent': 'Cloud-Init/0.7.9'}} configuration
2018-09-30 09:34:33,885 - openstack.py[DEBUG]: Unable to read openstack versions from http://169.254.169.254:80 due to: HTTPConnectionPool(host='169.254.169.254', port=80): Read timed out. (read timeout=5.0)
2018-09-30 09:34:33,885 - openstack.py[DEBUG]: Selected version 'latest' from []
2018-09-30 09:34:33,886 - url_helper.py[DEBUG]: [0/6] open 'http://169.254.169.254:80/openstack/latest/meta_data.json' with {'url': 'http://169.254.169.254:80/openstack/latest/meta_data.json', 'allow_redirects': True, 'method': 'GET', 'timeout': 5.0, 'headers': {'User-Agent': 'Cloud-Init/0.7.9'}} configuration
2018-09-30 09:34:38,894 - openstack.py[DEBUG]: Failed reading mandatory path http://169.254.169.254:80/openstack/latest/meta_data.json due to: HTTPConnectionPool(host='169.254.169.254', port=80): Read timed out. (read timeout=5.0)
2018-09-30 09:34:38,894 - util.py[DEBUG]: Crawl of openstack metadata service took 10.020 seconds
2018-09-30 09:34:38,895 - handlers.py[DEBUG]: finish: init-network/search-OpenStack: SUCCESS: no network data found from DataSourceOpenStack


这个timeout 只对第一个request 起了作用,后面的request仍然是按照 5 秒钟作为timeout。我研究到这里的时候已经后半夜两点了,不想再研究只对第一个request 起作用了,所以我决定直接改代码。

然而我发现在 Fedora Atomic, 即使你是root 用户,也是不能直接修改 cloud-init的代码的,这部分代码是只读的。

要修改这部分只读的代码,需要先知道当前deploy的host status, 可以通过如下命令获得:

[fedora@k8s-cluster-1-adbneq5un4ok-master-0 log]$ sudo atomic host status
State: idle
Deployments:
* fedora-atomic:fedora/27/x86_64/atomic-host
Version: 27.81 (2018-02-12 17:50:48)
Commit: b25bde0109441817f912ece57ca1fc39efc60e6cef4a7a23ad9de51b1f36b742
GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4


接下来再通过上面命令得到的commit ID, 通过chroot 命令切换到相应的commit下,这时候就可以读写了。

[root@fedora-atomic-27-x86_64 log]# chroot /sysroot/ostree/deploy/fedora-atomic/deploy/b25bde0109441817f912ece57ca1fc39efc60e6cef4a7a23ad9de51b1f36b742.0/
bash-4.4# vi /usr/lib/python3.6/site-packages/cloudinit/url_helper.py
bash-4.4# exit


未完待续