Improve cleaning up

Set up a proper owner reference to StatefulSet, and delete with
foreground policy to not leave orphans.
This commit is contained in:
Dmitrii Dolgov 2020-01-15 16:46:03 +01:00
parent fb43ee92d6
commit 4c69b2b996
2 changed files with 42 additions and 24 deletions

View File

@ -1804,6 +1804,26 @@ func (c *Cluster) generateConnPoolPodTemplate(spec *acidv1.PostgresSpec) (
return podTemplate, nil return podTemplate, nil
} }
// Return an array of ownerReferences to make an arbitraty object dependent on
// the StatefulSet. Dependency is made on StatefulSet instead of PostgreSQL CRD
// while the former is represent the actual state, and only it's deletion means
// we delete the cluster (e.g. if CRD was deleted, StatefulSet somehow
// survived, we can't delete an object because it will affect the functioning
// cluster).
func (c *Cluster) ownerReferences() []metav1.OwnerReference {
controller := true
return []metav1.OwnerReference{
{
UID: c.Statefulset.ObjectMeta.UID,
APIVersion: "apps/v1",
Kind: "StatefulSet",
Name: c.Statefulset.ObjectMeta.Name,
Controller: &controller,
},
}
}
func (c *Cluster) generateConnPoolDeployment(spec *acidv1.PostgresSpec) ( func (c *Cluster) generateConnPoolDeployment(spec *acidv1.PostgresSpec) (
*appsv1.Deployment, error) { *appsv1.Deployment, error) {
@ -1823,17 +1843,13 @@ func (c *Cluster) generateConnPoolDeployment(spec *acidv1.PostgresSpec) (
Namespace: c.Namespace, Namespace: c.Namespace,
Labels: c.labelsSet(true), Labels: c.labelsSet(true),
Annotations: map[string]string{}, Annotations: map[string]string{},
// make Postgresql CRD object its owner, so that if CRD object is // make StatefulSet object its owner to represent the dependency.
// deleted, this object will be deleted even if something went // By itself StatefulSet is being deleted with "Ophaned"
// wrong and operator didn't deleted it. // propagation policy, which means that it's deletion will not
OwnerReferences: []metav1.OwnerReference{ // clean up this deployment, but there is a hope that this object
{ // will be garbage collected if something went wrong and operator
UID: c.Statefulset.ObjectMeta.UID, // didn't deleted it.
APIVersion: "apps/v1", OwnerReferences: c.ownerReferences(),
Kind: "StatefulSet",
Name: c.Statefulset.ObjectMeta.Name,
},
},
}, },
Spec: appsv1.DeploymentSpec{ Spec: appsv1.DeploymentSpec{
Replicas: numberOfInstances, Replicas: numberOfInstances,
@ -1866,17 +1882,13 @@ func (c *Cluster) generateConnPoolService(spec *acidv1.PostgresSpec) *v1.Service
Namespace: c.Namespace, Namespace: c.Namespace,
Labels: c.labelsSet(true), Labels: c.labelsSet(true),
Annotations: map[string]string{}, Annotations: map[string]string{},
// make Postgresql CRD object its owner, so that if CRD object is // make StatefulSet object its owner to represent the dependency.
// deleted, this object will be deleted even if something went // By itself StatefulSet is being deleted with "Ophaned"
// wrong and operator didn't deleted it. // propagation policy, which means that it's deletion will not
OwnerReferences: []metav1.OwnerReference{ // clean up this service, but there is a hope that this object will
{ // be garbage collected if something went wrong and operator didn't
UID: c.Postgresql.ObjectMeta.UID, // deleted it.
APIVersion: acidv1.APIVersion, OwnerReferences: c.ownerReferences(),
Kind: acidv1.PostgresqlKind,
Name: c.Postgresql.ObjectMeta.Name,
},
},
}, },
Spec: serviceSpec, Spec: serviceSpec,
} }

View File

@ -154,10 +154,14 @@ func (c *Cluster) deleteConnectionPool() (err error) {
return nil return nil
} }
// set delete propagation policy to foreground, so that replica set will be
// also deleted.
policy := metav1.DeletePropagationForeground
options := metav1.DeleteOptions{PropagationPolicy: &policy}
deployment := c.ConnectionPool.Deployment deployment := c.ConnectionPool.Deployment
err = c.KubeClient. err = c.KubeClient.
Deployments(deployment.Namespace). Deployments(deployment.Namespace).
Delete(deployment.Name, c.deleteOptions) Delete(deployment.Name, &options)
if !k8sutil.ResourceNotFound(err) { if !k8sutil.ResourceNotFound(err) {
c.logger.Debugf("Connection pool deployment was already deleted") c.logger.Debugf("Connection pool deployment was already deleted")
@ -168,10 +172,12 @@ func (c *Cluster) deleteConnectionPool() (err error) {
c.logger.Infof("Connection pool deployment %q has been deleted", c.logger.Infof("Connection pool deployment %q has been deleted",
util.NameFromMeta(deployment.ObjectMeta)) util.NameFromMeta(deployment.ObjectMeta))
// set delete propagation policy to foreground, so that all the dependant
// will be deleted.
service := c.ConnectionPool.Service service := c.ConnectionPool.Service
err = c.KubeClient. err = c.KubeClient.
Services(service.Namespace). Services(service.Namespace).
Delete(service.Name, c.deleteOptions) Delete(service.Name, &options)
if !k8sutil.ResourceNotFound(err) { if !k8sutil.ResourceNotFound(err) {
c.logger.Debugf("Connection pool service was already deleted") c.logger.Debugf("Connection pool service was already deleted")