首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kubernetes postStart生命周期钩子阻止CNI

Kubernetes postStart生命周期钩子阻止CNI
EN

Stack Overflow用户
提问于 2019-03-22 19:09:39
回答 1查看 2.6K关注 0票数 2

我的工作负载需要网络连接才能正常启动,我想使用一个postStart lifecycle hook,它等到准备就绪后再执行某些操作。但是,生命周期挂钩似乎会阻止CNI;永远不会为以下工作负载分配IP:

代码语言:javascript
复制
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

这意味着我的工作负载永远不会开始(在尝试连接时挂起),而我的生命周期钩子将永远循环。有没有办法解决这个问题?

编辑:我使用了sidecar而不是生命周期钩子来实现同样的事情-尽管我仍然不确定为什么生命周期钩子不能工作,执行CNI是容器创建的一部分,所以我希望生命周期钩子会在网络配置完成后触发

EN

回答 1

Stack Overflow用户

发布于 2019-03-23 03:29:51

这是一个有趣的问题:-)这不是一个很好的答案,但我做了一些调查,我想我分享了它--也许它是有用的。

我从问题中发布的yaml开始。然后,我登录到运行此pod的机器并找到容器。

代码语言:javascript
复制
$ 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正在运行。让我们验证一下:

代码语言:javascript
复制
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地址实际上是在重叠网络上,因为它应该是这样的。现在查看进程列表:

代码语言:javascript
复制
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

哈,所以nginx正在运行,preStop命令也在运行。但是,请注意较大的PID。部署文件中有一个拼写错误,它在没有参数的情况下执行sleep -这是一个错误。

代码语言:javascript
复制
root@nginx-8f59d655b-ds7x2:/# sleep
sleep: missing operand
Try 'sleep --help' for more information.

这是从循环运行的,因此分叉的负载导致较大的PID。

作为另一个测试,我还尝试从一个节点卷曲服务器:

代码语言:javascript
复制
node-x$ curl http://10.244.0.169
...
<p><em>Thank you for using nginx.</em></p>
...

这是非常令人期待的。所以最后,我想强制preStop命令结束,这样我就可以从容器内部杀死包含外壳:

代码语言:javascript
复制
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

嗯,所以我想象50MB (!)有价值的消息是从丢失的参数到睡眠的失败。实际上,更可怕的是部署没有从这次故障中恢复过来。这个Pod将永远挂起,而不是您所期望的(生成另一个Pod并重试)。

此时,我删除了部署,并使用preStop挂钩(sleep 1)中修复的休眠重新创建了它。结果大同小异,在这种情况下,部署也不会产生另一个Pod (所以不仅仅是因为它被日志卡住了)。

我在上面确实说过,这并不是一个真正的答案。但是也许有一些结论:生命周期钩子需要一些工作才能被认为是有用和安全的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55298354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档