Kubernetes: configurações ignoradas de tempo limite de remoção de pods

Criado em 27 fev. 2019  ·  15Comentários  ·  Fonte: kubernetes/kubernetes

Use este modelo ao relatar um bug e forneça o máximo de informações possível. Não fazer isso pode resultar em seu bug não ser corrigido em tempo hábil. Obrigado! Se o assunto for relacionado à segurança, divulgue-o em particular via https://kubernetes.io/security/

O que aconteceu : eu modifiquei as configurações pod-eviction-timeout do gerenciador do controlador do kube no nó mestre (a fim de diminuir a quantidade de tempo antes que o k8s recrie um pod em caso de falha do nó). O valor padrão é 5 minutos, configurei 30 segundos. Usando o comando sudo docker ps --no-trunc | grep "kube-controller-manager" , verifiquei se a modificação foi aplicada com sucesso:

kubeadmin<strong i="10">@nodetest21</strong>:~$ sudo docker ps --no-trunc | grep "kube-controller-manager"
387261c61ee9cebce50de2540e90b89e2bc710b4126a0c066ef41f0a1fb7cf38   sha256:0482f640093306a4de7073fde478cf3ca877b6fcc2c4957624dddb2d304daef5                         "kube-controller-manager --address=127.0.0.1 --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf --client-ca-file=/etc/kubernetes/pki/ca.crt --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt --cluster-signing-key-file=/etc/kubernetes/pki/ca.key --controllers=*,bootstrapsigner,tokencleaner --kubeconfig=/etc/kubernetes/controller-manager.conf --leader-elect=true --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --root-ca-file=/etc/kubernetes/pki/ca.crt --service-account-private-key-file=/etc/kubernetes/pki/sa.key --use-service-account-credentials=true --pod-eviction-timeout=30s" 

Eu apliquei uma implantação básica com duas réplicas:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - image: busybox
        command:
        - sleep
        - "3600"
        imagePullPolicy: IfNotPresent
        name: busybox
      restartPolicy: Always

O primeiro pod criado no primeiro nó de trabalho, o segundo pod criado no segundo nó de trabalho:

NAME         STATUS   ROLES    AGE   VERSION
nodetest21   Ready    master   34m   v1.13.3
nodetest22   Ready    <none>   31m   v1.13.3
nodetest23   Ready    <none>   30m   v1.13.3

NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE   IP          NODE         NOMINATED NODE   READINESS GATES
default       busybox-74b487c57b-5s6g7             1/1     Running   0          13s   10.44.0.2   nodetest22   <none>           <none>
default       busybox-74b487c57b-6zdvv             1/1     Running   0          13s   10.36.0.1   nodetest23   <none>           <none>
kube-system   coredns-86c58d9df4-gmcjd             1/1     Running   0          34m   10.32.0.2   nodetest21   <none>           <none>
kube-system   coredns-86c58d9df4-wpffr             1/1     Running   0          34m   10.32.0.3   nodetest21   <none>           <none>
kube-system   etcd-nodetest21                      1/1     Running   0          33m   10.0.1.4    nodetest21   <none>           <none>
kube-system   kube-apiserver-nodetest21            1/1     Running   0          33m   10.0.1.4    nodetest21   <none>           <none>
kube-system   kube-controller-manager-nodetest21   1/1     Running   0          20m   10.0.1.4    nodetest21   <none>           <none>
kube-system   kube-proxy-6mcn8                     1/1     Running   1          31m   10.0.1.5    nodetest22   <none>           <none>
kube-system   kube-proxy-dhdqj                     1/1     Running   0          30m   10.0.1.6    nodetest23   <none>           <none>
kube-system   kube-proxy-vqjg8                     1/1     Running   0          34m   10.0.1.4    nodetest21   <none>           <none>
kube-system   kube-scheduler-nodetest21            1/1     Running   1          33m   10.0.1.4    nodetest21   <none>           <none>
kube-system   weave-net-9qls7                      2/2     Running   3          31m   10.0.1.5    nodetest22   <none>           <none>
kube-system   weave-net-h2cb6                      2/2     Running   0          33m   10.0.1.4    nodetest21   <none>           <none>
kube-system   weave-net-vkb62                      2/2     Running   0          30m   10.0.1.6    nodetest23   <none>           <none>

Para testar o despejo de pod correto, desliguei o primeiro nó de trabalho. Após cerca de 1 minuto, o status do primeiro nó de trabalho mudou para "NotReady", então
Tive que esperar +5 minutos (que é o tempo limite de remoção do pod padrão) para que o pod no nó desligado fosse recriado no outro nó.

O que você esperava que acontecesse :
Depois que o status do nó relatar "NotReady", o pod deve ser recriado no outro nó após 30 segundos, em vez de 5 minutos padrão!

