diff --git a/cilium-etcd-operator.yaml b/cilium-etcd-operator.yaml index 1803cd5..6aced93 100644 --- a/cilium-etcd-operator.yaml +++ b/cilium-etcd-operator.yaml @@ -36,6 +36,16 @@ spec: fieldRef: apiVersion: v1 fieldPath: metadata.namespace + - name: CILIUM_ETCD_OPERATOR_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: CILIUM_ETCD_OPERATOR_POD_UID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.uid image: docker.io/cilium/cilium-etcd-operator:v2.0.0 imagePullPolicy: IfNotPresent name: cilium-etcd-operator diff --git a/etcd-operator/descriptors.go b/etcd-operator/descriptors.go index 81eaac9..13cd6bf 100644 --- a/etcd-operator/descriptors.go +++ b/etcd-operator/descriptors.go @@ -21,16 +21,28 @@ import ( core_v1 "k8s.io/api/core/v1" apiextensions_v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ) +var blockOwnerDeletion = true + // EtcdOperatorDeployment returns the etcd operator deployment that is // for the given namespace. -func EtcdOperatorDeployment(namespace string) *apps_v1beta2.Deployment { +func EtcdOperatorDeployment(namespace, ownerName, ownerUID string) *apps_v1beta2.Deployment { nReplicas := int32(1) return &apps_v1beta2.Deployment{ ObjectMeta: meta_v1.ObjectMeta{ Name: "etcd-operator", Namespace: namespace, + OwnerReferences: []meta_v1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Pod", + Name: ownerName, + UID: types.UID(ownerUID), + BlockOwnerDeletion: &blockOwnerDeletion, + }, + }, }, Spec: apps_v1beta2.DeploymentSpec{ Replicas: &nReplicas, @@ -81,10 +93,19 @@ func EtcdOperatorDeployment(namespace string) *apps_v1beta2.Deployment { } // EtcdCRD returns the etcd CRD. -func EtcdCRD() *apiextensions_v1beta1.CustomResourceDefinition { +func EtcdCRD(ownerName, ownerUID string) *apiextensions_v1beta1.CustomResourceDefinition { return &apiextensions_v1beta1.CustomResourceDefinition{ ObjectMeta: meta_v1.ObjectMeta{ Name: "etcdclusters.etcd.database.coreos.com", + OwnerReferences: []meta_v1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Pod", + Name: ownerName, + UID: types.UID(ownerUID), + BlockOwnerDeletion: &blockOwnerDeletion, + }, + }, }, Spec: apiextensions_v1beta1.CustomResourceDefinitionSpec{ Group: "etcd.database.coreos.com", diff --git a/main.go b/main.go index cfc3097..4541a14 100644 --- a/main.go +++ b/main.go @@ -100,6 +100,9 @@ func init() { flags.StringVar(&namespace, "namespace", defaults.DefaultNamespace, "Namespace where etcd-operator should be deployed") viper.BindEnv("namespace", "CILIUM_ETCD_OPERATOR_NAMESPACE") + + viper.BindEnv("pod-name", "CILIUM_ETCD_OPERATOR_POD_NAME") + viper.BindEnv("pod-uid", "CILIUM_ETCD_OPERATOR_POD_UID") viper.BindPFlags(flags) } @@ -109,9 +112,11 @@ func parseFlags() { etcdVersion = viper.GetString("etcd-version") gracePeriodSec = viper.GetInt64("grace-period-seconds") namespace = viper.GetString("namespace") + ownerName := viper.GetString("pod-name") + ownerUID := viper.GetString("pod-uid") - etcdCRD = etcd_operator.EtcdCRD() - etcdDeployment = etcd_operator.EtcdOperatorDeployment(namespace) + etcdCRD = etcd_operator.EtcdCRD(ownerName, ownerUID) + etcdDeployment = etcd_operator.EtcdOperatorDeployment(namespace, ownerName, ownerUID) ciliumEtcdCR = cilium_etcd_cluster.CiliumEtcdCluster(namespace, etcdVersion, clusterSize) gracePeriod = time.Duration(gracePeriodSec) * time.Second err := k8s.CreateDefaultClient() @@ -196,7 +201,11 @@ func run() error { } if len(pl.Items) == 0 { log.Info("No running etcd pod found. Bootstrapping from scratch...") - deployCiliumCR(true) + err := deployCiliumCR(true) + if err != nil { + log.Error(err) + continue + } log.Infof("Sleeping for %s to allow cluster to come up...", gracePeriod) select { case <-cleanUPSig: @@ -224,9 +233,15 @@ func deployETCD() error { log.Info("Done!") log.Info("Deploying etcd-operator deployment...") - _, err = k8s.Client().AppsV1beta2().Deployments(etcdDeployment.Namespace).Get(etcdDeployment.Name, meta_v1.GetOptions{}) + etcdDeplyServer, err := k8s.Client().AppsV1beta2().Deployments(etcdDeployment.Namespace).Get(etcdDeployment.Name, meta_v1.GetOptions{}) switch { case err == nil: + etcdCpy := etcdDeployment.DeepCopy() + etcdCpy.UID = etcdDeplyServer.UID + _, err = k8s.Client().AppsV1beta2().Deployments(etcdDeployment.Namespace).Update(etcdDeployment) + if err != nil { + return fmt.Errorf("unable to update etcd-operator deployment: %s", err) + } case errors.IsNotFound(err): _, err := k8s.Client().AppsV1beta2().Deployments(etcdDeployment.Namespace).Create(etcdDeployment) if err != nil {