Kubernetes: a exclusão do namespace travou no estado "Terminando"

Criado em 5 mar. 2018  ·  180Comentários  ·  Fonte: kubernetes/kubernetes

Estou usando a v1.8.4 e estou tendo o problema de que o namespace excluído permanece no estado "Terminando" para sempre. Eu já fiz "kubectl delete namespace XXXX".

kinbug prioritimportant-soon siapi-machinery

Comentários muito úteis

@ManifoldFR , tive o mesmo problema que o seu e consegui fazer funcionar fazendo uma chamada de API com arquivo json.
kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
em seguida, edite tmp.json e remova "kubernetes"

curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize

e deve excluir seu namespace,

Todos 180 comentários

/ sig api-machines

@ shean-guangchang Você tem alguma maneira de reproduzir isso?

E por curiosidade, você está usando algum CRD? Já enfrentamos esse problema com os TPRs anteriormente.

/ tipo bug

Parece que estou tendo esse problema com a implantação de uma torre:

➜  tmp git:(master) ✗ kubectl delete namespace rook
Error from server (Conflict): Operation cannot be fulfilled on namespaces "rook": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.
➜  tmp git:(master) ✗ 

Acho que tem algo a ver com o CRD deles, vejo isso nos logs do servidor de API:

E0314 07:28:18.284942       1 crd_finalizer.go:275] clusters.rook.io failed with: timed out waiting for the condition
E0314 07:28:18.287629       1 crd_finalizer.go:275] clusters.rook.io failed with: Operation cannot be fulfilled on customresourcedefinitions.apiextensions.k8s.io "clusters.rook.io": the object has been modified; please apply your changes to the latest version and try again

Implantei o rook em um namespace diferente agora, mas não consigo criar o CRD do cluster:

➜  tmp git:(master) ✗ cat rook/cluster.yaml 
apiVersion: rook.io/v1alpha1
kind: Cluster
metadata:
  name: rook
  namespace: rook-cluster
spec:
  dataDirHostPath: /var/lib/rook-cluster-store
➜  tmp git:(master) ✗ kubectl create -f rook/
Error from server (MethodNotAllowed): error when creating "rook/cluster.yaml": the server does not allow this method on the requested resource (post clusters.rook.io)

Parece que o CRD nunca foi limpo:

➜  tmp git:(master) ✗ kubectl get customresourcedefinitions clusters.rook.io -o yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  creationTimestamp: 2018-02-28T06:27:45Z
  deletionGracePeriodSeconds: 0
  deletionTimestamp: 2018-03-14T07:36:10Z
  finalizers:
  - customresourcecleanup.apiextensions.k8s.io
  generation: 1
  name: clusters.rook.io
  resourceVersion: "9581429"
  selfLink: /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/clusters.rook.io
  uid: 7cd16376-1c50-11e8-b33e-aeba0276a0ce
spec:
  group: rook.io
  names:
    kind: Cluster
    listKind: ClusterList
    plural: clusters
    singular: cluster
  scope: Namespaced
  version: v1alpha1
status:
  acceptedNames:
    kind: Cluster
    listKind: ClusterList
    plural: clusters
    singular: cluster
  conditions:
  - lastTransitionTime: 2018-02-28T06:27:45Z
    message: no conflicts found
    reason: NoConflicts
    status: "True"
    type: NamesAccepted
  - lastTransitionTime: 2018-02-28T06:27:45Z
    message: the initial names have been accepted
    reason: InitialNamesAccepted
    status: "True"
    type: Established
  - lastTransitionTime: 2018-03-14T07:18:18Z
    message: CustomResource deletion is in progress
    reason: InstanceDeletionInProgress
    status: "True"
    type: Terminating
➜  tmp git:(master) ✗ 

Eu tenho um namespace de fissão em um estado semelhante:

➜  tmp git:(master) ✗ kubectl delete namespace fission
Error from server (Conflict): Operation cannot be fulfilled on namespaces "fission": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.
➜  tmp git:(master) ✗ kubectl get pods -n fission     
NAME                          READY     STATUS        RESTARTS   AGE
storagesvc-7c5f67d6bd-72jcf   0/1       Terminating   0          8d
➜  tmp git:(master) ✗ kubectl delete pod/storagesvc-7c5f67d6bd-72jcf --force --grace-period=0
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
Error from server (NotFound): pods "storagesvc-7c5f67d6bd-72jcf" not found
➜  tmp git:(master) ✗ kubectl describe pod -n fission storagesvc-7c5f67d6bd-72jcf
Name:                      storagesvc-7c5f67d6bd-72jcf
Namespace:                 fission
Node:                      10.13.37.5/10.13.37.5
Start Time:                Tue, 06 Mar 2018 07:03:06 +0000
Labels:                    pod-template-hash=3719238268
                           svc=storagesvc
Annotations:               <none>
Status:                    Terminating (expires Wed, 14 Mar 2018 06:41:32 +0000)
Termination Grace Period:  30s
IP:                        10.244.2.240
Controlled By:             ReplicaSet/storagesvc-7c5f67d6bd
Containers:
  storagesvc:
    Container ID:  docker://3a1350f6e4871b1ced5c0e890e37087fc72ed2bc8410d60f9e9c26d06a40c457
    Image:         fission/fission-bundle:0.4.1
    Image ID:      docker-pullable://fission/fission-bundle<strong i="6">@sha256</strong>:235cbcf2a98627cac9b0d0aae6e4ea4aac7b6e6a59d3d77aaaf812eacf9ef253
    Port:          <none>
    Command:
      /fission-bundle
    Args:
      --storageServicePort
      8000
      --filePath
      /fission
    State:          Terminated
      Exit Code:    0
      Started:      Mon, 01 Jan 0001 00:00:00 +0000
      Finished:     Mon, 01 Jan 0001 00:00:00 +0000
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /fission from fission-storage (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from fission-svc-token-zmsxx (ro)
Conditions:
  Type           Status
  Initialized    True 
  Ready          False 
  PodScheduled   True 
Volumes:
  fission-storage:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  fission-storage-pvc
    ReadOnly:   false
  fission-svc-token-zmsxx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  fission-svc-token-zmsxx
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
➜  tmp git:(master) ✗ 

A fissão também usa CRDs, no entanto, eles parecem estar limpos.

@ shean-guangchang - Eu tive o mesmo problema. Excluí tudo sob os namespaces manualmente, excluí e purifiquei tudo do "leme" e reiniciei os nós mestres um por um e isso corrigiu o problema.

Eu imagino que o que encontrei tem algo a ver com "ark", "tiller" e Kuberenets todos trabalhando juntos (eu iniciei usando o elmo e apoiei usando o ark) então isso pode não ser um problema Kuberenets por dizer, por outro Por outro lado, era praticamente impossível detectar o problema porque não há registros relevantes.

se for a torre, dê uma olhada nisto: https://github.com/rook/rook/issues/1488#issuecomment -365058080

Acho que faz sentido, mas parece problemático que seja possível colocar um namespace em um estado não eliminável.

Eu tenho um ambiente semelhante (Ark & Helm) com @barakAtSoluto e tenho o mesmo problema. Purgar e reiniciar os masters não resolveu para mim. Ainda preso no encerramento.

Eu também tive isso ao tentar recriar o problema. Eventualmente, tive que criar um novo cluster ....
Excluir - padrão, kube-system / public e todos os namespaces relacionados ao ark do backup e da restauração para evitar que isso aconteça ...

Também estou vendo isso em um cluster atualizado de 1.8.4 para 1.9.6. Eu nem sei quais registros olhar

O mesmo problema em 1.10.1 :(

Mesmo problema em 1.9.6

Edit: O namespace não pode ser excluído por causa de alguns pods pendurados. Eu fiz uma exclusão com --grace-period = 0 --force em todos eles e depois de alguns minutos o namespace foi excluído também.

Ei,

Eu tenho isso repetidamente e na maioria das vezes é um problema com os finalizadores.

Se um namespace estiver travado, tente kubectl get namespace XXX -o yaml e verifique se há um finalizador nele. Nesse caso, edite o namespace e remova o finalizador (passando um array vazio) e então o namespace será excluído

@xetys é seguro? no meu caso, há apenas um finalizador chamado "kubernetes".

Que estranho, nunca vi um finalizador assim. Só posso falar com base na minha experiência. Eu fiz isso várias vezes em um cluster de produção e ainda está vivo

Mesmo problema em 1.10.5. Tentei todos os conselhos nesta edição sem resultado. Consegui me livrar dos pods, mas o namespace ainda está pendurado.

Na verdade, os ns também foram excluídos depois de um tempo.

Seria bom entender o que causa esse comportamento, o único finalizador que tenho é o kubernetes. Eu também tenho webhooks dinâmicos. Eles podem estar relacionados?

@xetys Bem, finalmente usei seu truque com as réplicas dentro desse namespace. Eles tinham algum finalizador personalizado que provavelmente não existia mais, então não pude excluí-los. Quando removi as referências a esse finalizador, elas desapareceram, assim como o namespace. Obrigado! :)

Mesmo problema em um cluster EKS 1.10.3:

Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-28T20:13:43Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}

Tendo o mesmo problema em um cluster bare metal:

Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:17:28Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.1", GitCommit:"b1b29978270dc22fecc592ac55d903350454310a", GitTreeState:"clean", BuildDate:"2018-07-17T18:43:26Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}

Meu namespace é assim:

apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"creneaux-app","namespace":""}}
  name: creneaux-app
spec:
  finalizers:
  - kubernetes

Na verdade, é o segundo namespace que tive esse problema.

Tente isto para obter a lista real de todas as coisas em seu namespace: https://github.com/kubernetes/kubectl/issues/151#issuecomment -402003022

Então, para cada objeto, faça kubectl delete ou kubectl edit para remover os finalizadores.

remover o inicializador funcionou para mim ...

Quando eu faço kubectl edit namespace annoying-namespace-to-delete e removo os finalizadores, eles são adicionados novamente quando eu verifico com kubectl get -o yaml .

Além disso, ao tentar o que você sugeriu @adampl, não recebo nenhuma saída (remover --ignore-not-found confirma que nenhum recurso foi encontrado no namespace, de qualquer tipo).

@ManifoldFR , tive o mesmo problema que o seu e consegui fazer funcionar fazendo uma chamada de API com arquivo json.
kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
em seguida, edite tmp.json e remova "kubernetes"

curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize

e deve excluir seu namespace,

@slassh Funcionou! Deveria ter pensado em fazer uma chamada de API: muito obrigado! Vamos cantar seus louvores para sempre

O problema existe na v1.11.1. Tive um rancheiro / leme preso na implantação do dokuwiki. Primeiro, tive que forçar a exclusão dos pods conforme sugerido por @siXor e depois segui o conselho de @slassh . Tudo bem agora.

@slassh como ver o kubernetes-cluster-ip? eu uso um dos nódulos ip implantados na substituição de cluster kubernetes e ele reporta 404

oi @jiuchongxiao , por kubernetes-cluster-ip eu quis dizer um de seus mestres de nó ip.
desculpe se é confuso!