Como reproduzi-lo (o mínimo e precisamente possível) :
Crie três nós. Inicie o Kubernetes no primeiro nó ( sudo kubeadm init ), aplique o plug-in de rede ( kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" ) e junte os outros dois nós (como: kubeadm join 10.0.1.4:6443 --token xdx9y1.z7jc0j7c8g8lpjog --discovery-token-ca-cert-hash sha256:04ae8388f607755c14eed702a23fd47802d5512e092b08add57040a2ae0736ac ).
Adicione o parâmetro pod-eviction-timeout ao Kube Controller Manager no nó mestre: sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml :

apiVersion: v1
kind: Pod
metadata:
  annotations:
    scheduler.alpha.kubernetes.io/critical-pod: ""
  creationTimestamp: null
  labels:
    component: kube-controller-manager
    tier: control-plane
  name: kube-controller-manager
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-controller-manager
    - --address=127.0.0.1
    - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
    - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
    - --controllers=*,bootstrapsigner,tokencleaner
    - --kubeconfig=/etc/kubernetes/controller-manager.conf
    - --leader-elect=true
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --root-ca-file=/etc/kubernetes/pki/ca.crt
    - --service-account-private-key-file=/etc/kubernetes/pki/sa.key
    - --use-service-account-credentials=true
    - --pod-eviction-timeout=30s

(o yaml é truncado, apenas a primeira parte relacionada é mostrada aqui).

Verifique se as configurações foram aplicadas:
sudo docker ps --no-trunc | grep "kube-controller-manager"

Aplique uma implantação com duas réplicas, verifique se um pod é criado no primeiro nó de trabalho e o segundo é criado no segundo nó de trabalho.
Desligue um dos nós e verifique o tempo decorrido entre o evento, quando o nó relata "NotReady" e o pod é recriado.

Mais alguma coisa que precisamos saber? :
Eu experimento o mesmo problema no ambiente multi-master também.

Meio Ambiente :

  • Versão do Kubernetes (use kubectl version ): v1.13.3
    Versão do cliente: version.Info {Major: "1", Minor: "13", GitVersion: "v1.13.3", GitCommit: "721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState: "clean", BuildDate: "2019-02-01T20: 08: 12Z ", GoVersion:" go1.11.5 ", Compilador:" gc ", Plataforma:" linux / amd64 "}
    Versão do servidor: version.Info {Major: "1", Minor: "13", GitVersion: "v1.13.3", GitCommit: "721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState: "clean", BuildDate: "2019-02-01T20: 00: 57Z ", GoVersion:" go1.11.5 ", Compilador:" gc ", Plataforma:" linux / amd64 "}
  • Provedor de nuvem ou configuração de hardware: VM do Azure
  • SO (por exemplo: cat /etc/os-release ): NAME = "Ubuntu" VERSION = "16.04.5 LTS (Xenial Xerus)"
  • Kernel (por exemplo, uname -a ): Linux nodetest21 4.15.0-1037-azure # 39 ~ 16.04.1-Ubuntu SMP Ter 15 de janeiro 17:20:47 UTC 2019 x86_64 x86_64 x86_64 GNU / Linux
  • Ferramentas de instalação:
  • Outros: Docker v18.06.1-ce
kinbug siapps sinode

Comentários muito úteis

Obrigado pelo seu feedback ChiefAlexander!
Essa é a situação, você escreveu. Eu verifiquei os pods e certifique-se de que existem os valores padrão atribuídos ao pod para tolerância:

kubectl describe pod busybox-74b487c57b-95b6n | grep -i toleration -A 2
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s

Então, simplesmente adicionei meus próprios valores à implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      tolerations:
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 2
      - key: "node.kubernetes.io/not-ready"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 2
      containers:
      - image: busybox
        command:
        - sleep
        - "3600"
        imagePullPolicy: IfNotPresent
        name: busybox
      restartPolicy: Always

Depois de aplicar a implantação em caso de falha do nó, o status do nó muda para "NotReady" e os pods são recriados após 2 segundos.

Assim, não temos mais que lidar com o tempo limite de evicção do pod, o tempo limite pode ser definido com base no pod! Legal!

Obrigado novamente por sua ajuda!

Todos 15 comentários

@ kubernetes / sig-node-bugs
@ kubernetes / sig-apps-bugs

@danielloczi : Reiterando as menções para acionar uma notificação:
@ kubernetes / sig-node-bugs, @ kubernetes / sig-apps-bugs

Em resposta a isso :

@ kubernetes / sig-node-bugs
@ kubernetes / sig-apps-bugs

Instruções para interagir comigo usando comentários de RP estão disponíveis aqui . Se você tiver dúvidas ou sugestões relacionadas ao meu comportamento, registre um problema no repositório kubernetes / test-infra .

Eu também encontrei esse problema ao testar a configuração do tempo limite de despejo mais baixo. Depois de mexer nisso por algum tempo, descobri que a causa é o novo TaintBasedEvictions.

Na versão 1.13, o recurso TaintBasedEvictions é promovido a beta e habilitado por padrão, portanto, os taints são adicionados automaticamente pelo NodeController (ou kubelet) e a lógica normal para expulsar pods de nós com base no Ready NodeCondition é desabilitada.

Definir o sinalizador de recurso para false faz com que os pods sejam despejados como esperado. Não parei para pesquisar o código de despejo baseado em contaminação, mas acho que não estamos utilizando este sinalizador de tempo limite de despejo nele.

Olhando mais para isso. Com TaintBasedEvictions definido como true, você pode definir o tempo de despejo de seus pods dentro de suas especificações sob tolerâncias:
https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/#taint -based-evictions
Os valores padrão deles estão sendo definidos por um controlador de admissão: https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/defaulttolerationseconds/admission.go#L34
Essas duas bandeiras podem ser definidas por meio do kube-apiserver e devem obter o mesmo efeito.

// Controller will not proactively sync node health, but will monitor node
// health signal updated from kubelet. There are 2 kinds of node healthiness
// signals: NodeStatus and NodeLease. NodeLease signal is generated only when
// NodeLease feature is enabled. If it doesn't receive update for this amount
// of time, it will start posting "NodeReady==ConditionUnknown". The amount of
// time before which Controller start evicting pods is controlled via flag
// 'pod-eviction-timeout'.
// Note: be cautious when changing the constant, it must work with
// nodeStatusUpdateFrequency in kubelet and renewInterval in NodeLease
// controller. The node health signal update frequency is the minimal of the
// two.
// There are several constraints:
// 1. nodeMonitorGracePeriod must be N times more than  the node health signal
//    update frequency, where N means number of retries allowed for kubelet to
//    post node status/lease. It is pointless to make nodeMonitorGracePeriod
//    be less than the node health signal update frequency, since there will
//    only be fresh values from Kubelet at an interval of node health signal
//    update frequency. The constant must be less than podEvictionTimeout.
// 2. nodeMonitorGracePeriod can't be too large for user experience - larger
//    value takes longer for user to see up-to-date node health.

Obrigado pelo seu feedback ChiefAlexander!
Essa é a situação, você escreveu. Eu verifiquei os pods e certifique-se de que existem os valores padrão atribuídos ao pod para tolerância:

kubectl describe pod busybox-74b487c57b-95b6n | grep -i toleration -A 2
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s

Então, simplesmente adicionei meus próprios valores à implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      tolerations:
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 2
      - key: "node.kubernetes.io/not-ready"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 2
      containers:
      - image: busybox
        command:
        - sleep
        - "3600"
        imagePullPolicy: IfNotPresent
        name: busybox
      restartPolicy: Always

Depois de aplicar a implantação em caso de falha do nó, o status do nó muda para "NotReady" e os pods são recriados após 2 segundos.

Assim, não temos mais que lidar com o tempo limite de evicção do pod, o tempo limite pode ser definido com base no pod! Legal!

Obrigado novamente por sua ajuda!

@danielloczi Olá danielloczi, Como você corrige esse problema? Eu também encontro esse problema

@ 323929 Acho que @danielloczi não se preocupa com o parâmetro pod-eviction-timeout no gerenciador de controle do kube, mas resolve usando Taint based Evictions , testei com Taint based Evictions , funcionou para mim.

Isso mesmo: eu simplesmente comecei a usar Taint based Eviction .

É possível torná-lo global? Não quero habilitar isso para cada configuração de pod, especialmente porque uso muitas coisas preparadas do helm

+1 por ter a possibilidade de configurá-lo por cluster inteiro. o ajuste por pod ou por implantação raramente é útil: na maioria dos casos, um valor global lógico é muuuito mais conveniente e o padrão atual de 5m é muuuuito longo para muitos casos.

por favor, reabra este problema.

Estou enfrentando o mesmo problema. Existe uma maneira de não habilitar Despejos baseados em Taint e que o tempo limite de eviction de pod funciona em modo global?

Estou enfrentando o mesmo problema. Existe uma maneira de não habilitar Despejos baseados em Taint e que o tempo limite de eviction de pod funciona em modo global?

Acho que você pode configurar o despejo global de pod via apiserver: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
Eu não tentei isso, mas como posso ver, existem opções: --default-not-ready-toleration-seconds e --default-unreachable-toleration-seconds.

Por que esse bug foi marcado como fechado? Parece que o problema original não foi resolvido, mas apenas contornado.
Não está claro para mim por que o sinalizador pod-eviction-timeout não está funcionando

o mesmo problema

Esta página foi útil?
0 / 5 - 0 avaliações