From 5fd53d0b28f8b7deef3b324935649eaeee39e344 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Fri, 1 Feb 2019 15:08:56 +0100 Subject: [PATCH] Add global option to enable/disable init containers and sidecars --- charts/postgres-operator/values-crd.yaml | 6 +++-- charts/postgres-operator/values.yaml | 11 ++++++-- docs/quickstart.md | 25 ++++++++++--------- docs/reference/cluster_manifest.md | 6 +++++ docs/reference/operator_parameters.md | 23 ++++++++++++++--- docs/user.md | 8 ++++++ glide.yaml | 23 +++++++++++++++++ manifests/configmap.yaml | 2 +- ...gresql-operator-default-configuration.yaml | 2 ++ .../v1/operator_configuration_type.go | 2 ++ pkg/cluster/k8sres.go | 23 ++++++++++++++--- pkg/cluster/k8sres_test.go | 2 +- pkg/cluster/types.go | 2 +- pkg/controller/operator_config.go | 2 ++ pkg/controller/util_test.go | 2 +- pkg/util/config/config.go | 10 +++++--- 16 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 glide.yaml diff --git a/charts/postgres-operator/values-crd.yaml b/charts/postgres-operator/values-crd.yaml index af05ae56c..b6a6b3a4c 100644 --- a/charts/postgres-operator/values-crd.yaml +++ b/charts/postgres-operator/values-crd.yaml @@ -186,15 +186,17 @@ configAwsOrGcp: configLogicalBackup: # image for pods of the logical backup job (example runs pg_dumpall) logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup" - # S3 Access Key ID + # S3 Access Key ID logical_backup_s3_access_key_id: "" # S3 bucket to store backup results logical_backup_s3_bucket: "my-bucket-url" + # S3 server side encription to use + logical_backup_s3_sse: "AES256" # S3 endpoint url when not using AWS logical_backup_s3_endpoint: "" # S3 Secret Access Key logical_backup_s3_secret_access_key: "" - # S3 server side encription + # S3 server side encription logical_backup_s3_sse: "AES256" # backup schedule in the cron format logical_backup_schedule: "30 00 * * *" diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index b572b5844..6874f79c4 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -56,10 +56,15 @@ configKubernetes: cluster_name_label: version # annotations attached to each database pod # custom_pod_annotations: keya:valuea + + # enables initContainers to run actions before Spilo is started + enable_init_containers: "false" # toggles pod anti affinity on the Postgres pods enable_pod_antiaffinity: "false" # toggles PDB to set to MinAvailabe 0 or 1 enable_pod_disruption_budget: "true" + # enables sidecar containers to run alongside Spilo in the same pod + enable_sidecars: "false" # name of the secret containing infrastructure roles names and passwords # infrastructure_roles_secret_name: postgresql-infrastructure-roles @@ -180,15 +185,17 @@ configAwsOrGcp: configLogicalBackup: # image for pods of the logical backup job (example runs pg_dumpall) logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup" - # S3 Access Key ID + # S3 Access Key ID logical_backup_s3_access_key_id: "" # S3 bucket to store backup results logical_backup_s3_bucket: "my-bucket-url" + # S3 server side encription + logical_backup_s3_sse: "AES256" # S3 endpoint url when not using AWS logical_backup_s3_endpoint: "" # S3 Secret Access Key logical_backup_s3_secret_access_key: "" - # S3 server side encription + # S3 server side encription logical_backup_s3_sse: "AES256" # backup schedule in the cron format logical_backup_schedule: "30 00 * * *" diff --git a/docs/quickstart.md b/docs/quickstart.md index 500d4db30..bdb9c5943 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -49,14 +49,15 @@ git clone https://github.com/zalando/postgres-operator.git cd postgres-operator # apply the manifests in the following order -kubectl create -f manifests/configmap.yaml # configuration +kubectl create -f manifests/operatorconfiguration.crd.yaml # registers the CRD +kubectl create -f manifests/postgresql-operator-default-configuration.yaml # configuration kubectl create -f manifests/operator-service-account-rbac.yaml # identity and permissions kubectl create -f manifests/postgres-operator.yaml # deployment ``` There is a [Kustomization](https://github.com/kubernetes-sigs/kustomize) -manifest that [combines the mentioned resources](../manifests/kustomization.yaml) - -it can be used with kubectl 1.14 or newer as easy as: +manifest that [combines the mentioned resources](../manifests/kustomization.yaml). +It can be used with kubectl 1.14 or newer as easy as: ```bash kubectl apply -k github.com/zalando/postgres-operator/manifests @@ -119,15 +120,15 @@ kubectl get pod -l app.kubernetes.io/name=postgres-operator kubectl create -f manifests/minimal-postgres-manifest.yaml ``` -After the cluster manifest is submitted the operator will create Service and -Endpoint resources and a StatefulSet which spins up new Pod(s) given the number -of instances specified in the manifest. All resources are named like the -cluster. The database pods can be identified by their number suffix, starting -from `-0`. They run the [Spilo](https://github.com/zalando/spilo) container -image by Zalando. As for the services and endpoints, there will be one for the -master pod and another one for all the replicas (`-repl` suffix). Check if all -components are coming up. Use the label `application=spilo` to filter and list -the label `spilo-role` to see who is currently the master. +After the cluster manifest is submitted and passed the validation the operator +will create Service and Endpoint resources and a StatefulSet which spins up new +Pod(s) given the number of instances specified in the manifest. All resources +are named like the cluster. The database pods can be identified by their number +suffix, starting from `-0`. They run the [Spilo](https://github.com/zalando/spilo) +container image by Zalando. As for the services and endpoints, there will be one +for the master pod and another one for all the replicas (`-repl` suffix). Check +if all components are coming up. Use the label `application=spilo` to filter and +list the label `spilo-role` to see who is currently the master. ```bash # check the deployed cluster diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index cf522d73d..da5f61dc2 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -327,6 +327,7 @@ defined in the sidecar dictionary: (https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/) for environment variables. Optional. +<<<<<<< HEAD * **resources** [CPU and memory requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container) for each sidecar container. Optional. @@ -354,3 +355,8 @@ CPU and memory limits for the sidecar container. * **memory** memory limits for the sidecar container. Optional, overrides the `default_memory_limits` operator configuration parameter. Optional. +======= + **Note**: The operator will not launch a cluster if sidecar containers are specified + but globally disabled in the configuration. The `enable_sidecars` option + must be set to `true`. +>>>>>>> efce5a5f... updated docs diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index a024aad1f..6aade105e 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -82,10 +82,18 @@ Those are top-level keys, containing both leaf keys and groups. your own Spilo image from the [github repository](https://github.com/zalando/spilo). +* **enable_init_containers** + global option to allow for creating init containers to run actions before + Spilo is started. Disabled by default. + +* **enable_sidecars** + global option to allow for creating sidecar containers to run alongside Spilo + on the same pod. Disabled by default. + * **sidecar_docker_images** - a map of sidecar names to docker images for the containers to run alongside - Spilo. In case of the name conflict with the definition in the cluster - manifest the cluster-specific one is preferred. + a map of sidecar names to docker images to run with Spilo. In case of the name + conflict with the definition in the cluster manifest the cluster-specific one + is preferred. * **enable_shm_volume** Instruct operator to start any new database pod without limitations on shm @@ -444,10 +452,19 @@ grouped under the `logical_backup` key. * **logical_backup_s3_endpoint** When using non-AWS S3 storage, endpoint can be set as a ENV variable. +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ebd09880... Modified dump.sh so it knows how to handle new features. Configurable S3 SSE * **logical_backup_s3_sse** Specify server side encription that S3 storage is using. If empty string is specified, no argument will be passed to `aws s3` command. Default: "AES256". +<<<<<<< HEAD +======= +>>>>>>> 7cd05ba4... Updated documentation for logical backup endpoint, access and secret key. +======= +>>>>>>> ebd09880... Modified dump.sh so it knows how to handle new features. Configurable S3 SSE * **logical_backup_s3_access_key_id** When set, value will be in AWS_ACCESS_KEY_ID env variable. The Default is empty. diff --git a/docs/user.md b/docs/user.md index ee8e7183c..08b81ef2a 100644 --- a/docs/user.md +++ b/docs/user.md @@ -350,6 +350,10 @@ variables are always passed to sidecars: The PostgreSQL volume is shared with sidecars and is mounted at `/home/postgres/pgdata`. +**Note**: The operator will not launch a cluster if sidecar containers are +specified but globally disabled in the configuration. The `enable_sidecars` +option must be set to `true`. + ## InitContainers Support Each cluster can specify arbitrary init containers to run. These containers can @@ -374,6 +378,10 @@ spec: `initContainers` accepts full `v1.Container` definition. +**Note**: The operator will not launch a cluster if init containers are specified +but globally disabled in the configuration. The `enable_init_containers` option +must be set to `true`. + ## Increase volume size PostgreSQL operator supports statefulset volume resize if you're using the diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 000000000..986970887 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,23 @@ +package: github.com/zalando/postgres-operator +import: +- package: github.com/sirupsen/logrus + version: ^1.0.1 +- package: github.com/aws/aws-sdk-go + version: ^1.8.24 + subpackages: + - aws + - aws/session + - service/ec2 +- package: github.com/lib/pq +- package: github.com/motomux/pretty +- package: k8s.io/apimachinery + version: kubernetes-1.11.3-beta.0 +- package: k8s.io/apiextensions-apiserver + version: kubernetes-1.11.3-beta.0 +- package: k8s.io/client-go + version: kubernetes-1.11.3-beta.0 +- package: k8s.io/code-generator + version: kubernetes-1.11.3-beta.0 +- package: k8s.io/gengo +- package: gopkg.in/yaml.v2 +- package: github.com/mohae/deepcopy diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index 40aca9716..0867135d8 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -41,7 +41,7 @@ data: # logical_backup_s3_secret_access_key: "" # logical_backup_s3_sse: "AES256" # logical_backup_schedule: "30 00 * * *" - master_dns_name_format: "{cluster}.{team}.staging.{hostedzone}" + master_dns_name_format: '{cluster}.{team}.staging.{hostedzone}' # master_pod_move_timeout: 10m # max_instances: "-1" # min_instances: "-1" diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index 94f91f1f0..7f2aad949 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -25,8 +25,10 @@ configuration: # custom_pod_annotations: # keya: valuea # keyb: valueb + enable_init_containers: false enable_pod_antiaffinity: false enable_pod_disruption_budget: true + enable_sidecars: false # infrastructure_roles_secret_name: "" # inherited_labels: # - application diff --git a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go index d00d40532..1cc69af28 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -160,6 +160,8 @@ type OperatorConfigurationData struct { SetMemoryRequestToLimit bool `json:"set_memory_request_to_limit,omitempty"` ShmVolume *bool `json:"enable_shm_volume,omitempty"` Sidecars map[string]string `json:"sidecar_docker_images,omitempty"` + EnableSidecars bool `json:"enable_sidecars,omitempty"` + EnableInitContainers bool `json:"enable_init_containers,omitempty"` PostgresUsersConfiguration PostgresUsersConfiguration `json:"users"` Kubernetes KubernetesMetaConfiguration `json:"kubernetes"` PostgresPodResources PostgresPodResourcesDefaults `json:"postgres_pod_resources"` diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 95e83454f..caae1a772 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -720,6 +720,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef var ( err error + initContainers []v1.Container sidecarContainers []v1.Container podTemplate *v1.PodTemplateSpec volumeClaimTemplate *v1.PersistentVolumeClaim @@ -786,6 +787,14 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef return nil, fmt.Errorf("could not generate resource requirements: %v", err) } + if spec.InitContainers != nil { + if c.OpConfig.EnableInitContainers { + initContainers = spec.InitContainers + } else { + return nil, fmt.Errorf("InitContainers specified but globally disabled!") + } + } + customPodEnvVarsList := make([]v1.EnvVar, 0) if c.OpConfig.PodEnvironmentConfigMap != "" { @@ -872,9 +881,15 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef } // generate sidecar containers - if sidecarContainers, err = generateSidecarContainers(sideCars, volumeMounts, defaultResources, - c.OpConfig.SuperUsername, c.credentialSecretName(c.OpConfig.SuperUsername), c.logger); err != nil { - return nil, fmt.Errorf("could not generate sidecar containers: %v", err) + if sideCars != nil { + if c.OpConfig.EnableSidecars { + if sidecarContainers, err = generateSidecarContainers(sideCars, volumeMounts, defaultResources, + c.OpConfig.SuperUsername, c.credentialSecretName(c.OpConfig.SuperUsername), c.logger); err != nil { + return nil, fmt.Errorf("could not generate sidecar containers: %v", err) + } + } else { + return nil, fmt.Errorf("Sidecar containers specified but globally disabled!") + } } tolerationSpec := tolerations(&spec.Tolerations, c.OpConfig.PodToleration) @@ -894,7 +909,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef c.labelsSet(true), annotations, spiloContainer, - spec.InitContainers, + initContainers, sidecarContainers, &tolerationSpec, effectiveFSGroup, diff --git a/pkg/cluster/k8sres_test.go b/pkg/cluster/k8sres_test.go index 5b206f760..e8fe05456 100644 --- a/pkg/cluster/k8sres_test.go +++ b/pkg/cluster/k8sres_test.go @@ -3,7 +3,7 @@ package cluster import ( "reflect" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "testing" diff --git a/pkg/cluster/types.go b/pkg/cluster/types.go index afdc7376e..138b7015c 100644 --- a/pkg/cluster/types.go +++ b/pkg/cluster/types.go @@ -5,7 +5,7 @@ import ( acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" appsv1 "k8s.io/api/apps/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" policybeta1 "k8s.io/api/policy/v1beta1" "k8s.io/apimachinery/pkg/types" ) diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 3ea513879..583f251ed 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -35,6 +35,8 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.SetMemoryRequestToLimit = fromCRD.SetMemoryRequestToLimit result.ShmVolume = fromCRD.ShmVolume result.Sidecars = fromCRD.Sidecars + result.EnableSidecars = fromCRD.EnableSidecars + result.EnableInitContainers = fromCRD.EnableInitContainers // user config result.SuperUsername = fromCRD.PostgresUsersConfiguration.SuperUsername diff --git a/pkg/controller/util_test.go b/pkg/controller/util_test.go index c9e16cbd9..a5d3c7ac5 100644 --- a/pkg/controller/util_test.go +++ b/pkg/controller/util_test.go @@ -9,7 +9,7 @@ import ( "github.com/zalando/postgres-operator/pkg/spec" "github.com/zalando/postgres-operator/pkg/util/k8sutil" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index e8de85e20..1a0413471 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -87,10 +87,12 @@ type Config struct { Scalyr LogicalBackup - WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to' - EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use K8s as a DCS - DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-11:1.6-p1"` - Sidecars map[string]string `name:"sidecar_docker_images"` + WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to' + EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use K8s as a DCS + DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-11:1.6-p1"` + Sidecars map[string]string `name:"sidecar_docker_images"` + EnableSidecars bool `name:"enable_sidecars" default:"false"` + EnableInitContainers bool `name:"enable_init_containers" default:"false"` // default name `operator` enables backward compatibility with the older ServiceAccountName field PodServiceAccountName string `name:"pod_service_account_name" default:"operator"` // value of this string must be valid JSON or YAML; see initPodServiceAccount