Kubernetes postStart жизненный цикл крюковых блоков CNI

Моей рабочей нагрузке для правильного запуска требуется сетевое подключение, и я хочу использовать ловушку жизненного цикла postStart, которая ждет, пока она не будет готова, а затем что-то сделает. Однако, крюки жизненного цикла, кажется, блокируют 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 создания контейнера, поэтому я ожидаю, что ловушки жизненного цикла сработают после настройки сети

1 ответ

Это интересный ответ:-) Это не очень хороший ответ, но я провел небольшое исследование и подумал, что могу поделиться им - возможно, он будет полезен.

Я начал с ямла, размещенного в вопросе. Затем я вошел в машину с этим модулем и обнаружил контейнер.

$ 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 является контейнером инфраструктуры. Другой - это контейнер 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

Итак, сеть настроена, маршруты на месте, и IP-адрес на eth0 фактически находится в оверлейной сети, как и должно быть. Глядя на список процессов сейчас:

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 без параметров - что является ошибкой.

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

Хм, так что я представляю, что 50 МБ (!) Сообщений были ошибками из-за отсутствия параметра в спящем режиме. На самом деле, еще более пугающим является то, что развертывание не восстанавливается после этого сбоя. Этот Стручок продолжает зависать вечно, вместо того, что вы ожидаете (порождайте другой Стручок и повторите попытку).

В этот момент я удалил развертывание и воссоздал его с фиксированным сном в хуке preStop (sleep 1). Результаты почти такие же, и в этом случае Deployment не будет порождать еще один Pod (так что дело не только в том, что он захлебнулся в журналах).

Теперь я сказал наверху, что это не совсем ответ. Но, возможно, некоторые выводы: хукам жизненного цикла нужно немного поработать, прежде чем они смогут стать полезными и безопасными.

Другие вопросы по тегам