Se você iniciar o 'kubectl proxy' primeiro, poderá direcionar o curl para http://127.0.0.1 : 8001 / api / v1 / namespaces / irritante-namespace-to-delete / finalize. Eu não conseguia fazer a autenticação funcionar até que fizesse dessa forma.

boas dicas @ 2stacks. Basta substituir https por http .

Ainda vejo esse problema em 1.11.2.

Para dar mais contexto para a reprodução, vi isso apenas com CRDs. Ao excluir o objeto CRD, fiquei em um estado estranho onde os objetos pertencentes a ele não foram excluídos. Não percebi, então emiti uma exclusão para o namespace. Em seguida, apaguei todos os objetos do namespace com kubectl delete all --all -n my-namespace . Nesse ponto, a exclusão do namespace travou. Espero que isso ajude de algum jeito.

Olhando os logs, descobri que esse problema específico estava relacionado ao fato de o gerenciador do controlador não estar íntegro. No meu caso, provavelmente não era um bug. Quando o gerenciador do controlador voltou a funcionar, tudo foi limpo corretamente.

@slassh Solução perfeita! Muito obrigado!!!!

Também vejo esse problema com 1.10.x. Considero o comentário de Terminating ?

Descobrimos o motivo de a exclusão de namespaces ficar presa em nosso caso (@palmerabollo)

Quando um namespace tem um finalizador kubernetes , isso significa que é um problema interno com o servidor API.

Execute kubectl api-resources , se retornar um como o seguinte, significa que a API personalizada não está acessível.

error: unable to retrieve the complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to handle the request

Execute kubectl get apiservices v1beta1.metrics.k8s.io -o yaml , para verificar suas condições de status.

status:
  conditions:
  - lastTransitionTime: 2018-10-15T08:14:15Z
    message: endpoints for service/metrics-server in "kube-system" have no addresses
    reason: MissingEndpoints
    status: "False"
    type: Available

O erro acima deve ser causado por um crashloopbackoff afetando o metrics-server. Seria semelhante para outras APIs personalizadas registradas no Kubernetes.

Verifique a integridade dos serviços em kube-system para restaurar as operações de tempo de execução do cluster, como a exclusão de namespaces.

Estou enfrentando esse problema na v1.11.3. Nos finalizadores, apenas kubernetes estão presentes para o namespace problemático.

spec:
  finalizers:
  - kubernetes

@slassh Obrigado um milhão, sua solução funciona bem!
Eu tenho o mesmo problema no meu cluster com ark, tiller e kubed. Suspeito que os problemas podem ser a api do kubed que está apresentando um erro, embora não tenha certeza de por que isso afeta a exclusão de outro namespace.

@javierprovecho Eu estava apenas brincando com o servidor de métricas e como não estava funcionando, tentei excluir o serviço e outros enfeites, mas meu namespace ainda não exclui, o erro é

status:
  conditions:
  - lastTransitionTime: 2018-08-24T08:59:36Z
    message: service/metrics-server in "kube-system" is not present
    reason: ServiceNotFound
    status: "False"
    type: Available

Você sabe como se recuperar desse estado?

editar: Eu descobri ... Eu tive que excluir _tudo_ mesmo remotamente relacionado a métricas / HPA e, em seguida, reiniciar todo o plano de controle (tive que derrubar todas as minhas réplicas, antes de reinicializá-las de volta.) Isso incluiu a exclusão de apiservice v1beta1.metrics.k8s.io si.

@ 2rs2ts

$ kubectl delete apiservice v1beta1.metrics.k8s.io

Ao se livrar do serviço de API metrics funcional, o gerenciador do controlador poderá excluir o (s) namespace (s) obsoleto (s).

Reiniciar o plano de controle não é necessário.

@antoineco não, foi necessário; Excluí o apiservice e esperei um pouco, mas o namespace não seria excluído até que reiniciei o plano de controle.

primeiro, tome um pequeno café e relaxe, agora vá para seus nós mestres k8s

  1. kubectl cluster-info
    O mestre do Kubernetes está sendo executado em https: // localhost : 6443
    KubeDNS está sendo executado em https: // localhost : 6443 / api / v1 / namespaces / kube-system / services / kube- dns: dns / proxy

Para depurar e diagnosticar ainda mais os problemas do cluster, use 'kubectl cluster-info dump'.

  1. agora execute o kube-proxy
    proxy kubectl &
    Começando a servir em 127.0.0.1:8001

salve o ID para excluí-lo mais tarde :)

  1. encontre o seu espaço de nome que decidiu não ser excluído :) para nós será o sistema de gado
    kubectl get ns
    Sistema de gado Terminando 1d

coloque no arquivo

  1. kubectl get namespace cattle-system -o json> tmp.json
  1. edite o arquivo e remova os finalizadores
    },
    "spec": {
    "finalizadores": [
    "kubernetes"
    ]
    },
    após a edição, deve ficar assim 👍
    },
    "spec": {
    "finalizadores": [
    ]
    },
    estamos quase lá 👍

curl -k -H "Content-Type: application / json" -X PUT --data-binary @ tmp.json http://127.0.0.1 : 8001 / api / v1 / namespaces / $ {NAMESPACE} / finalize

e se foi 👍

Ei, o finalizador kubernetes existe por um motivo. Para nós, era um nome de serviço de API de métricas configurado incorretamente. Talvez para você seja outra coisa, que você pode descobrir olhando para os registros do seu plano de controle. Sem a confirmação de um bug, remover o finalizador pode produzir consequências indesejadas, como deixar coisas criadas que não podem mais ser acessadas novamente para fins de exclusão.

já que este problema ainda está aberto:
dentro do meu cluster minikube rodando com "none", isso aconteceu depois que o host acordou da hibernação.

minha suposição:
no meu caso, a hibernação desencadeou os mesmos problemas, uma troca habilitada faria.

o que produz a suposição:
a troca pode ser habilitada nos clusters afetados?

mas isso é apenas conjectura. o importante para mim e para qualquer um que tenha encontrado esse bug com minha configuração local: o hibernate é ruim para o kubernetes .

primeiro, tome um pequeno café e relaxe, agora vá para seus nós mestres k8s

  1. kubectl cluster-info
    O mestre do Kubernetes está sendo executado em https: // localhost : 6443
    KubeDNS está sendo executado em https: // localhost : 6443 / api / v1 / namespaces / kube-system / services / kube- dns: dns / proxy

Para depurar e diagnosticar ainda mais os problemas do cluster, use 'kubectl cluster-info dump'.

  1. agora execute o kube-proxy
    proxy kubectl &
    Começando a servir em 127.0.0.1:8001

salve o ID para excluí-lo mais tarde :)

  1. encontre o seu espaço de nome que decidiu não ser excluído :) para nós será o sistema de gado
    kubectl get ns
    Sistema de gado Terminando 1d

coloque no arquivo

  1. kubectl get namespace cattle-system -o json> tmp.json
  1. edite o arquivo e remova os finalizadores
    },
    "spec": {
    "finalizadores": [
    "kubernetes"
    ]
    },
    após a edição, deve ficar assim 👍
    },
    "spec": {
    "finalizadores": [
    ]
    },
    estamos quase lá 👍

curl -k -H "Content-Type: application / json" -X PUT --data-binary @ tmp.json http://127.0.0.1 : 8001 / api / v1 / namespaces / $ {NAMESPACE} / finalize

e se foi 👍

Ótimo!!
Trabalho

Eu me deparo com esse problema periodicamente se alterarmos nossas instâncias do gcloud (por exemplo, atualizando nós). Isso substitui o nó antigo de gcloud instances list por um novo, mas deixa os pods no namespace k8s pendurados:

Reason:                    NodeLost
Message:                   Node <old node> which was running pod <pod> is unresponsive

Isso deixa os pods em um estado desconhecido:

$ kubectl get po
NAME                               READY     STATUS    RESTARTS   AGE
<pod>                              2/2       Unknown   0          39d

Devido a isso, o namespace nunca terminará. Não tenho certeza se isso significa que devemos mudar nossos finalizadores ou se há um bug real relacionado ao encerramento que deveria tratar pods em um estado UNKNOWN (ou se deveria haver uma maneira de forçar o encerramento de um namespace para casos como este )

Eu me deparo com esse problema periodicamente se alterarmos nossas instâncias do gcloud (por exemplo, atualizando nós). Isso substitui o nó antigo de gcloud instances list por um novo, mas deixa os pods no namespace k8s pendurados:

Reason:                    NodeLost
Message:                   Node <old node> which was running pod <pod> is unresponsive

Isso deixa os pods em um estado desconhecido:

$ kubectl get po
NAME                               READY     STATUS    RESTARTS   AGE
<pod>                              2/2       Unknown   0          39d

Devido a isso, o namespace nunca terminará. Não tenho certeza se isso significa que devemos mudar nossos finalizadores ou se há um bug real relacionado ao encerramento que deveria tratar pods em um estado UNKNOWN (ou se deveria haver uma maneira de forçar o encerramento de um namespace para casos como este )

legal não é o mesmo problema
você precisa colocar os nós no modo de manutenção e, em seguida, depois de entrar no modo de manutenção, todos os pods serão evacuados e então você pode excluir / atualizar

olhe isso, https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ ,
edite o recurso e exclua metadata.finalizers, e exclua o crd inutilizável, você pode excluí-lo force

Mas o que o finalizador kubernetes faz exatamente? Existe algum risco de que os recursos não sejam limpos corretamente com este hack?

curl -k -H "Content-Type: application / json" -X PUT --data-binary @ tmp.json https: // kubernetes-cluster-ip / api / v1 / namespaces / irring-namespace-to-delete / finalizar

Erro do servidor (NotFound): namespaces "irritante-namespace-a-deletar" não encontrado

primeiro, tome um pequeno café e relaxe, agora vá para seus nós mestres k8s

  1. kubectl cluster-info
    O mestre do Kubernetes está sendo executado em https: // localhost : 6443
    KubeDNS está sendo executado em https: // localhost : 6443 / api / v1 / namespaces / kube-system / services / kube- dns: dns / proxy

Para depurar e diagnosticar ainda mais os problemas do cluster, use 'kubectl cluster-info dump'.

  1. agora execute o kube-proxy
    proxy kubectl &
    Começando a servir em 127.0.0.1:8001

salve o ID para excluí-lo mais tarde :)

  1. encontre o seu espaço de nome que decidiu não ser excluído :) para nós será o sistema de gado
    kubectl get ns
    Sistema de gado Terminando 1d

coloque no arquivo

  1. kubectl get namespace cattle-system -o json> tmp.json
  1. edite o arquivo e remova os finalizadores
    },
    "spec": {
    "finalizadores": [
    "kubernetes"
    ]
    },
    após a edição, deve ficar assim 👍
    },
    "spec": {
    "finalizadores": [
    ]
    },
    estamos quase lá 👍

curl -k -H "Content-Type: application / json" -X PUT --data-binary @ tmp.json http://127.0.0.1 : 8001 / api / v1 / namespaces / $ {NAMESPACE} / finalize

e se foi 👍

Valor inválido: "O arquivo editado falhou na validação": ValidationError (Namespace.spec): tipo inválido para io.k8s.api.core.v1.NamespaceSpec: obtido "string", esperado "mapa"

