从同一命名空间中运行的进程删除ClusterRoleBinding和命名空间

问题描述 投票:0回答:1

我在kube群集上创建一个Namespace,然后在该命名空间中安装我的应用。该应用程序向服务器发送常规的心跳请求,并且如果它从服务器收到“ remove self”]]响应,它将通过在整个kube命名空间上调用delete来删除自身。我还通过创建ClusterRoleBinding,使ServiceAccount服从ClusterRoleBinding并使用此ServiceAccount运行Pod,来为应用集群提供广泛的访问权限。

问题是我想在应用程序的自删除过程中删除ClusterRoleBinding(如果可能的话)。如果我之前删除了ClusterRoleBinding,则该应用程序将无法在Namespace上执行删除操作,因此这似乎是鸡与蛋的问题。有办法吗?

这是我已经尝试无济于事的东西:

  • 在应用容器中添加了PreStop处理程序。因此,现在当应用程序在整个命名空间上调用delete时,kube会在杀死容器之前调用此处理程序。在此PreStop处理程序中,如果我睡了5秒钟以上,然后在ClusterRoleBinding上调用delete,我会从kubernetes返回“ Unauthorized”

    响应。
  • 这使我认为也许链接到ServiceAccountClusterRoleBinding在应用程序有机会在PreStop处理程序中删除ClusterRoleBinding之前就被删除了。因此,为了测试这一点,在对命名空间发出delete之前,我向ServiceAccount添加了终结器,然后在PreStop处理程序中等待5秒钟,对ClusterRoleBinding 再次发出delete(再次返回“未经授权”的错误) ,

    然后按名称((返回“未经授权的错误”))的形式获得ServiceAccount对象,从ServiceAccount (获得错误的“ error =” finalizer对象不存在”“),因为它无法删除空对象上的终结器。
  • [当我使用kubectl时,我发现ServiceAccount存在但处于“ Terminated”状态,而终结器仍处于设置状态。

    ServiceAccount处于"Terminating"状态时,即使尚未硬删除kube也会撤销访问吗?

是否有办法从需要删除的ClusterRoleBinding中运行的同一进程中删除NamespaceNamespace

任何帮助将不胜感激!

ClusterRoleBinding和ServiceAccounts的YAML定义如下:

### 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 dmt 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 ''"

我在kube群集上创建一个名称空间,然后在该名称空间中安装我的应用程序。该应用程序向服务器发送常规的心跳请求,如果它从服务器收到“删除自己”的响应,则它会...

我发现的最可靠的方法是:

  1. 当应用从服务器返回“删除你自己”
响应时,它使ClusterRoleBinding成为应用运行所在Namespace的所有者。
  • 这可以通过在命名空间的ClusterRoleBinding下添加medatadata.owerReferences来完成。
  • 一旦成功将ClusterRoleBinding添加为Namespace的所有者,那么应用程序就可以使用DeletePropagationBackground在ClusterRoleBinding上调用delete。

    对于上述情况,这是将ownerReference补丁添加到命名空间(在Golang中)的方式。

  • 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) {
        temp := true
        patch, err := json.Marshal([]ownerReferencePatch{
            {
                Op:   "add",
                Path: "/metadata/ownerReferences",
                Value: []metav1.OwnerReference{
                    {
                        APIVersion:         crb.RoleRef.APIGroup,
                        Controller:         &temp,
                        BlockOwnerDeletion: &temp,
                        Kind:               "ClusterRoleBinding",
                        Name:               crb.GetName(),
                        UID:                crb.GetUID(),
                    },
                },
            },
        })
        if err != nil {
            return nil, err
        }
    
        return client.CoreV1().Namespaces().Patch(namespace, patchType, patch)
    }
    
    kubernetes rbac
    1个回答
    0
    投票

    我发现的最可靠的方法是:

    1. 当应用从服务器返回“删除你自己”
    © www.soinside.com 2019 - 2024. All rights reserved.