我正在使用Kubernetes v1.2.4 (在CoreOS稳定的1010.5.0之上),并希望挂载rbd/ceph卷。基本上,我遵循了https://github.com/kubernetes/kubernetes/tree/master/examples/rbd,只是我更喜欢YAML而不是JSON。
注意到两者都有:
secretRef:
name: ceph-secret和
keyring: /etc/ceph/keyring否则库贝克尔就抱怨。这是预期的行为吗?
似乎kubelet试图在主机上直接调用rbd二进制文件(这对于CoreOS这样的“裸系统”来说是个问题)。由于对二进制文件和依赖项的复制有点麻烦,所以我做了这个技巧:
$ cat /opt/bin/rbd
#!/bin/sh
docker run -v /etc/ceph:/etc/ceph ceph/rbd $@负责/etc/ceph配置,使shell脚本可执行等等--如果我在CoreOS上执行"rbd list“,一切都很好。/opt/bin (默认情况下位于CoreOS上的路径上)也位于kubelet进程的路径中(我可以通过/proc/kubelet /environ确认该路径)。
但是,如果启动(测试)结束符,就会得到这个错误(在kubectl描述中):
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
5s 5s 1 {default-scheduler } Normal Scheduled Successfully assigned busybox4 to some-host
4s 4s 1 {kubelet some-host} Warning FailedMount Unable to mount volumes for pod "busybox4_default(5386c7f3-3959-11e6-a768-aa00009a7832)": rbd: map failed fork/exec /opt/bin/rbd: invalid argument
4s 4s 1 {kubelet some-host} Warning FailedSync Error syncing pod, skipping: rbd: map failed fork/exec /opt/bin/rbd: invalid argument那么,叉子()还是execve()返回EINVAL?通过阅读几个手册页,我发现只有EINVAL的执行人员可能会因为以下原因而失败
An ELF executable had more than one PT_INTERP segment (i.e., tried to name more than one interpreter)但这似乎很模糊。
你知道是怎么回事吗?或者我怎么解决这个问题?
编辑:我尝试了strace -fp pid,并且有很多stat()调用,我认为这些调用来自golang /exec LookPath。但是,我没有看到任何关于"rbd“的execve(),也没有任何系统调用在EINVAL中失败。为了确保它与舰队(systemd)无关,我还尝试将kubelet直接作为root在控制台上运行。结果是一样的。
发布于 2016-06-30 23:59:15
我不太熟悉kubernetes如何启动这个rbd脚本,但我认为问题在于它是一个脚本。一个脚本不能通过调用exec直接运行,kubernetes正在这样做。
文件顶部的行#!/bin/sh不会自动为您启动shell。实际上是由另一个外壳解释的。因此,您真正想要的不是在kubernetes配置中直接调用脚本/opt/bin/rbd。您想要将其更改为:
/bin/sh -c "/opt/bin/rbd“
然后它就能起作用了。
实际上,我会稍微修改一下脚本
#!/bin/sh
exec docker run -v /etc/ceph:/etc/ceph ceph/rbd $@但也许你真正想做的是看看这个指南:
在kubernetes上使用krbd为您的容器带来持久存储
事情已经进展了。
发布于 2016-07-02 19:17:48
部分回答: rbd是一个shell脚本并不重要。通过查看kubelet在调用其他外部工具时的strace输出,我发现使用了克隆()。我编写了一些简短的测试代码来验证失败时会发生什么。
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
int test(void *p) {
printf("Hello there!");
return 0;
}
int main() {
if (clone(test, NULL, CLONE_THREAD, NULL) == -1) {
perror("clone");
}
return 0;
}现在如果我做了
strace ./test 2>&1 | grep clone输出是
write(2, "clone: Invalid argument\n", 24clone: Invalid argument这就解释了这个谜团的一部分。当()在EINVAL strace中失败时,根本不显示它.
然后我一直在看库伯奈特的消息来源
好像很有魅力
[pid 25039] execve("/usr/sbin/modprobe", ["modprobe", "rbd"], [/* 4 vars */] <unfinished ...>不知道为什么util.go#L231或util.go#L234的调用不会失败(特别是什么会使那里的克隆()调用失败)
发布于 2016-08-27 10:24:05
只是跟进这个问题。
同时,我用Kubernetes v1.3.5升级到了CoreOS稳定版(1068.9.0)。
我的/opt/bin/rbd如下所示:
#!/bin/sh
exec docker run -v /dev:/dev -v /sys:/sys --net=host --privileged=true -v /etc/ceph:/etc/ceph ceph/rbd $@(部分是基于你的建议)。现在一切都像魅力一样运作。所以我想是一些bug被修复了( secretRef和keyring现在也不再需要了,不再需要kubectl)。也许有人可以对实际问题发表评论,但其他人则认为案件已经结案。
https://stackoverflow.com/questions/37996983
复制相似问题