我的工作负载需要网络连接才能正常启动,我想使用一个开始的生命周期挂钩,该钩子等待直到准备就绪,然后做某事。但是,生命周期的钩子似乎阻止了CNI。以下工作负载将永远不会分配一个IP:
kubectl apply -f <(cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command:
- "/bin/sh"
- "-c"
- |
while true; do
sleep
done
EOF
)
kubectl get pods -o wide
这意味着我的工作量永远不会开始(试图连接时悬挂)和我的生命周期钩子永远。有没有办法解决这个问题?
编辑:我使用边锋而不是生命周期挂钩来实现同一件事 - 仍然不确定生命周期钩子为什么不起作用,执行CNI是容器创建IMO的一部分,所以我希望我希望生命周期挂钩在网络后射击已配置
这是一个有趣的一个:-)这不是什么答案,但我做了一些调查,我认为我分享了 - 也许是有用的。
我是从问题中发布的yaml开始的。然后,我登录了运行此吊舱并找到容器的机器。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-8f59d655b-ds7x2 0/1 ContainerCreating 0 3m <none> node-x
$ ssh node-x
node-x$ docker ps | grep nginx-8f59d655b-ds7x2
2064320d1562 881bd08c0b08 "nginx -g 'daemon off" 3 minutes ago Up 3 minutes k8s_nginx_nginx-8f59d655b-ds7x2_default_14d1e071-4cd4-11e9-8104-42010af00004_0
2f09063ed20b k8s.gcr.io/pause-amd64:3.1 "/pause" 3 minutes ago Up 3 minutes k8s_POD_nginx-8f59d655b-ds7x2_default_14d1e071-4cd4-11e9-8104-42010af00004_0
运行/pause
的第二个容器是基础架构容器。另一个是POD的NGINX容器。请注意,通常此信息也可以提供kubectl get pod
,但在这种情况下不是。奇怪。
在容器中,我希望已建立网络,并且正在运行NGINX。让我们验证:
node-x$ docker exec -it 2064320d1562 bash
root@nginx-8f59d655b-ds7x2:/# apt update && apt install -y iproute2 procps
...installs correctly...
root@nginx-8f59d655b-ds7x2:/# ip a s eth0
3: eth0@if2136: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UP group default
link/ether 0a:58:0a:f4:00:a9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.244.0.169/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::da:d3ff:feda:1cbe/64 scope link
valid_lft forever preferred_lft forever
因此,建立了网络,路线就位了,ETH0上的IP地址实际上在覆盖网络上。现在查看过程列表:
root@nginx-8f59d655b-ds7x2:/# ps auwx
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 32652 4900 ? Ss 18:56 0:00 nginx: master process nginx -g daemon off;
root 5 5.9 0.0 4276 1332 ? Ss 18:56 0:46 /bin/sh -c while true; do sleep done
nginx 94 0.0 0.0 33108 2520 ? S 18:56 0:00 nginx: worker process
root 13154 0.0 0.0 36632 2824 ? R+ 19:09 0:00 ps auwx
root 24399 0.0 0.0 18176 3212 ? Ss 19:02 0:00 bash
hah,所以nginx正在运行,prestop命令也是如此。但是,请注意大型PID。部署文件中有一个错别字,它正在执行sleep
没有参数 - 这是错误。
root@nginx-8f59d655b-ds7x2:/# sleep
sleep: missing operand
Try 'sleep --help' for more information.
这是从循环中运行的,因此叉车的负载导致大型PID。
作为另一个测试,我也尝试卷曲服务器:
node-x$ curl http://10.244.0.169
...
<p><em>Thank you for using nginx.</em></p>
...
这是非常期待的。所以最后,我想强制PRESTOP命令完成,因此从容器内部我杀死了包含的外壳:
root@nginx-8f59d655b-ds7x2:/# kill -9 5
...container is terminated in a second, result of the preStop hook failure...
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-8f59d655b-ds7x2 0/1 PostStartHookError: rpc error: code = ResourceExhausted desc = grpc: received message larger than max (53423560 vs. 16777216) 0 21m
hm,所以我认为价值50MB(!)的消息是缺少参数到睡眠的失败。实际上,更怪异的是部署没有从此失败中恢复。这个豆荚一直在永远徘徊,而不是您期望的(生成另一个吊舱和重试)。
在这一点上,我删除了部署并用固定在Prestop钩子(sleep 1
)中的睡眠来重新创建了部署。结果大致相同,部署也不会在这种情况下产生另一个豆荚(因此,不仅仅是它在日志上cho住了)。
现在,我确实在顶部说这不是一个真正的答案。但是也许有一些收获:生命周期挂钩需要一些工作才能被认为有用且安全。