我发现的最可靠的方法是:
- 当应用从服务器返回“删除你自己”
我在kube群集上创建一个 问题是我想在应用程序的自删除过程中删除Namespace
,然后在该命名空间中安装我的应用。该应用程序向服务器发送常规的心跳请求,并且如果它从服务器收到“ remove self”]]响应,它将通过在整个kube命名空间上调用delete来删除自身。我还通过创建ClusterRoleBinding
,使ServiceAccount
服从ClusterRoleBinding
并使用此ServiceAccount
运行Pod,来为应用集群提供广泛的访问权限。ClusterRoleBinding
(如果可能的话)。如果我之前删除了ClusterRoleBinding
,则该应用程序将无法在Namespace
上执行删除操作,因此这似乎是鸡与蛋的问题。有办法吗?
这是我已经尝试无济于事的东西:
在应用容器中添加了PreStop处理程序。因此,现在当应用程序在整个命名空间上调用delete时,kube会在杀死容器之前调用此处理程序。在此PreStop处理程序中,如果我睡了5秒钟以上,然后在ClusterRoleBinding
上调用delete,我会从kubernetes返回“ Unauthorized”
这使我认为也许链接到ServiceAccount
的ClusterRoleBinding
在应用程序有机会在PreStop处理程序中删除ClusterRoleBinding
之前就被删除了。因此,为了测试这一点,在对命名空间发出delete之前,我向ServiceAccount
添加了终结器,然后在PreStop处理程序中等待5秒钟,对ClusterRoleBinding
再次发出delete(再次返回“未经授权”的错误) ,
ServiceAccount
对象,从ServiceAccount
(获得错误的“ error =” finalizer对象不存在”“),因为它无法删除空对象上的终结器。[当我使用kubectl时,我发现ServiceAccount
存在但处于“ Terminated”状态,而终结器仍处于设置状态。
ServiceAccount
处于"Terminating"
状态时,即使尚未硬删除kube也会撤销访问吗?
是否有办法从需要删除的ClusterRoleBinding
中运行的同一进程中删除Namespace
和Namespace
?
任何帮助将不胜感激!
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群集上创建一个名称空间,然后在该名称空间中安装我的应用程序。该应用程序向服务器发送常规的心跳请求,如果它从服务器收到“删除自己”的响应,则它会...
响应时,它使我发现的最可靠的方法是:
- 当应用从服务器返回“删除你自己”
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) }
我发现的最可靠的方法是: