Удалите ClusterRoleBinding и Namespace из процесса, работающего в том же пространстве имен в Kubernetes - PullRequest
0 голосов
/ 18 февраля 2020

Я создаю Namespace в кластере кубов и устанавливаю свое приложение в этом пространстве имен. Приложение отправляет регулярные запросы сердцебиения на сервер и, если оно получает «удалить себя» ответ от сервера, оно удаляет себя, вызывая delete во всем пространстве имен куба. Я также предоставляю кластеру приложений широкий доступ, создав ClusterRoleBinding, сделав ServiceAccount подчиненным ClusterRoleBinding и запустив модуль с этим ServiceAccount.

. Проблема в том, что я хочу удалить ClusterRoleBinding как часть процесса самостоятельного удаления приложения (если это возможно). Если я удалю ClusterRoleBinding до этого, приложение не сможет выполнить удаление на Namespace, поэтому это похоже на проблему курицы и яйца. Есть ли способ сделать это?

Это то, что я уже пытался безрезультатно:

  • Добавлен обработчик PreStop в контейнере приложения. Так что теперь, когда приложение вызывает delete во всем пространстве имен, kube вызывает этот обработчик перед тем, как уничтожить контейнер. В этом обработчике PreStop, если я сплю более 5 сек c перед вызовом удаления на ClusterRoleBinding, я получаю "Несанкционированный" ответ от kubernetes.

  • Это привело меня к мысли, что, возможно, ServiceAccount, связанный с ClusterRoleBinding, будет удален до того, как приложение сможет удалить ClusterRoleBinding в обработчике PreStop. Таким образом, чтобы проверить это, перед выдачей delete в Пространстве имен я добавляю финализатор к ServiceAccount, затем в обработчике PreStop жду 5 se c, выдача delete на ClusterRoleBinding (снова get "Unauthorized «ошибка возвращается», , затем я получаю объект ServiceAccount по имени (возвращает ошибку «Несанкционированный») , удаляем финализатор из ServiceAccount (ошибка получения »= "финализатор не существует для объекта ''") , потому что он не может удалить финализатор для пустого объекта. Когда я использую kubectl, я обнаружил, что ServiceAccount существует, но находится в "Завершается" состояние, как и ожидалось, с финализатором по-прежнему установлен.

Отменяет ли kube доступ, когда ServiceAccount находится в состоянии "Terminating", даже если он еще не удален?

Есть ли способ удалить ClusterRoleBinding и Namespace из того же процесса, который выполняется в Namespace, который необходимо удалить? (Учитывая, что ClusterRoleBinding мы хотим удалить дает приложению разрешение на удаление Namespace в первую очередь)

Любая помощь будет принята с благодарностью!

Определения YAML для ClusterRoleBinding и ServiceAccount приведены ниже:

### ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
    creationTimestamp: null
    name: xyz-myapp-cluster-admin
roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: cluster-admin
subjects:
- kind: ServiceAccount
  name: xyz
  namespace: xyz-myapp

### ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
    creationTimestamp: null
    name: xyz
    namespace: xyz-myapp

Соответствующие журналы приложений:

time="2020-02-18T16:08:33Z" level=info msg="App instructed to remove itself"
time="2020-02-18T16:08:33Z" level=info msg="Created finalizer 'xyz.myapp.com/my-finalizer' on ServiceAccount"
time="2020-02-18T16:08:33Z" level=info msg="Called delete on Namespace"
time="2020-02-18T16:08:38Z" level=info msg="PreStop handler called"
time="2020-02-18T16:08:38Z" level=info msg="----- sleeping for 5 sec -----"
time="2020-02-18T16:08:43Z" level=info msg="Deleting ClusterRoleBinding"
time="2020-02-18T16:08:43Z" level=warning msg="Failed to delete ClusterRoleBinding" error="Unexpected error removing ClusterRolebinding: Unauthorized"
time="2020-02-18T16:08:43Z" level=warning msg="Failed to get ServiceAccount" error=Unauthorized
time="2020-02-18T16:08:43Z" level=warning msg="Failed to remove finalizer from ServiceAccount" error="finalizer 'xyz.myapp.com/my-finalizer' doesn't exist for object ''"

1 Ответ

1 голос
/ 19 февраля 2020

После просмотра документации kubernetes, я нашел самый надежный способ сделать это:

  1. Когда приложение получает ответ "удалить себя" с сервера, которое оно делает ClusterRoleBinding владелец Namespace, в котором запущено приложение.
  2. Это можно сделать, добавив ClusterRoleBinding в medatadata.owerReferences пространства имен, используя патч.
  3. Как только ClusterRoleBinding успешно добавлен в качестве владельца для Namespace, затем приложение может вызвать delete на ClusterRoleBinding, используя DeletePropagationBackground.

Ниже приведен пример того, как патч, добавляющий ClusterRoleBinding к Может применяться ownerReferences из Namespace (в Golang).

import (
    "encoding/json"
    "k8s.io/client-go/kubernetes"
    v1 "k8s.io/api/core/v1"
    rbacv1 "k8s.io/api/rbac/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type ownerReferencePatch struct {
    Op    string                  `json:"op"`
    Path  string                  `json:"path"`
    Value []metav1.OwnerReference `json:"value"`
}

func AddClusterRoleBindingOwnerReferenceToNamespace(client kubernetes.Interface, crb *rbacv1.ClusterRoleBinding, ns *v1.Namespace) (*v1.Namespace, error) {
    patch, err := json.Marshal([]ownerReferencePatch{
        {
            Op:   "add",
            Path: "/metadata/ownerReferences",
            Value: []metav1.OwnerReference{
                {
                    APIVersion:         crb.RoleRef.APIGroup,
                    BlockOwnerDeletion: func(in bool) *bool {return &in}(true),
                    Kind:               "ClusterRoleBinding",
                    Name:               crb.GetName(),
                    UID:                crb.GetUID(),
                },
            },
        },
    })
    if err != nil {
        return nil, err
    }

    return client.CoreV1().Namespaces().Patch(ns.GetName(), types.JSONPatchType, patch)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...