Se você tiver muitos namespaces presos no Encerramento, pode automatizar isso:

kubectl get ns | grep Terminating | awk '{print $1}' | gxargs  -n1 -- bash -c 'kubectl get ns "$0" -o json | jq "del(.spec.finalizers[0])" > "$0.json"; curl -k -H "Content-Type: application/json" -X PUT --data-binary @"$0.json" "http://127.0.0.1:8001/api/v1/namespaces/$0/finalize" '

certifique-se de que todos os namespaces que deseja que o finalizador remova sejam realmente Terminating .

Você precisa de kubectl proxy execução e jq para que o acima funcione.

No nosso caso, o serviço de API de métricas está inativo e posso ver este log de erro do registro detalhado

kubectl delete ns <namespace-name> -v=7
.......
I0115 11:03:25.548299   12445 round_trippers.go:383] GET https://<api-server-url>/apis/metrics.k8s.io/v1beta1?timeout=32s
I0115 11:03:25.548317   12445 round_trippers.go:390] Request Headers:
I0115 11:03:25.548323   12445 round_trippers.go:393]     Accept: application/json, */*
I0115 11:03:25.548329   12445 round_trippers.go:393]     User-Agent: kubectl/v1.11.3 (darwin/amd64) kubernetes/a452946
I0115 11:03:25.580116   12445 round_trippers.go:408] Response Status: 503 Service Unavailable in 31 milliseconds

Depois de corrigir o serviço de métricas, os de encerramento são concluídos.
Não tenho certeza de por que a exclusão depende de metrics apiservice, também estou interessado em saber como funciona se metrics apiservice não estiver instalado no cluster

Não tenho certeza de por que a exclusão depende das métricas de um serviço,

@manojbadam porque as métricas são registradas no servidor api, ao executar uma exclusão de namespace, ele deve consultar essa api externa para recursos (com namespace) a serem excluídos (se houver) associados a esse namespace. Se o servidor de extensão não estiver disponível, o Kubernetes não pode garantir que todos os objetos foram removidos e não tem um mecanismo persistente (na memória ou no disco) para reconciliar posteriormente, porque o objeto raiz teria sido removido. Isso acontece com qualquer serviço de extensão API registrado.

Como eu estava constantemente enfrentando isso, automatizei isso com um pequeno script de shell:

https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns

Ele busca o projeto, corrige o JSON, inicia e interrompe adequadamente o "proxy kubectl",…

Obrigado a todos que estão me apontando na direção certa!

Como eu estava constantemente enfrentando isso, automatizei isso com um pequeno script de shell:

https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns

Ele busca o projeto, corrige o JSON, inicia e interrompe adequadamente o "proxy kubectl",…

Obrigado a todos que estão me apontando na direção certa!

meu heroi! <3

Eu também tive esse problema. Estou no Google Kubernetes Engine e usando o Terraform para ativar clusters Kubernetes e criar namespaces e pods dentro do cluster. O problema começou um pouco depois de executar terraform destroy .

No meu caso, esse é um problema com a ordem em que o Terraform executa a destruição. O Terraform exclui o pool de nós primeiro e, em seguida, exclui os namespaces e pods. Mas, devido à exclusão do (único) pool de nós, o cluster do Kubernetes quebrou e foi isso que fez com que a exclusão do namespace travasse na "finalização" para sempre.

@FooBarWidget é o mesmo problema para mim :(

Como eu estava constantemente enfrentando isso, automatizei isso com um pequeno script de shell:

https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns

Ele busca o projeto, corrige o JSON, inicia e interrompe adequadamente o "proxy kubectl",…

Obrigado a todos que estão me apontando na direção certa!

[root@k8s-master ~]# curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://172.*****:6443/api/v1/namespaces/rook-ceph/finalize
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {

},
"status": "Failure",
"message": "namespaces "rook-ceph" is forbidden: User "system:anonymous" cannot update namespaces/finalize in the namespace "rook-ceph"",
"reason": "Forbidden",
"details": {
"name": "rook-ceph",
"kind": "namespaces"
},
"code": 403

Recebi um código de retorno 403, o que devo fazer :(

Como eu estava constantemente enfrentando isso, automatizei isso com um pequeno script de shell:
https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns
Ele busca o projeto, corrige o JSON, inicia e interrompe adequadamente o "proxy kubectl",…
Obrigado a todos que estão me apontando na direção certa!

[root@k8s-master ~]# curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://172.*****:6443/api/v1/namespaces/rook-ceph/finalize
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {

},
"status": "Failure",
"message": "namespaces "rook-ceph" is forbidden: User "system:anonymous" cannot update namespaces/finalize in the namespace "rook-ceph"",
"reason": "Forbidden",
"details": {
"name": "rook-ceph",
"kind": "namespaces"
},
"code": 403

Recebi um código de retorno 403, o que devo fazer :(

Meu deus, o namespace de terminação finalmente se foi. O método a seguir funciona bem para mim.

NAMESPACE=rook-ceph
kubectl proxy &
kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize

Eu tenho o mesmo problema, mas não vejo nenhum serviço de métricas.

Estou brincando com k8s do digitalocean e gitlab auto devops. Minha suposição é algum armazenamento de blob digitalocean, mas estou perdido em como analisar ou consertar isso.

@mingxingshi tx. Editei o namespace que não funcionou. Seu script fez isso.

Uau, finalmente me livrei disso. Obrigado pelos comandos @mingxingshi !

A solução para mim foi:

kubectl delete apiservice v1beta1.metrics.k8s.io

apenas percebi que deveria deixar minha experiência disso aqui:

eu estava fazendo terraform apply com o seguinte recurso:

resource "helm_release" "servicer" {
  name      = "servicer-api"
  // n.b.: this is a local chart just for this terraform project
  chart     = "charts/servicer-api"
  namespace = "servicer"
  ...
}

mas eu sou um leme newb e tinha um modelo que tinha um modelo nele que criava um namespace chamado servicer . Isso fez com que o terrenoformado e o k8s ficassem neste estado ruim onde o terrenoformado falharia, então o k8s deixaria o namespace servicer permanentemente no estado Terminating . Fazer o que @mingxingshi sugere acima fez com que o namespace fosse encerrado, pois não havia recursos anexados a ele.

esse problema parou de acontecer para mim quando removi o modelo que criava o namespace e deixei para o comando para criá-lo.

O problema é completamente repetível para mim. Primeiro, clone o operador prometheus . Então:

cd prometheus-operator/contrib/kube-prometheus
kubectl create -f manifests/ --validate=false
 ... wait ...
kubectl delete namespace monitoring

Pendura. Se, no entanto, eu usar kubectl delete -f manifests/ , a limpeza foi bem-sucedida.

Sim, tive o mesmo problema com a operadora de prometheus. Precisa kubectl delete -f manifests/ para descolar.
Acho que há alguns finalizadores nos CRDs do prometheus que estão se comportando mal. Neste cenário específico, dificilmente é uma falha do Kubernetes. No entanto, o kubernetes deve tornar mais fácil encontrar o culpado, porque os desafios desta discussão demonstram que podem haver muitas causas e não é fácil chegar ao fundo disso em cada cenário específico.

Sou um novato do Kubernetes, então não posso oferecer muitas informações aqui, mas também tenho 2 namespaces presos no status de encerramento. Minha configuração de kubernetes está usando IBM Cloud Private 3.1.2 Community Edition

kubectl version
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.4+icp", GitCommit:"3f5277fa129f05fea532de48284b8b01e3d1ab4e", GitTreeState:"clean", BuildDate:"2019-01-17T13:41:02Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.4+icp", GitCommit:"3f5277fa129f05fea532de48284b8b01e3d1ab4e", GitTreeState:"clean", BuildDate:"2019-01-17T13:41:02Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}

kubectl cluster-info
Kubernetes master is running at https://ip
catalog-ui is running at https://ip/api/v1/namespaces/kube-system/services/catalog-ui:catalog-ui/proxy
Heapster is running at https://ip/api/v1/namespaces/kube-system/services/heapster/proxy
image-manager is running at https://ip/api/v1/namespaces/kube-system/services/image-manager:image-manager/proxy
CoreDNS is running at https://ip/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
metrics-server is running at https://ip/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
platform-ui is running at https://ip/api/v1/namespaces/kube-system/services/platform-ui:platform-ui/proxy

kubectl get nodes
NAME          STATUS                     ROLES                          AGE   VERSION
ip1    Ready,SchedulingDisabled   etcd,management,master,proxy   23h   v1.12.4+icp
ip2   Ready                      worker                         23h   v1.12.4+icp
ip3   Ready                      worker                         23h   v1.12.4+icp

Eu tenho dois namespaces presos no estado de terminação

kubectl get ns
NAME           STATUS        AGE
my-apps       Terminating   21h
cert-manager   Active        23h
default        Active        23h
istio-system   Active        23h
kube-public    Active        23h
kube-system    Active        23h
platform       Active        22h
psp-example    Terminating   18h
services       Active        22h

Quando eu verifico os finalizadores conforme descrito neste comentário, vejo apenas kubernetes .

kubectl get ns my-apps -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"my-apps"}}
  creationTimestamp: 2019-04-10T18:23:55Z
  deletionTimestamp: 2019-04-11T15:24:24Z
  name: my-apps
  resourceVersion: "134914"
  selfLink: /api/v1/namespaces/my-apps
  uid: ccb0398d-5bbd-11e9-a62f-005056ad5350
spec:
  finalizers:
  - kubernetes
status:
  phase: Terminating

Apesar de tudo, tentei remover kubernetes dos finalizadores e não funcionou. Também tentei usar a abordagem json / api descrita neste comentário . Também não funcionou. Tentei reiniciar todos os nós e também não funcionou.

Eu também tentei fazer a exclusão forçada e isso também não funcionou

kubectl delete namespace my-apps --force --grace-period 0
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
Error from server (Conflict): Operation cannot be fulfilled on namespaces "my-apps": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.

No meu caso, o namespace é rook-ceph, kubectl -n rook-ceph patch cephclusters.ceph.rook.io rook-ceph -p '{"metadata":{"finalizers": []}}' --type=merge funciona para mim. Para outros casos, deve funcionar também.

De: https://github.com/rook/rook/blob/master/Documentation/ceph-teardown.md

@ManifoldFR , tive o mesmo problema que o seu e consegui fazer funcionar fazendo uma chamada de API com arquivo json.
kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
em seguida, edite tmp.json e remova "kubernetes"

curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize

e deve excluir seu namespace,

Tenho alguns problemas ao usar sua abordagem. O que devo fazer na próxima etapa de solução de problemas?

~ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://39.96.4.11:6443/api/v1/namespaces/istio-system/finalize
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "namespaces \"istio-system\" is forbidden: User \"system:anonymous\" cannot update resource \"namespaces/finalize\" in API group \"\" in the namespace \"istio-system\"",
  "reason": "Forbidden",
  "details": {
    "name": "istio-system",
    "kind": "namespaces"
  },
  "code": 403

@ManifoldFR , tive o mesmo problema que o seu e consegui fazer funcionar fazendo uma chamada de API com arquivo json.
kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
em seguida, edite tmp.json e remova "kubernetes"
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize
e deve excluir seu namespace,

Tenho alguns problemas ao usar sua abordagem. O que devo fazer na próxima etapa de solução de problemas?

~ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://39.96.4.11:6443/api/v1/namespaces/istio-system/finalize
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "namespaces \"istio-system\" is forbidden: User \"system:anonymous\" cannot update resource \"namespaces/finalize\" in API group \"\" in the namespace \"istio-system\"",
  "reason": "Forbidden",
  "details": {
    "name": "istio-system",
    "kind": "namespaces"
  },
  "code": 403

Meu problema pode ser resolvido por este script: https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns .

yup https://github.com/ctron/kill-kube-ns/blob/master/kill-kube-ns resolve o problema

set -eo pipefail

die() { echo "$*" 1>&2 ; exit 1; }

need() {
    which "$1" &>/dev/null || die "Binary '$1' is missing but required"
}

# checking pre-reqs

need "jq"
need "curl"
need "kubectl"

PROJECT="$1"
shift

test -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"

kubectl proxy &>/dev/null &
PROXY_PID=$!
killproxy () {
    kill $PROXY_PID
}
trap killproxy EXIT

sleep 1 # give the proxy a second

kubectl get namespace "$PROJECT" -o json | jq 'del(.spec.finalizers[] | select("kubernetes"))' | curl -s -k -H "Content-Type: application/json" -X PUT -o /dev/null --data-binary @- http://localhost:8001/api/v1/namespaces/$PROJECT/finalize && echo "Killed namespace: $PROJECT"

Parece que os namespaces não são excluídos.
No meu caso, kubectl get ns não mostra o namespace excluído, mas um kubectl get all -n <namespace> mostra todos os recursos sãos e salvos.
Eu verifiquei os nós e os contêineres docker ainda estavam em execução ...

@glouis é porque você contornou os finalizadores usando o método acima, então o Kubernetes não teve tempo para executar todas as tarefas essenciais de exclusão.

É muito triste ver tantas pessoas defendendo cegamente esse método, sem entender suas consequências. É extremamente feio e pode potencialmente deixar toneladas de sobras no cluster. @javierprovechomencionou isso acima, e @liggitt também mencionou em outro problema do GitHub.

Seria melhor consertar o serviço de API v1beta1.metrics.k8s.io corrompido ou excluí-lo se não precisar dele.

Veja também # 73405

Eu segundo mensagem @antoineco . Eu testei isso em um de nossos ambientes de sandbox porque estávamos constantemente travando namespaces. depois de cerca de um mês, todos os daemons docker estavam congelando sem motivo. Acontece que criamos enormes vazamentos de memória ao deixar recursos para trás.

Depois de muita tentativa e erro, e lendo esses comentários, acabou sendo uma definição de recurso customizada para a pilha coreos grafana para os namespaces. A listagem dos CRDs mostrou recursos específicos para esse namespace. Tive muita sorte que o nome do CRD contivesse o namespace que estava preso.

Descobriu-se também que ter um namespace bloqueado impede que mais namespaces sejam excluídos. Portanto, mesmo se você tiver o espaço de nomes A que não possui nenhum CRD bloqueando, e houver um espaço de nomes B com um CRD preso, todos os recursos em A permanecerão por aí até que B se esgote. Acho que devo ter feito a correção descrita acima no namespace A, deixando uma tonelada de recursos sempre.

O que ainda está me matando é que não consigo encontrar nenhum log que mencione uma falha de limpeza de namespace ao excluir um CRD, ou mesmo o que ele está fazendo no momento. Tive que passar uma hora tentando descobrir em que CRD ele estava preso. Se alguém tiver uma ideia sobre como obter mais informações, então eu não tenho que gastar muito tempo tentando descobrir o recurso preso, isso seria incrível.

@jecafarelli uma boa dica para

Tentei analisar o problema, mas nada neste tópico me ajudou a resolvê-lo por outros meios.

Esta solução oficial me ajudou: https://success.docker.com/article/kubernetes-namespace-stuck-in-terminating
Isso não é o mesmo que kubectl edit namespace rook-ceph . Não fui capaz de resolver este problema até que I PUT solicitei com _ "finalizadores" _ excluídos

ok então eu corri para isso de novo com coreos, e cavei um pouco mais fundo. isso é definitivamente por causa de uma definição de recurso de todo o cluster que tem espaço de nomes e, mais ainda, talvez não pudesse excluí-lo porque não pode consultar informações em coreos. Eu encontrei erros nos logs do apiserver que mostraram erros ao tentar obter informações sobre um grupo de api. Usei o problema mencionado acima para criar um script rápido que lista os recursos que travaram o ns para mim.

Provavelmente, usarei isso no futuro se encontrar com ele novamente e continuar adicionando quaisquer outros recursos com namespace que encontrar.

for ns in `kubectl get ns --field-selector status.phase=Terminating -o name | cut -d/ -f2`; 
do
  echo "apiservice under namespace $ns"
  kubectl get apiservice -o json |jq --arg ns "$ns" '.items[] |select(.spec.service.namespace != null) | select(.spec.service.namespace == $ns) | .metadata.name ' --raw-output
  echo "api resources under namespace $ns"
  for resource in `kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -o name -n $ns`; 
  do 
    echo $resource
  done;
done

Muito obrigado @jecafarelli , você me ajudou a resolver meu problema da maneira certa ;-)

Eu tinha instalado o cert-manager em um cluster OpenShift dentro do namespace cert-manager e quando tentei excluir este namespace, ele travou no estado de encerramento. A execução de oc delete apiservices v1beta1.admission.certmanager.k8s.io parece ter resolvido o problema, o namespace se foi.

Muito obrigado @jecafarelli , você me ajudou a resolver meu problema da maneira certa ;-)

Eu tinha instalado o cert-manager em um cluster OpenShift dentro do namespace cert-manager e quando tentei excluir este namespace, ele travou no estado de encerramento. A execução de oc delete apiservices v1beta1.admission.certmanager.k8s.io parece ter resolvido o problema, o namespace se foi.

O mesmo aqui, executando kubectl delete -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml ajudou

Estou apenas entrando na conversa para dizer que também encontrei esse erro na versão 1.13.6 com GKE. Aconteceu depois que desativei o complemento Istio do GKE com o objetivo de instalá-lo manualmente para controle total.
Este é o tópico mais longo que já tive tempo para ler, e estou surpreso por não haver consenso real ou etapas de reprodução para a raiz desse problema. Parece que pode ser travado de muitas maneiras diferentes :(

O método JSON e curl / proxy mencionado inúmeras vezes acima e documentado em https://success.docker.com/article/kubernetes-namespace-stuck-in-terminating foi o que me salvou.

O conselho em https://success.docker.com/article/kubernetes-namespace-stuck-in-terminating é ativamente prejudicial e pode fazer com que recursos órfãos não sejam limpos e reaparecem se um namespace com um nome idêntico for posteriormente recriado .

Há um trabalho em andamento para revelar a causa específica da exclusão travada, mas o problema fundamental é que existem tipos de API que não podem ser verificados como limpos, portanto, a exclusão do namespace bloqueia até que sejam verificados.

Também atingimos isso com o Knative, que instala este apiservice com namespace.

---
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  labels:
    autoscaling.knative.dev/metric-provider: custom-metrics
    serving.knative.dev/release: v0.7.1
  name: v1beta1.custom.metrics.k8s.io
spec:
  group: custom.metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: autoscaler
    namespace: knative-serving
  version: v1beta1
  versionPriority: 100
---

Depois de excluí-lo, os ns que servem knative e vários outros namespaces presos foram limpos. Agradecimentos a @jecafarelli pelo script bash acima.
Aqui está uma versão terrível do PowerShell.

$api = kubectl get apiservice -o json  | convertfrom-json
#list out the namespaced api items can ignore kube-system
$api.items | % { $_.spec.service.namespace }
#repalce knative-serving with whatever namespace you found
$api.items | ? { $_.spec.service.namespace -eq 'knative-serving'  } | ConvertTo-Json
#replace v1beta1.custom.metrics.k8s.io with whatever you found. 
k delete apiservice v1beta1.custom.metrics.k8s.io

Tive o mesmo problema hoje e este script funcionou para mim.

@ kubernetes / sig-api-machines-misc

Este bug existe há> ano e ainda é um problema ... Qual é o seu plano para resolver problemas internos como este?

Isso pode ajudar pelo menos a entender o que está acontecendo: https://github.com/kubernetes/kubernetes/pull/80962

Estou tendo o mesmo problema

k get ns cdnamz-k8s-builder-system  -o yaml 
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"labels":{"control-plane":"controller-manager"},"name":"cdnamz-k8s-builder-system"}}
  creationTimestamp: "2019-08-05T18:38:21Z"
  deletionTimestamp: "2019-08-05T20:37:37Z"
  labels:
    control-plane: controller-manager
  name: cdnamz-k8s-builder-system
  resourceVersion: "5980028"
  selfLink: /api/v1/namespaces/cdnamz-k8s-builder-system
  uid: 3xxxxxxx
spec:
  finalizers:
  - kubernetes
status:
  phase: Terminating
 k get ns 
NAME                        STATUS        AGE
cdnamz-k8s-builder-system   Terminating   4h20m

O controlador de namespace deve relatar as condições para o status do namespace e os clientes devem relatar isso. Precisa de um KEP, mas deve ser bastante simples se alguém puder aceitá-lo e validá-lo.

@timothysc há (ou havia) um PR em vôo (em algum lugar) fazendo exatamente o que @smarterclayton diz.

Tenho certeza de que há outro problema no github sobre isso também.

Sim, o PR está aqui: https://github.com/kubernetes/kubernetes/pull/73405

O problema que considero canônico está aqui: https://github.com/kubernetes/kubernetes/issues/70916

Aqui está um recurso que me ajudou: https://www.ibm.com/support/knowledgecenter/en/SSBS6K_3.1.1/troubleshoot/ns_terminating.html

É semelhante à solução proposta por @slassh , mas usa kubectl proxy para criar um proxy local e tornar previsível o IP de destino do comando curl .

-

Edit: conforme afirmado várias vezes abaixo desta resposta, esta solução é um hack sujo e possivelmente deixará alguns recursos dependentes no cluster. Use por sua própria conta e risco e, possivelmente, apenas como uma saída rápida em um cluster de desenvolvimento (não use em um cluster de produção).

remover o finalizador diretamente conforme descrito no documento acima pode ter consequências. Os recursos que estavam com exclusão pendente ainda serão definidos no cluster, mesmo depois que o namespace for liberado. Esse é o objetivo do finalizador. Para garantir que todos os dependentes sejam removidos antes de permitir a exclusão dos ns.

Solução alternativa encontrada em questões semelhantes:

NAMESPACE=<namespace-name>
kubectl proxy &
kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize

Solução alternativa encontrada em questões semelhantes:

NAMESPACE=<namespace-name>
kubectl proxy &
kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize

Obrigado!
Funciona bem.
Eu crio um aplicativo simples e uso esta solução alternativa: https://github.com/jenoOvchi/k8sdelns
Eu o uso para exclusão rápida e espero que seja útil para alguém.

Os namespaces do Kubernetes 1.12.2 estão no estado Terminating. Às vezes, os finalizadores podem ser excluídos modificando o yaml de ns. Ele não pode ser excluído pela API. Ele pode ser excluído? Qual é a situação? Nós o rastreamos especificamente (pré-requisito: não há recursos neste ns), espero poder obter dicas, obrigado!

Novamente, não remova o finalizador, ele existe por um motivo. Em vez disso, tente descobrir quais recursos no NS estão com exclusão pendente:

  • Verificar se algum serviço não está disponível e, portanto, não atende seus recursos: kubectl get apiservice|grep False
  • Encontrar todos os recursos que ainda existem por meio de kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete (Parabéns a Jordan por isso)

A solução para este problema não é causar um curto-circuito no mecanismo de limpeza, mas sim descobrir o que impede a limpeza de ter êxito.

Novamente, não remova o finalizador, ele existe por um motivo. Em vez disso, tente descobrir quais recursos no NS estão com exclusão pendente:

  • Verificar se algum serviço não está disponível e, portanto, não atende seus recursos: kubectl get apiservice|grep False
  • Encontrar todos os recursos que ainda existem por meio de kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete (Parabéns a Jordan por isso)

A solução para este problema não é causar um curto-circuito no mecanismo de limpeza, mas sim descobrir o que impede a limpeza de ter êxito.

Como você está certo.
No meu caso, o pod do Operator Framework apiservice foi excluído e bloqueou o processo de encerramento.
Removendo um apiservice não utilizado (kubectl delete apiservice) resolveu o problema.

Olá a todos, o congelamento do código ocorrerá em apenas alguns dias (quinta-feira, final do dia, horário do Pacífico), então precisamos ter certeza de que esse problema será resolvido para v1.16 ou movido para v1.17. Você pode comentar sobre seu status?

Isso será feito backport em uma versão atual do GKE? Eu tenho um cluster que tem um punhado de namespaces que ainda estão "Terminando".

@squarelover mesmo depois de fazer isso? https://github.com/kubernetes/kubernetes/issues/60807#issuecomment -524772920

@josiahbjorgaard Acabei de aprovar o PR, que é tudo o que faremos para 1.16.

https://github.com/kubernetes/kubernetes/pull/73405 é o PR mencionado anteriormente

Está fundido. Acho que podemos fazer mais, mas, por favor, leve seus comentários futuros para # 70916.

Novamente, não remova o finalizador, ele existe por um motivo. Em vez disso, tente descobrir quais recursos no NS estão com exclusão pendente:

  • Verificar se algum serviço não está disponível e, portanto, não atende seus recursos: kubectl get apiservice|grep False
  • Encontrar todos os recursos que ainda existem por meio de kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete (Parabéns a Jordan por isso)

A solução para este problema não é causar um curto-circuito no mecanismo de limpeza, mas sim descobrir o que impede a limpeza de ter êxito.

Em muitos casos, você pode ter o Metric-Server instalado. Quando os pods que você implanta em um namespaces específicos procuram por coleta de métricas Ele permanece com o servidor Metric. Portanto, mesmo depois de excluir todos os recursos desse namespace, o metric-server é de alguma forma vinculado a esse namespace. O que o impedirá de excluir o namespace.
Esta postagem ajuda a identificar o motivo pelo qual você não pode excluir o Namespace. Portanto, o caminho do rito.

Tente isso para obter a lista real de todas as coisas em seu namespace: kubernetes / kubectl # 151 (comentário)

Então, para cada objeto, faça kubectl delete ou kubectl edit para remover os finalizadores.

Esta solução é útil para mim, obrigado.

Oi pessoal,

Fiz um script para facilitar a exclusão de namespaces no status Encerrando: https://github.com/thyarles/knsk.

Obrigado.

Encontramos o mesmo problema, ao excluir um namespace, ele ficará preso no estado 'Terminando'. Eu segui os stpes acima para remover 'kubernetes' no finalizador no arquivo yaml. Funciona.

No entanto, não sabemos por que precisamos realizar etapas extras. Ele deve fazer kubectl delete ns foonamespace e deve excluir. Alguém pode me dar um motivo? Obrigado!

Olá @ xzhang007 ,

Se você descobrir por que a exclusão do namespace para no estado Terminating, por favor, me avise. Tentei por um tempo uma boa resposta, mas nada. Depois fiz um roteiro para facilitar minha vida até descobrir e consertar a causa.

Obrigado.

@thyales , parece que não encontrei uma resposta até agora.

Em nosso caso, descobrimos que um dos webhhoks e finalizadores que éramos
usando era alcançar um pod que vivia nos namespaces que tinham
excluído.
Depois que o pod foi excluído, a terminação travou.

>

@ xzhang007 você olhou para a resposta fornecida por @alvaroaleman ? Para nós, foi o suficiente para descobrir qual foi a causa.

Novamente, não remova o finalizador, ele existe por um motivo. Em vez disso, tente descobrir quais recursos no NS estão com exclusão pendente:

  • Verificar se algum serviço não está disponível e, portanto, não atende seus recursos: kubectl get apiservice|grep False
  • Encontrar todos os recursos que ainda existem por meio de kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete (Parabéns a Jordan por isso)

A solução para este problema não é causar um curto-circuito no mecanismo de limpeza, mas sim descobrir o que impede a limpeza de ter êxito.


além disso, quando esse problema foi fechado, um novo tíquete foi mencionado para discutir como deixar claro por que o namespace está preso em Terminating. Eu sugiro que você leve a conversa para lá, em vez deste assunto encerrado.

Está fundido. Acho que podemos fazer mais, mas, por favor, leve seus comentários futuros para # 70916.

@ jeff-knurek Esse deve ser o caminho certo. Obrigado.

No nosso caso, foi uma atualização malfeita de cert-manager que quebrou o finalizador. https://github.com/jetstack/cert-manager/issues/1582

$ kube get apiservice

NAME                                   SERVICE                                                     AVAILABLE                  AGE
v1.                                    Local                                                       True                       43d
v1.apps                                Local                                                       True                       43d
v1.authentication.k8s.io               Local                                                       True                       43d
v1.authorization.k8s.io                Local                                                       True                       43d
v1.autoscaling                         Local                                                       True                       43d
v1.batch                               Local                                                       True                       43d
v1.coordination.k8s.io                 Local                                                       True                       43d
v1.networking.k8s.io                   Local                                                       True                       43d
v1.rbac.authorization.k8s.io           Local                                                       True                       43d
v1.scheduling.k8s.io                   Local                                                       True                       43d
v1.storage.k8s.io                      Local                                                       True                       43d
v1alpha1.certmanager.k8s.io            Local                                                       True                       3d22h
v1alpha1.crd.k8s.amazonaws.com         Local                                                       True                       43d
v1beta1.admission.certmanager.k8s.io   cert-manager/cointainers-cointainers-cert-manager-webhook   False (MissingEndpoints)   60m
v1beta1.admissionregistration.k8s.io   Local                                                       True                       43d
v1beta1.apiextensions.k8s.io           Local                                                       True                       43d
v1beta1.apps                           Local                                                       True                       43d
v1beta1.authentication.k8s.io          Local                                                       True                       43d
v1beta1.authorization.k8s.io           Local                                                       True                       43d
v1beta1.batch                          Local                                                       True                       43d
v1beta1.certificates.k8s.io            Local                                                       True                       43d
v1beta1.coordination.k8s.io            Local                                                       True                       43d
v1beta1.events.k8s.io                  Local                                                       True                       43d
v1beta1.extensions                     Local                                                       True                       43d
v1beta1.networking.k8s.io              Local                                                       True                       43d
v1beta1.node.k8s.io                    Local                                                       True                       43d
v1beta1.policy                         Local                                                       True                       43d
v1beta1.rbac.authorization.k8s.io      Local                                                       True                       43d
v1beta1.scheduling.k8s.io              Local                                                       True                       43d
v1beta1.storage.k8s.io                 Local                                                       True                       43d
v1beta1.webhook.cert-manager.io        cert-manager/cointainers-cointainers-cert-manager-webhook   False (MissingEndpoints)   3d22h
v1beta2.apps                           Local                                                       True                       43d
v2beta1.autoscaling                    Local                                                       True                       43d
v2beta2.autoscaling                    Local                                                       True                       43d

Oi.
Meu namespace de caso travar em Terminating when https://github.com/rancher/rancher/issues/21546#issuecomment -553635629

Talvez ajude.

https://medium.com/@newtondev/how -to-fix-kubernetes-namespace-deleting-stick-in-terminating-state-5ed75792647e

Isso funcionou como um campeão para mim

Eu também enfrentei o mesmo problema agora que está funcionando bem para mim. Por favor, consulte o seguinte documento e resolva seu problema

@zerkms bem, às vezes é um conselho legítimo, não é? Freqüentemente, os finalizadores em espera costumavam ser atendidos por objetos que foram excluídos como parte da exclusão do namespace. Neste caso, uma vez que não adianta mais esperar - não há mais nada que possa fazer a finalização -, corrigir os objetos da forma como o artigo descreve _é a única opção_.

Observe que o artigo é aplicável apenas se o problema _não foi resolvido_ aplicando as etapas listadas na página de Problemas Conhecidos, vinculada no início do artigo, que basicamente é o conselho de que o comentário que você vinculou se repete.

@zerkms bem, às vezes é um conselho legítimo, não é? Frequentemente, os finalizadores em espera costumavam ser servidos por objetos que foram excluídos como parte da exclusão do namespace

Nunca vi isso ser verdade para spec.finalizer em um namespace. Cada instância que vi envolveu o controlador de limpeza do namespace e foi causada por um objeto persistente no namespace (que esse conselho ficaria preso no etcd) ou uma API agregada sem resposta (que a remoção do namespace spec.finalizer pularia esperando, também retendo quaisquer recursos persistentes dessa API)

O artigo não avisa que ignorar a finalização do namespace pode deixar os recursos com namespace retidos no armazenamento e não é recomendado.

Nunca vi isso ser verdade para um spec.finalizer em um namespace

Sim, é isso mesmo, porque esse finalizador é implementado pelo próprio kubernetes, mas pode haver outros finalizadores em objetos dentro desse namespace, que podem ser implementados por objetos nesse namespace. Um exemplo que encontrei recentemente foi https://appscode.com/products/stash/ .

Ele coloca finalizadores em alguns de seus CRDs que devem ser atendidos pela implantação do operador stash. Mas com o operador stash já excluído, não há nada que possa remover a marca do finalizador desses CRDs e a exclusão do namespace fica paralisada. Nesse caso, corrigir esses finalizadores (não no próprio namespace, mas nesses objetos) é a única coisa sensata a fazer.

Espero que faça sentido.

Nesse caso, corrigir esses finalizadores (não no próprio namespace, mas nesses objetos) é a única coisa sensata a fazer.

Corrigir. Eu não faria objeções a isso em um cenário de limpeza "excluir todos os recursos", mas não é isso que o artigo vinculado aborda ... ele descreve como remover um spec.finalizer do namespace.

primeiro, tome um pequeno café e relaxe, agora vá para seus nós mestres k8s

kubectl cluster-info
O mestre do Kubernetes está sendo executado em https: // localhost : 6443
KubeDNS está sendo executado em https: // localhost : 6443 / api / v1 / namespaces / kube-system / services / kube- dns: dns / proxy
Para depurar e diagnosticar ainda mais os problemas do cluster, use 'kubectl cluster-info dump'.

agora execute o kube-proxy
proxy kubectl &
Começando a servir em 127.0.0.1:8001
salve o ID para excluí-lo mais tarde :)

  1. encontre o seu espaço de nome que decidiu não ser excluído :) para nós será o sistema de gado
    kubectl get ns
    Sistema de gado Terminando 1d

coloque no arquivo

  1. kubectl get namespace cattle-system -o json> tmp.json

edite o arquivo e remova os finalizadores
},
"spec": {
"finalizadores": [
"kubernetes"
]
},
após a edição, deve ficar assim 👍
},
"spec": {
"finalizadores": [
]
},
estamos quase lá 👍
curl -k -H "Content-Type: application / json" -X PUT --data-binary @ tmp.json http://127.0.0.1 : 8001 / api / v1 / namespaces / $ {NAMESPACE} / finalize

e se foi 👍

Novamente, não remova o finalizador, ele existe por um motivo. Em vez disso, tente descobrir quais recursos no NS estão com exclusão pendente:

  • Verificar se algum serviço não está disponível e, portanto, não atende seus recursos: kubectl get apiservice|grep False
  • Encontrar todos os recursos que ainda existem por meio de kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete (Parabéns a Jordan por isso)

A solução para este problema não é causar um curto-circuito no mecanismo de limpeza, mas sim descobrir o que impede a limpeza de ter êxito.

Ei pessoal! Eu sigo as dicas fornecidas por @alvaroaleman e fiz um script que inspeciona e tenta a exclusão limpa antes de fazer uma exclusão definitiva do namespace travado .

O que o script https://github.com/thyarles/knsk faz:

  1. Verifique se há recursos indisponíveis e peça para excluí-los
  2. Verifique se há recursos pendentes no namespace e peça para excluí-los
  3. Aguarde cerca de 5 minutos para ver se o Kubernetes faz uma exclusão limpa se o script faz alguma exclusão
  4. Forçar a exclusão do namespace travado

Espero que ajude.

@thyarles Muito obrigado. Usei sua maneira de resolver o problema.

$ kubectl get apiservices para verificar qual serviço não está disponível, excluir aqueles disponíveis é falso por $ kubectl delete apiservice [nome do serviço] e, depois disso, não haveria problemas para excluir um espaço de nomes.

Para nossa equipe, existem 3 apiservices indisponíveis, v1beta1.admission.certmanager.k8s.io, v1beta1.metrics.k8s.io e v1beta1.webhook.certmanager.k8s.io.

Observe que seu cluster está um pouco quebrado se o apiserver de métricas não estiver em execução, apenas remover o APIService não corrige a causa raiz.

@lavalamp the metrics é um serviço indisponível.

Sim, o que significa que o apiserver de métricas não está em execução, o que significa que o HPA não funciona em seu cluster e, provavelmente, em outras coisas também.

Sim. HPA não funciona agora. Não devo excluir as métricas e encontrar uma maneira de corrigi-las.

@thyarles Muito obrigado. Usei sua maneira de resolver o problema.

$ kubectl get apiservices para verificar qual serviço não está disponível, excluir aqueles disponíveis é falso por $ kubectl delete apiservice [nome do serviço] e, depois disso, não haveria problemas para excluir um espaço de nomes.

Para nossa equipe, existem 3 apiservices indisponíveis, v1beta1.admission.certmanager.k8s.io, v1beta1.metrics.k8s.io e v1beta1.webhook.certmanager.k8s.io.

@ xzhang007 fico feliz em saber! Agora você deve verificar por que seu v1beta1.metrics.k8s.io quebrou. Veja como gostaria:

`` `
$ kubectl -n kube-system obter todos | grep metrics

pod / metrics-server-64f74f8d47-r5vcq 2/2 Executando 9 119d
service / metrics-server ClusterIP xx.xx.xx.xx443 / TCP 201d
deployment.apps / metrics-server 1/1 1 1 201d
replicaset.apps / metrics-server-55c7f68d94 0 0 0 165d
replicaset.apps / metrics-server-5c696bb6d7 0 0 0 201d
replicaset.apps / metrics-server-5cdb8bb4fb 0 0 0 201d
replicaset.apps / metrics-server-64f74f8d47 1 1 1 119d
replicaset.apps / metrics-server-686789bb4b 0 0 0 145d```

$ kubectl -n kube-system obter todos | grep metrics

pod / metrics-server-5dcfd4dd9f-m2v9k 1/1 Executando 0 2d20h

service / metrics-server ClusterIP xx.xx.xx.xx443 / TCP 27d

deployment.apps / metrics-server 1/1 1 1 27d

replicaset.apps / metrics-server-5dcfd4dd9f 1 1 1 27d
replicaset.apps / metrics-server-7fcf9cc98b 0 0 0 27d

Sim. HPA não funciona agora. Não devo excluir as métricas e encontrar uma maneira de corrigi-las.

@ xzhang007 na verdade não funciona antes de você perceber o problema ... você só percebeu porque colocou seus namespaces excluídos no modo travado. Basta usar um gerenciador de pacotes helm para reimplantar seu metric-server ou apenas chamar o comando abaixo para corrigi-lo ( verifique o arquivo de implantação antes de aplicar ):

$ curl https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/metrics-server/metrics-server-deployment.yaml | kubectl apply -f -

A solução

Exclua v1beta1.metrics.k8s.io APIService

kubectl get ns ns-to-delete -o yaml
...
status:
  conditions:
  - lastTransitionTime: "2020-01-08T05:36:52Z"
    message: 'Discovery failed for some groups, 1 failing: unable to retrieve the
      complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently
      unable to handle the request'
...
kubectl get APIService
...
v1beta1.metrics.k8s.io                 kube-system/metrics-server   False (ServiceNotFound)
 kubectl delete v1beta1.metrics.k8s.io APIService

O cert-manager talvez não estivesse disponível porque foi configurado incorretamente. Por exemplo, use uma sintaxe errada no controlador de ingresso. Para nosso sistema, foi

"certmanager.k8s.io/cluster-issuer": "letsencrypt-prod"

e foi alterado para

"cert-manager.io/cluster-issuer": "letsencrypt-prod"

torná-lo disponível.

Conforme mencionado anteriormente neste problema, há outra maneira de encerrar um namespace usando API não exposta por kubectl usando uma versão moderna de kubectl onde kubectl replace --raw está disponível (não tenho certeza de qual versão). Desta forma, você não terá que gerar um processo kubectl proxy e evitar a dependência com curl (que em alguns ambientes como o busybox não está disponível). Na esperança de que isso ajude alguém, deixei isso aqui:

kubectl get namespace "stucked-namespace" -o json \
            | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
            | kubectl replace --raw /api/v1/namespaces/stucked-namespace/finalize -f -

Foi estabelecido se este é um problema corrigível? Parece haver muitas soluções hacky aqui, mas nada abordando o problema subjacente que é que nenhum de nós pode deletar nossos namespaces ....
Eu tenho isso no cluster EKS v1.14

Foi estabelecido se este é um problema corrigível? Parece haver muitas soluções hacky aqui, mas nada abordando o problema subjacente que é que nenhum de nós pode deletar nossos namespaces

O problema fundamental é que um grupo de API agregado em seu cluster não está disponível. É intencional que o controlador de limpeza do namespace seja bloqueado até que todas as APIs estejam disponíveis, para que ele possa verificar se todos os recursos de todos os grupos de API foram limpos para esse namespace.

para ppl tentando curl a API:

# Check all possible clusters, as your .KUBECONFIG may have multiple contexts:
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

# Select name of cluster you want to interact with from above output:
export CLUSTER_NAME="some_server_name"

# Point to the API server referring the cluster name
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

# Gets the token value
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 --decode)

# Explore the API with TOKEN
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#without -kubectl-proxy

Aqui está um script para fazer isso automaticamente. Precisa de jq :


#!/bin/bash

if [ -z "${1}" ] ; then
  echo -e "\nUsage: ${0} <name_of_the_namespace_to_remove_the_finalizer_from>\n"
  echo "Valid cluster names, based on your kube config:"
  kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
  exit 1
fi

kubectl proxy --port=8901 &
PID=$!
sleep 1

echo -n 'Current context : '
kubectl config current-context 
read -p "Are you sure you want to remove the finalizer from namespace ${1}? Press Ctrl+C to abort."

kubectl get namespace "${1}" -o json \
            | jq '.spec.finalizers = [ ]' \
            | curl -k \
            -H "Content-Type: application/json" \
            -X PUT --data-binary @- "http://localhost:8901/api/v1/namespaces/${1}/finalize"

kill -15 $PID

Todos: scripts para automatizar a remoção do finalizador fazem mais mal do que bem . Eles podem deixar bombas-relógio no (s) apiserver (es) agregado (s) que não estão disponíveis; se alguém recriar o namespace, de repente um monte de objetos antigos podem reaparecer.

A verdadeira solução é:

$ kubectl get api-services

# something in the list is unavailable. Figure out what it is and fix it.

# ... the namespace lifecycle controller will finish deleting the namespace.

Todos: scripts para automatizar a remoção do finalizador fazem mais mal do que bem . Eles podem deixar bombas-relógio no (s) apiserver (es) agregado (s) que não estão disponíveis; se alguém recriar o namespace, de repente um monte de objetos antigos podem reaparecer.

A verdadeira solução é:

$ kubectl get api-services

# something in the list is unavailable. Figure out what it is and fix it.

# ... the namespace lifecycle controller will finish deleting the namespace.

https://github.com/thyarles/knsk

Este script faz todas as verificações e tenta fazer uma exclusão limpa, incluindo a procura de recursos órfãos. Se o usuário quiser correr um risco, o script oferece uma opção --force para executar uma forma não recomendada de exclusão.

erro de digitação, deve ser apiservices

Este comando mostra apis não disponíveis:

kubectl get apiservices --template='{{range $api := .items}}{{range $api.status.conditions}}{{if eq .type "Available"}}{{$api.metadata.name}} {{.status}}{{"\n"}}{{end}}{{end}}{{end}}' | grep -i false

Este artigo certamente será útil para você:

https://access.redhat.com/solutions/5038511

Na verdade o que existe é um conflito nas apiserviços, eles poderiam validar o estado de saúde das apis em openshift:

oc get apiservices -o = custom-columns = " nome: .metadata.name , status: .status.conditions [0] .status"

a api que falhar precisará reiniciá-la, reiniciando o pod ou a implantação que pertence a essa API, depois disso, tente excluir o namespace.

$ oc delete namspace

e pronto, negócio arrumado !!

É muito desrespeitoso usar sua própria língua em um lugar onde todos concordam em falar inglês. 👎

Onde todos concordam em falar inglês?

Na quinta-feira, 30 de abril de 2020 às 17:58 theAkito [email protected] escreveu:

É muito desrespeitoso usar sua própria língua em um lugar onde todos
concorda em falar inglês. 👎

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubernetes/issues/60807#issuecomment-622137770 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ALGMKB6K4OU4X3XOYMALOBLRPHYCDANCNFSM4ETUOEPA
.

>

Chris, arquiteto-chefe @ brace.ai

-

Aviso de confidencialidade: este e-mail destina-se ao uso exclusivo do
destinatário (s) pretendido (s) e podem conter informações confidenciais, proprietárias ou
informação privilegiada. Se você não é o destinatário pretendido, você é
notificado que qualquer uso, revisão, disseminação, cópia ou ação tomada com base
nesta mensagem ou seus anexos, se houver, é proibido. Se você não está
o destinatário pretendido, entre em contato com o remetente por e-mail de resposta e
destruir ou excluir todas as cópias da mensagem original e quaisquer anexos.

pronto, com licença foi pela minha velocidade, foi consertado

Temos uma base de usuários multilíngue, é ruim o suficiente que nenhuma de nossas ferramentas seja internacionalizada, podemos pelo menos ser legais aqui no github, por favor.

@teoincontatto

Conforme mencionado anteriormente neste problema, há outra maneira de encerrar um namespace usando API não exposta por kubectl usando uma versão moderna de kubectl onde kubectl replace --raw está disponível (não tenho certeza de qual versão). Desta forma, você não terá que gerar um processo kubectl proxy e evitar a dependência com curl (que em alguns ambientes como o busybox não está disponível). Na esperança de que isso ajude alguém, deixei isso aqui:

kubectl get namespace "stucked-namespace" -o json \
            | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
            | kubectl replace --raw /api/v1/namespaces/stucked-namespace/finalize -f -

Funcionou perfeitamente!

Temos uma base de usuários multilíngue, é ruim o suficiente que nenhuma de nossas ferramentas seja internacionalizada, podemos pelo menos ser legais aqui no github, por favor.

Temos uma base de usuários multilíngue, é ruim o suficiente que nenhuma de nossas ferramentas seja internacionalizada, podemos pelo menos ser legais aqui no github, por favor.

Ainda tentando entender. Me perdoe. Posso ter clicado no polegar para baixo por engano.
Sim, de fato, as ferramentas não foram feitas com perfeição.
Isso, dar um polegar para baixo sem explicação, não faz sentido.

Quase sempre que tenho esse problema, depende dos CRDs. Exclua os CRDs se eles forem usados ​​apenas naquele namespace e, em seguida, você poderá prosseguir com a exclusão do finalizador e do namespace.

Conforme mencionado anteriormente neste problema, há outra maneira de encerrar um namespace usando API não exposta por kubectl usando uma versão moderna de kubectl onde kubectl replace --raw está disponível (não tenho certeza de qual versão). Desta forma, você não terá que gerar um processo kubectl proxy e evitar a dependência com curl (que em alguns ambientes como o busybox não está disponível). Na esperança de que isso ajude alguém, deixei isso aqui:

kubectl get namespace "stucked-namespace" -o json \
            | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
            | kubectl replace --raw /api/v1/namespaces/stucked-namespace/finalize -f -

@teoincontatto Obrigado! Isso finalmente funcionou!

Às vezes, apenas editar o manifesto do recurso online não funcionaria muito bem (quero dizer, remover o finalizers arquivado e salvar).
Então, eu ganhei um jeito novo de outros.

kubectl get namespace linkerd -o json > linkerd.json

# Where:/api/v1/namespaces/<your_namespace_here>/finalize
kubectl replace --raw "/api/v1/namespaces/linkerd/finalize" -f ./linkerd.json

Depois de executar esse comando, o namespace deve estar ausente da sua lista de namespaces. E funciona para mim.

Não apenas namespace mas também apóia os outros recursos.

Eu resolvi o problema removendo as linhas dos finalizadores usando: kubectl edit annoying-ns

Hmm ... Estou com esse problema agora :)
Hoje fiz uma atualização do meu cluster eks de 1,15 para 1,16.
Tudo parece bem até agora.
Mas meu "configcluster" de desenvolvimento era uma espécie de "damanged".
Então eu decido limpar tudo.

k deletar ns configcluster
....
agora isso trava (3h +): /

$ kubectl get namespace configcluster -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"configcluster"}}
  creationTimestamp: "2020-06-19T06:40:15Z"
  deletionTimestamp: "2020-06-19T09:19:16Z"
  name: configcluster
  resourceVersion: "22598109"
  selfLink: /api/v1/namespaces/configcluster
  uid: e50f0b53-b21e-4e6e-8946-c0a0803f031b
spec:
  finalizers:
  - kubernetes
status:
  conditions:
  - lastTransitionTime: "2020-06-19T09:19:21Z"
    message: 'Discovery failed for some groups, 1 failing: unable to retrieve the
      complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently
      unable to handle the request'
    reason: DiscoveryFailed
    status: "True"
    type: NamespaceDeletionDiscoveryFailure
  - lastTransitionTime: "2020-06-19T09:19:22Z"
    message: All legacy kube types successfully parsed
    reason: ParsedGroupVersions
    status: "False"
    type: NamespaceDeletionGroupVersionParsingFailure
  - lastTransitionTime: "2020-06-19T09:19:22Z"
    message: All content successfully deleted
    reason: ContentDeleted
    status: "False"
    type: NamespaceDeletionContentFailure
  phase: Terminating

Como podemos obter mais exposição a esse problema no pé?

Na sexta-feira, 19 de junho de 2020 às 4:46 AM Andreas Höhmann [email protected]
escrevi:

Hmm ... Estou com esse problema agora :)
Hoje fiz uma atualização do meu cluster eks de 1,15 para 1,16.
Tudo parece bem até agora.
Mas meu "configcluster" de desenvolvimento era uma espécie de "damanged".
Então eu decido limpar tudo.

k deletar ns configcluster
....
agora isso trava (3h +): /

$ kubectl get namespace configcluster -o yaml
apiVersion: v1
kind: namespace
metadados:
anotações:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion": "v1", "kind": "Namespace", "metadata": {"annotations": {}, "name": "configcluster"}}
creationTimestamp: "2020-06-19T06: 40: 15Z"
deletionTimestamp: "2020-06-19T09: 19: 16Z"
nome: configcluster
resourceVersion: "22598109"
selfLink: / api / v1 / namespaces / configcluster
uid: e50f0b53-b21e-4e6e-8946-c0a0803f031b
especificação:
finalizadores:

  • Kubernetes
    status:
    condições:
  • lastTransitionTime: "2020-06-19T09: 19: 21Z"
    mensagem: 'Falha na descoberta para alguns grupos, 1 falha: não foi possível recuperar o
    lista completa de APIs de servidor: metrics.k8s.io/v1beta1: o servidor está atualmente
    incapaz de lidar com o pedido '
    motivo: DiscoveryFailed
    status: "Verdadeiro"
    tipo: NamespaceDeletionDiscoveryFailure
  • lastTransitionTime: "2020-06-19T09: 19: 22Z"
    mensagem: Todos os tipos legados de kube analisados ​​com sucesso
    motivo: ParsedGroupVersions
    status: "Falso"
    tipo: NamespaceDeletionGroupVersionParsingFailure
  • lastTransitionTime: "2020-06-19T09: 19: 22Z"
    mensagem: Todo o conteúdo foi excluído com sucesso
    motivo: ContentDeleted
    status: "Falso"
    tipo: NamespaceDeletionContentFailure
    fase: Terminando

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubernetes/issues/60807#issuecomment-646543073 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AFLKRCLHIZ77X2Z3F5GAOCTRXMXVTANCNFSM4ETUOEPA
.

@bobhenkel bem, este problema foi encerrado, então, efetivamente, isso significa que não há nenhum problema (no que diz respeito a quaisquer itens acionáveis). Se você precisar de ajuda prática para lidar com uma situação semelhante, leia o tópico acima, existem alguns conselhos bons (e também alguns ruins).

No meu caso, tive que excluir manualmente meu balanceador de carga de entrada do console do GCP Network Service. Eu tinha criado manualmente o front-end do balanceador de carga diretamente no console. Depois de excluir o balanceador de carga, o namespace foi excluído automaticamente.

Estou suspeitando que o Kubernetes não queria excluir, pois o estado do balanceador de carga era diferente do estado no manifesto.

Vou tentar automatizar a criação do front-end de entrada usando anotações a seguir para ver se consigo resolver esse problema.

Às vezes, apenas editar o manifesto do recurso online não funcionaria muito bem (quero dizer, remover o finalizers arquivado e salvar).
Então, eu ganhei um jeito novo de outros.

kubectl get namespace linkerd -o json > linkerd.json

# Where:/api/v1/namespaces/<your_namespace_here>/finalize
kubectl replace --raw "/api/v1/namespaces/linkerd/finalize" -f ./linkerd.json

Depois de executar esse comando, o namespace deve estar ausente da sua lista de namespaces. E funciona para mim.

Não apenas namespace mas também apóia os outros recursos.

você é uma estrela funcionou

Às vezes, apenas editar o manifesto do recurso online não funcionaria muito bem (quero dizer, remover o finalizers arquivado e salvar).
Então, eu ganhei um jeito novo de outros.

kubectl get namespace linkerd -o json > linkerd.json

# Where:/api/v1/namespaces/<your_namespace_here>/finalize
kubectl replace --raw "/api/v1/namespaces/linkerd/finalize" -f ./linkerd.json

Depois de executar esse comando, o namespace deve estar ausente da sua lista de namespaces. E funciona para mim.

Não apenas namespace mas também apóia os outros recursos.

Tentei muitas soluções, mas esta é a que funcionou para mim. Obrigado!

Essa realmente deveria ser a resposta "aceita" - ela resolveu completamente a raiz do problema!

Pegue no link acima:

Esse não é o caminho certo, especialmente em um ambiente de produção.

Hoje eu tive o mesmo problema. Ao remover o finalizador, você acabará com sobras em vários estados. Você realmente deve encontrar o que está impedindo a exclusão completa.

Consulte https://github.com/kubernetes/kubernetes/issues/60807#issuecomment -524772920

(também, infelizmente, 'kubetctl get all' não relata todas as coisas, você precisa usar comandos semelhantes, como no link)

Meu caso - deletando o namespace 'cert-manager'. Na saída de 'kubectl get apiservice -o yaml', encontrei APIService 'v1beta1.admission.certmanager.k8s.io' com status = False. Este apiservice fazia parte do cert-manager, que acabei de excluir. Portanto, em 10 segundos após eu 'kubectl excluir apiservice v1beta1.admission.certmanager.k8s.io', o namespace desapareceu.

Espero que ajude.


Com isso dito, escrevi um pequeno microsserviço para ser executado como um CronJob a cada hora que exclui automaticamente os namespaces de terminação.

Você pode encontrá-lo aqui: https://github.com/oze4/service.remove-terminating-namespaces

Eu escrevi um pequeno microsserviço para ser executado como um CronJob a cada hora que exclui automaticamente os namespaces de terminação.

Você pode encontrá-lo aqui: https://github.com/oze4/service.remove-terminating-namespaces

Mais um oneliner:

for ns in $(kubectl get ns --field-selector status.phase=Terminating -o jsonpath='{.items[*].metadata.name}'); do  kubectl get ns $ns -ojson | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/$ns/finalize" -f -; done

Mas excluir namespaces presos não é uma boa solução. O jeito certo é descobrir por que está preso. O motivo muito comum é a indisponibilidade de serviço (s) de API que impede o cluster de finalizar namespaces.
Por exemplo, não excluí o Knative corretamente:

$ kubectl get apiservice|grep False
NAME                                   SERVICE                             AVAILABLE   AGE
v1beta1.custom.metrics.k8s.io          knative-serving/autoscaler          False (ServiceNotFound)   278d

Excluir resolveu o problema

k delete apiservice v1beta1.custom.metrics.k8s.io
apiservice.apiregistration.k8s.io "v1beta1.custom.metrics.k8s.io" deleted
$  k create ns test2
namespace/test2 created
$ k delete ns test2
namespace "test2" deleted
$ kgns test2
Error from server (NotFound): namespaces "test2" not found  

Eu escrevi um pequeno microsserviço para ser executado como um CronJob a cada hora que exclui automaticamente os namespaces de terminação.

Você pode encontrá-lo aqui: https://github.com/oze4/service.remove-terminating-namespaces

bom trabalho.

Tive um problema semelhante no 1.18 em um cluster de laboratório k8s e adicionei uma nota para talvez ajudar outros. Eu estava trabalhando com a API de métricas e com métricas personalizadas em particular. Depois de excluir esses objetos k8s para recriá-los, ele parou na exclusão do namespace com um erro de que o endpoint da API de métricas não pôde ser encontrado. Colocando de volta em outro namespace, tudo ficou claro imediatamente.

Isso estava no namespace em status.conditions.message:

Discovery failed for some groups, 4 failing: unable to retrieve the
complete list of server APIs: custom.metrics.k8s.io/v1beta1: the server is currently
unable to handle the request, custom.metrics.k8s.io/v1beta2: the server is currently
unable to handle the request, external.metrics.k8s.io/v1beta1: the server is
currently unable to handle the request, metrics.k8s.io/v1beta1: the server is

Mais um oneliner:

for ns in $(kubectl get ns --field-selector status.phase=Terminating -o jsonpath='{.items[*].metadata.name}'); do  kubectl get ns $ns -ojson | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/$ns/finalize" -f -; done

Mas excluir namespaces presos não é uma boa solução. O jeito certo é descobrir por que está preso. O motivo muito comum é a indisponibilidade de serviço (s) de API que impede o cluster de finalizar namespaces.
Por exemplo, não excluí o Knative corretamente:

$ kubectl get apiservice|grep False
NAME                                   SERVICE                             AVAILABLE   AGE
v1beta1.custom.metrics.k8s.io          knative-serving/autoscaler          False (ServiceNotFound)   278d

Excluir resolveu o problema

k delete apiservice v1beta1.custom.metrics.k8s.io
apiservice.apiregistration.k8s.io "v1beta1.custom.metrics.k8s.io" deleted
$  k create ns test2
namespace/test2 created
$ k delete ns test2
namespace "test2" deleted
$ kgns test2
Error from server (NotFound): namespaces "test2" not found  

Definitivamente o forro mais limpo! É importante observar que nenhuma dessas "soluções" realmente resolve o problema raiz.

Veja aqui a solução correta

Essa é a mensagem que deveria ser espalhada: sorria: não "mais um liner".

definitivamente o forro mais limpo! É importante observar que nenhuma dessas "soluções" realmente resolve o problema raiz.

Esta solução resolve uma de todas as possibilidades. Para procurar todas as causas raiz possíveis e corrigi-las, uso este script: https://github.com/thyarles/knsk

@thyarles muito bom!

Não use modify finalize para excluir o namespace. Isso vai causar um erro

image

Descubra a causa do encerramento do namespace. Orientações de solução de problemas atualmente conhecidas

  • terminação de pod
  • cert-manager webhook block secrte

Eu encontro o mesmo problema:

# sudo kubectl get ns
NAME                   STATUS        AGE
cattle-global-data     Terminating   8d
cattle-global-nt       Terminating   8d
cattle-system          Terminating   8d
cert-manager           Active        8d
default                Active        10d
ingress-nginx          Terminating   9d
kube-node-lease        Active        10d
kube-public            Active        10d
kube-system            Active        10d
kubernetes-dashboard   Terminating   4d6h
local                  Active        8d
p-2sfgk                Active        8d
p-5kdx9                Active        8d
# sudo kubectl get all -n kubernetes-dashboard
No resources found in kubernetes-dashboard namespace.
# sudo kubectl get namespace kubernetes-dashboard  -o json 
{
    "apiVersion": "v1",
    "kind": "Namespace",
    "metadata": {
        "annotations": {
            "cattle.io/status": "{\"Conditions\":[{\"Type\":\"ResourceQuotaInit\",\"Status\":\"True\",\"Message\":\"\",\"LastUpdateTime\":\"2020-09-29T01:15:46Z\"},{\"Type\":\"InitialRolesPopulated\",\"Status\":\"True\",\"Message\":\"\",\"LastUpdateTime\":\"2020-09-29T01:15:46Z\"}]}",
            "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"kubernetes-dashboard\"}}\n",
            "lifecycle.cattle.io/create.namespace-auth": "true"
        },
        "creationTimestamp": "2020-09-29T01:15:45Z",
        "deletionGracePeriodSeconds": 0,
        "deletionTimestamp": "2020-10-02T07:59:52Z",
        "finalizers": [
            "controller.cattle.io/namespace-auth"
        ],
        "managedFields": [
            {
                "apiVersion": "v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            "f:cattle.io/status": {},
                            "f:lifecycle.cattle.io/create.namespace-auth": {}
                        },
                        "f:finalizers": {
                            ".": {},
                            "v:\"controller.cattle.io/namespace-auth\"": {}
                        }
                    }
                },
                "manager": "Go-http-client",
                "operation": "Update",
                "time": "2020-09-29T01:15:45Z"
            },
            {
                "apiVersion": "v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:kubectl.kubernetes.io/last-applied-configuration": {}
                        }
                    }
                },
                "manager": "kubectl-client-side-apply",
                "operation": "Update",
                "time": "2020-09-29T01:15:45Z"
            },
            {
                "apiVersion": "v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:status": {
                        "f:phase": {}
                    }
                },
                "manager": "kube-controller-manager",
                "operation": "Update",
                "time": "2020-10-02T08:13:49Z"
            }
        ],
        "name": "kubernetes-dashboard",
        "resourceVersion": "3662184",
        "selfLink": "/api/v1/namespaces/kubernetes-dashboard",
        "uid": "f1944b81-038b-48c2-869d-5cae30864eaa"
    },
    "spec": {},
    "status": {
        "conditions": [
            {
                "lastTransitionTime": "2020-10-02T08:13:49Z",
                "message": "All resources successfully discovered",
                "reason": "ResourcesDiscovered",
                "status": "False",
                "type": "NamespaceDeletionDiscoveryFailure"
            },
            {
                "lastTransitionTime": "2020-10-02T08:11:49Z",
                "message": "All legacy kube types successfully parsed",
                "reason": "ParsedGroupVersions",
                "status": "False",
                "type": "NamespaceDeletionGroupVersionParsingFailure"
            },
            {
                "lastTransitionTime": "2020-10-02T08:11:49Z",
                "message": "All content successfully deleted, may be waiting on finalization",
                "reason": "ContentDeleted",
                "status": "False",
                "type": "NamespaceDeletionContentFailure"
            },
            {
                "lastTransitionTime": "2020-10-02T08:11:49Z",
                "message": "All content successfully removed",
                "reason": "ContentRemoved",
                "status": "False",
                "type": "NamespaceContentRemaining"
            },
            {
                "lastTransitionTime": "2020-10-02T08:11:49Z",
                "message": "All content-preserving finalizers finished",
                "reason": "ContentHasNoFinalizers",
                "status": "False",
                "type": "NamespaceFinalizersRemaining"
            }
        ],
        "phase": "Terminating"
    }

#  sudo kubectl version

Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.2", GitCommit:"f5743093fd1c663cb0cbc89748f730662345d44d", GitTreeState:"clean", BuildDate:"2020-09-16T13:41:02Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.2", GitCommit:"f5743093fd1c663cb0cbc89748f730662345d44d", GitTreeState:"clean", BuildDate:"2020-09-16T13:32:58Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}

Você pode usar etcdctl para encontrar recursos não excluídos

ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/peer.crt \
--key=/etc/kubernetes/pki/etcd/peer.key \
get /registry --prefix | grep <namespace>

Basta copiar e colar no seu terminal

for NS in $(kubectl get ns 2>/dev/null | grep Terminating | cut -f1 -d ' '); do
  kubectl get ns $NS -o json > /tmp/$NS.json
  sed -i '' "s/\"kubernetes\"//g" /tmp/$NS.json
  kubectl replace --raw "/api/v1/namespaces/$NS/finalize" -f /tmp/$NS.json
done
/tmp/$NS.json

isso funcionou para mim e corri após verificar se não havia objetos k8s pendurados no ns. Obrigado!

Usei isso para remover um namespace preso em Terminated

exemplo:

kubectl get namespace openebs -o json | jq -j '.spec.finalizers=null' > tmp.json 
kubectl replace --raw "/api/v1/namespaces/openebs/finalize" -f ./tmp.json

Para todos os googlers que se depararam com namespaces presos em Terminating on Rancher namespaces específicos (por exemplo, gado-system), o seguinte comando modificado (original do grebois) funcionou para mim:

for NS in $(kubectl get ns 2>/dev/null | grep Terminating | cut -f1 -d ' '); do
  kubectl get ns $NS -o json > /tmp/$NS.json
  sed -i "s/\"controller.cattle.io\/namespace-auth\"//g" /tmp/$NS.json
  kubectl replace --raw "/api/v1/namespaces/$NS/finalize" -f /tmp/$NS.json
done

Pessoal, só para sua informação, quando o vídeo para esta palestra sobre o kubecon for lançado, pretendo criar um link para ele e alguns dos comentários úteis acima, e bloquear este problema.

Gravei uma explicação de 10 minutos do que está acontecendo e apresentei nesta sessão SIG Deep Dive .

Aqui está um comentário correto com 65 votos positivos

Mencionado várias vezes acima, este post médio é um exemplo de como fazer as coisas da maneira certa. Encontre e corrija o serviço de API corrompido.

Todos os liners que apenas removem os finalizadores no namespace tratam da causa raiz e deixam seu cluster sutilmente quebrado, o que o afetará mais tarde. Então, por favor, não faça isso. A correção da causa raiz geralmente é mais fácil de qualquer maneira. Parece que as pessoas gostam de postar variações sobre este tema, embora já haja várias respostas corretas no tópico, então vou bloquear o problema agora, para garantir que este comentário permaneça no final.

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