Kubernetes postStart жизненный цикл крюковых блоков CNI - PullRequest
1 голос
/ 22 марта 2019

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

1 голос
/ 22 марта 2019

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

Я начал с 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 является контейнером инфраструктуры.Другой - контейнер 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 МБ (!) Были ошибками отнедостающий параметр для сна.На самом деле, еще более пугающим является то, что развертывание не восстанавливается после этого сбоя.Этот Pod продолжает зависать вечно, вместо того, что вы ожидаете (создать другой Pod и повторить попытку).

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

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

...