From f25351c36a4e62e18f2af6704d9aace38b7539d6 Mon Sep 17 00:00:00 2001 From: jens-totemic <44175225+jens-totemic@users.noreply.github.com> Date: Tue, 13 Nov 2018 02:22:07 -0800 Subject: [PATCH 01/33] Make OperatorConfiguration work (#410) * Fixes # 404 --- manifests/operator-service-account-rbac.yaml | 1 + manifests/postgres-operator.yaml | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/manifests/operator-service-account-rbac.yaml b/manifests/operator-service-account-rbac.yaml index 8a1bfb857..7bd539ac5 100644 --- a/manifests/operator-service-account-rbac.yaml +++ b/manifests/operator-service-account-rbac.yaml @@ -14,6 +14,7 @@ rules: - acid.zalan.do resources: - postgresqls + - operatorconfigurations verbs: - "*" - apiGroups: diff --git a/manifests/postgres-operator.yaml b/manifests/postgres-operator.yaml index 0c4cf84cb..d8a4a6ac4 100644 --- a/manifests/postgres-operator.yaml +++ b/manifests/postgres-operator.yaml @@ -12,9 +12,13 @@ spec: serviceAccountName: zalando-postgres-operator containers: - name: postgres-operator - image: registry.opensource.zalan.do/acid/postgres-operator:v1.0.0 + image: registry.opensource.zalan.do/acid/smoke-tested-postgres-operator:v1.0.0-21-ge39915c imagePullPolicy: IfNotPresent env: # provided additional ENV vars can overwrite individual config map entries - name: CONFIG_MAP_NAME value: "postgres-operator" + # In order to use the CRD OperatorConfiguration instead, uncomment these lines and comment out the two lines above + # - name: POSTGRES_OPERATOR_CONFIGURATION_OBJECT + # value: postgresql-operator-default-configuration + From 45c89b3da4f72a0ebb1a683fec5a8ffdd76ce20e Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Thu, 15 Nov 2018 14:00:08 +0100 Subject: [PATCH 02/33] [WIP] Add set_memory_request_to_limit option (#406) * Add set_memory_request_to_limit option --- README.md | 2 + delivery.yaml | 2 +- docs/administrator.md | 6 +- docs/reference/operator_parameters.md | 3 + manifests/complete-postgres-manifest.yaml | 4 +- manifests/configmap.yaml | 3 +- .../v1/operator_configuration_type.go | 1 + pkg/apis/acid.zalan.do/v1/postgresql_type.go | 4 +- pkg/apis/acid.zalan.do/v1/util_test.go | 4 +- .../acid.zalan.do/v1/zz_generated.deepcopy.go | 2 +- pkg/cluster/k8sres.go | 66 +++++++++++++++++-- pkg/controller/controller.go | 23 +++++++ pkg/controller/operator_config.go | 1 + pkg/util/config/config.go | 1 + pkg/util/util.go | 18 +++++ pkg/util/util_test.go | 23 +++++++ 16 files changed, 145 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 18ea97538..13adae24d 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ cd postgres-operator ./run_operator_locally.sh ``` +Note we provide the `/manifests` directory as an example only; you should consider adjusting the manifests to your particular setting. + ## Running and testing the operator The best way to test the operator is to run it locally in [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/). See developer docs(`docs/developer.yaml`) for details. diff --git a/delivery.yaml b/delivery.yaml index 502aa75b2..c939e64f0 100644 --- a/delivery.yaml +++ b/delivery.yaml @@ -22,7 +22,7 @@ pipeline: go version - desc: 'Install Docker' cmd: | - curl -sSL https://get.docker.com/ | sh + curl -fLOsS https://delivery.cloud.zalando.com/utils/ensure-docker && sh ensure-docker && rm ensure-docker - desc: 'Symlink sources into the GOPATH' cmd: | mkdir -p $OPERATOR_TOP_DIR diff --git a/docs/administrator.md b/docs/administrator.md index 83594ef1f..f2c747cce 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -41,12 +41,12 @@ manifests: ```bash $ kubectl create namespace test - $ kubectl config set-context --namespace=test + $ kubectl config set-context $(kubectl config current-context) --namespace=test ``` All subsequent `kubectl` commands will work with the `test` namespace. The -operator will run in this namespace and look up needed resources - such as its -config map - there. +operator will run in this namespace and look up needed resources - such as its +config map - there. Please note that the namespace for service accounts and cluster role bindings in [operator RBAC rules](manifests/operator-service-account-rbac.yaml) needs to be adjusted to the non-default value. ## Specify the namespace to watch diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 76109c890..47f67228c 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -221,6 +221,9 @@ CRD-based configuration. memory limits for the postgres containers, unless overridden by cluster-specific settings. The default is `1Gi`. +* **set_memory_request_to_limit** + Set `memory_request` to `memory_limit` for all Postgres clusters (the default value is also increased). This prevents certain cases of memory overcommitment at the cost of overprovisioning memory and potential scheduling problems for containers with high memory limits due to the lack of memory on Kubernetes cluster nodes. This affects all containers (Postgres, Scalyr sidecar, and other sidecars). The default is `false`. + ## Operator timeouts This set of parameters define various timeouts related to some operator diff --git a/manifests/complete-postgres-manifest.yaml b/manifests/complete-postgres-manifest.yaml index 60d39c94b..e0f76e4d4 100644 --- a/manifests/complete-postgres-manifest.yaml +++ b/manifests/complete-postgres-manifest.yaml @@ -6,7 +6,7 @@ metadata: spec: teamId: "ACID" volume: - size: 5Gi + size: 1Gi numberOfInstances: 2 users: #Application/Robot users zalando: @@ -31,7 +31,7 @@ spec: memory: 100Mi limits: cpu: 300m - memory: 3000Mi + memory: 300Mi patroni: initdb: encoding: "UTF8" diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index ed7652907..d127e72f2 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -10,11 +10,12 @@ data: debug_logging: "true" workers: "4" - docker_image: registry.opensource.zalan.do/acid/spilo-cdp-10:1.4-p29 + docker_image: registry.opensource.zalan.do/acid/spilo-cdp-10:1.5-p35 pod_service_account_name: "zalando-postgres-operator" secret_name_template: '{username}.{cluster}.credentials' super_username: postgres enable_teams_api: "false" + # set_memory_request_to_limit: "true" # postgres_superuser_teams: "postgres_superusers" # enable_team_superuser: "false" # team_admin_role: "admin" 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 de7681db4..da163620b 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -131,6 +131,7 @@ type OperatorConfigurationData struct { PostgresUsersConfiguration PostgresUsersConfiguration `json:"users"` Kubernetes KubernetesMetaConfiguration `json:"kubernetes"` PostgresPodResources PostgresPodResourcesDefaults `json:"postgres_pod_resources"` + SetMemoryRequestToLimit bool `json:"set_memory_request_to_limit,omitempty"` Timeouts OperatorTimeouts `json:"timeouts"` LoadBalancer LoadBalancerConfiguration `json:"load_balancer"` AWSGCP AWSGCPConfiguration `json:"aws_or_gcp"` diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 380ba68d7..aedb0512f 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -90,8 +90,8 @@ type ResourceDescription struct { // Resources describes requests and limits for the cluster resouces. type Resources struct { - ResourceRequest ResourceDescription `json:"requests,omitempty"` - ResourceLimits ResourceDescription `json:"limits,omitempty"` + ResourceRequests ResourceDescription `json:"requests,omitempty"` + ResourceLimits ResourceDescription `json:"limits,omitempty"` } // Patroni contains Patroni-specific configuration diff --git a/pkg/apis/acid.zalan.do/v1/util_test.go b/pkg/apis/acid.zalan.do/v1/util_test.go index 99e3f2b7c..b6a27542c 100644 --- a/pkg/apis/acid.zalan.do/v1/util_test.go +++ b/pkg/apis/acid.zalan.do/v1/util_test.go @@ -240,8 +240,8 @@ var unmarshalCluster = []struct { Slots: map[string]map[string]string{"permanent_logical_1": {"type": "logical", "database": "foo", "plugin": "pgoutput"}}, }, Resources: Resources{ - ResourceRequest: ResourceDescription{CPU: "10m", Memory: "50Mi"}, - ResourceLimits: ResourceDescription{CPU: "300m", Memory: "3000Mi"}, + ResourceRequests: ResourceDescription{CPU: "10m", Memory: "50Mi"}, + ResourceLimits: ResourceDescription{CPU: "300m", Memory: "3000Mi"}, }, TeamID: "ACID", diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index 4496f8c0a..55a5ac075 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -573,7 +573,7 @@ func (in *ResourceDescription) DeepCopy() *ResourceDescription { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Resources) DeepCopyInto(out *Resources) { *out = *in - out.ResourceRequest = in.ResourceRequest + out.ResourceRequests = in.ResourceRequests out.ResourceLimits = in.ResourceLimits return } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 66ac55388..b775ee636 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -92,18 +92,18 @@ func (c *Cluster) makeDefaultResources() acidv1.Resources { defaultRequests := acidv1.ResourceDescription{CPU: config.DefaultCPURequest, Memory: config.DefaultMemoryRequest} defaultLimits := acidv1.ResourceDescription{CPU: config.DefaultCPULimit, Memory: config.DefaultMemoryLimit} - return acidv1.Resources{ResourceRequest: defaultRequests, ResourceLimits: defaultLimits} + return acidv1.Resources{ResourceRequests: defaultRequests, ResourceLimits: defaultLimits} } func generateResourceRequirements(resources acidv1.Resources, defaultResources acidv1.Resources) (*v1.ResourceRequirements, error) { var err error - specRequests := resources.ResourceRequest + specRequests := resources.ResourceRequests specLimits := resources.ResourceLimits result := v1.ResourceRequirements{} - result.Requests, err = fillResourceList(specRequests, defaultResources.ResourceRequest) + result.Requests, err = fillResourceList(specRequests, defaultResources.ResourceRequests) if err != nil { return nil, fmt.Errorf("could not fill resource requests: %v", err) } @@ -377,8 +377,8 @@ func generateSidecarContainers(sidecars []acidv1.Sidecar, resources, err := generateResourceRequirements( makeResources( - sidecar.Resources.ResourceRequest.CPU, - sidecar.Resources.ResourceRequest.Memory, + sidecar.Resources.ResourceRequests.CPU, + sidecar.Resources.ResourceRequests.Memory, sidecar.Resources.ResourceLimits.CPU, sidecar.Resources.ResourceLimits.Memory, ), @@ -625,7 +625,7 @@ func getBucketScopeSuffix(uid string) string { func makeResources(cpuRequest, memoryRequest, cpuLimit, memoryLimit string) acidv1.Resources { return acidv1.Resources{ - ResourceRequest: acidv1.ResourceDescription{ + ResourceRequests: acidv1.ResourceDescription{ CPU: cpuRequest, Memory: memoryRequest, }, @@ -644,6 +644,60 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State podTemplate *v1.PodTemplateSpec volumeClaimTemplate *v1.PersistentVolumeClaim ) + + if c.OpConfig.SetMemoryRequestToLimit { + + // controller adjusts the default memory request at operator startup + + request := spec.Resources.ResourceRequests.Memory + if request == "" { + request = c.OpConfig.DefaultMemoryRequest + } + + limit := spec.Resources.ResourceLimits.Memory + if limit == "" { + limit = c.OpConfig.DefaultMemoryLimit + } + + isSmaller, err := util.RequestIsSmallerThanLimit(request, limit) + if err != nil { + return nil, err + } + if isSmaller { + c.logger.Warningf("The memory request of %v for the Postgres container is increased to match the memory limit of %v.", request, limit) + spec.Resources.ResourceRequests.Memory = limit + + } + + // controller adjusts the Scalyr sidecar request at operator startup + // as this sidecar is managed separately + + // adjust sidecar containers defined for that particular cluster + for _, sidecar := range spec.Sidecars { + + // TODO #413 + sidecarRequest := sidecar.Resources.ResourceRequests.Memory + if request == "" { + request = c.OpConfig.DefaultMemoryRequest + } + + sidecarLimit := sidecar.Resources.ResourceLimits.Memory + if limit == "" { + limit = c.OpConfig.DefaultMemoryLimit + } + + isSmaller, err := util.RequestIsSmallerThanLimit(sidecarRequest, sidecarLimit) + if err != nil { + return nil, err + } + if isSmaller { + c.logger.Warningf("The memory request of %v for the %v sidecar container is increased to match the memory limit of %v.", sidecar.Resources.ResourceRequests.Memory, sidecar.Name, sidecar.Resources.ResourceLimits.Memory) + sidecar.Resources.ResourceRequests.Memory = sidecar.Resources.ResourceLimits.Memory + } + } + + } + defaultResources := c.makeDefaultResources() resourceRequirements, err := generateResourceRequirements(spec.Resources, defaultResources) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 1bc4e08e0..fd1c099de 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -110,6 +110,29 @@ func (c *Controller) initOperatorConfig() { c.opConfig = config.NewFromMap(configMapData) c.warnOnDeprecatedOperatorParameters() + if c.opConfig.SetMemoryRequestToLimit { + + isSmaller, err := util.RequestIsSmallerThanLimit(c.opConfig.DefaultMemoryRequest, c.opConfig.DefaultMemoryLimit) + if err != nil { + panic(err) + } + if isSmaller { + c.logger.Warningf("The default memory request of %v for Postgres containers is increased to match the default memory limit of %v.", c.opConfig.DefaultMemoryRequest, c.opConfig.DefaultMemoryLimit) + c.opConfig.DefaultMemoryRequest = c.opConfig.DefaultMemoryLimit + } + + isSmaller, err = util.RequestIsSmallerThanLimit(c.opConfig.ScalyrMemoryRequest, c.opConfig.ScalyrMemoryLimit) + if err != nil { + panic(err) + } + if isSmaller { + c.logger.Warningf("The memory request of %v for the Scalyr sidecar container is increased to match the memory limit of %v.", c.opConfig.ScalyrMemoryRequest, c.opConfig.ScalyrMemoryLimit) + c.opConfig.ScalyrMemoryRequest = c.opConfig.ScalyrMemoryLimit + } + + // generateStatefulSet adjusts values for individual Postgres clusters + } + } func (c *Controller) modifyConfigFromEnvironment() { diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 93ba1a0f4..006cfd2d1 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -55,6 +55,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.DefaultMemoryRequest = fromCRD.PostgresPodResources.DefaultMemoryRequest result.DefaultCPULimit = fromCRD.PostgresPodResources.DefaultCPULimit result.DefaultMemoryLimit = fromCRD.PostgresPodResources.DefaultMemoryLimit + result.SetMemoryRequestToLimit = fromCRD.SetMemoryRequestToLimit result.ResourceCheckInterval = time.Duration(fromCRD.Timeouts.ResourceCheckInterval) result.ResourceCheckTimeout = time.Duration(fromCRD.Timeouts.ResourceCheckTimeout) diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 92fd3fd73..2bd7924ad 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -104,6 +104,7 @@ type Config struct { PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"` ProtectedRoles []string `name:"protected_role_names" default:"admin"` PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""` + SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" defaults:"false"` } // MustMarshal marshals the config or panics diff --git a/pkg/util/util.go b/pkg/util/util.go index 7b7b58fc4..99e670af9 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -3,12 +3,14 @@ package util import ( "crypto/md5" // #nosec we need it to for PostgreSQL md5 passwords "encoding/hex" + "fmt" "math/rand" "regexp" "strings" "time" "github.com/motomux/pretty" + resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/zalando-incubator/postgres-operator/pkg/spec" @@ -127,3 +129,19 @@ func Coalesce(val, defaultVal string) string { } return val } + +// RequestIsSmallerThanLimit +func RequestIsSmallerThanLimit(requestStr, limitStr string) (bool, error) { + + request, err := resource.ParseQuantity(requestStr) + if err != nil { + return false, fmt.Errorf("could not parse memory request %v : %v", requestStr, err) + } + + limit, err2 := resource.ParseQuantity(limitStr) + if err2 != nil { + return false, fmt.Errorf("could not parse memory limit %v : %v", limitStr, err2) + } + + return request.Cmp(limit) == -1, nil +} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 53ac13768..3a02149b4 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -69,6 +69,17 @@ var substringMatch = []struct { {regexp.MustCompile(`aaaa (\d+) bbbb`), "aaaa 123 bbbb", nil}, } +var requestIsSmallerThanLimitTests = []struct { + request string + limit string + out bool +}{ + {"1G", "2G", true}, + {"1G", "1Gi", true}, // G is 1000^3 bytes, Gi is 1024^3 bytes + {"1024Mi", "1G", false}, + {"1e9", "1G", false}, // 1e9 bytes == 1G +} + func TestRandomPassword(t *testing.T) { const pwdLength = 10 pwd := RandomPassword(pwdLength) @@ -143,3 +154,15 @@ func TestMapContains(t *testing.T) { } } } + +func TestRequestIsSmallerThanLimit(t *testing.T) { + for _, tt := range requestIsSmallerThanLimitTests { + res, err := RequestIsSmallerThanLimit(tt.request, tt.limit) + if err != nil { + t.Errorf("RequestIsSmallerThanLimit returned unexpected error: %#v", err) + } + if res != tt.out { + t.Errorf("RequestIsSmallerThanLimit expected: %#v, got: %#v", tt.out, res) + } + } +} From a0e09cd6a636e2a94077b77b8d3c9b61a3f45d89 Mon Sep 17 00:00:00 2001 From: Dmitry Dolgov <9erthalion6@gmail.com> Date: Tue, 27 Nov 2018 11:59:59 +0100 Subject: [PATCH 03/33] Add golangci badge (#423) Since we've connected it, it makes sense also to display the results. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 13adae24d..d96458eec 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Coverage Status](https://coveralls.io/repos/github/zalando-incubator/postgres-operator/badge.svg)](https://coveralls.io/github/zalando-incubator/postgres-operator) [![Go Report Card](https://goreportcard.com/badge/github.com/zalando-incubator/postgres-operator)](https://goreportcard.com/report/github.com/zalando-incubator/postgres-operator) [![GoDoc](https://godoc.org/github.com/zalando-incubator/postgres-operator?status.svg)](https://godoc.org/github.com/zalando-incubator/postgres-operator) +[![golangci](https://golangci.com/badges/github.com/zalando-incubator/postgres-operator.svg)](https://golangci.com/r/github.com/zalando-incubator/postgres-operator) ## Introduction From ff5c63ddf13d7f7ed6810c64a2a697163cc01915 Mon Sep 17 00:00:00 2001 From: Isaev Denis Date: Tue, 27 Nov 2018 14:00:15 +0300 Subject: [PATCH 04/33] add .golangci.yml (#422) --- .golangci.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..4ffc1915a --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,5 @@ +# https://github.com/golangci/golangci/wiki/Configuration + +service: + prepare: + - make deps From d6e6b007707fb19f4ca8486188b2e540cb14110c Mon Sep 17 00:00:00 2001 From: Dmitry Dolgov <9erthalion6@gmail.com> Date: Fri, 21 Dec 2018 16:22:30 +0100 Subject: [PATCH 05/33] Add shm_volume option (#427) Add possibility to mount a tmpfs volume to /dev/shm to avoid issues like [this](https://github.com/docker-library/postgres/issues/416). To achieve that two new options were introduced: * `enableShmVolume` to PostgreSQL manifest, to specify whether or not mount this volume per database cluster * `enable_shm_volume` to operator configuration, to specify whether or not mount per operator. The first one, `enableShmVolume` takes precedence to allow us to be more flexible. --- docs/reference/cluster_manifest.md | 15 +++++- docs/reference/operator_parameters.md | 8 +++ manifests/complete-postgres-manifest.yaml | 3 +- pkg/apis/acid.zalan.do/v1/postgresql_type.go | 1 + pkg/apis/acid.zalan.do/v1/util_test.go | 6 +-- pkg/cluster/k8sres.go | 52 ++++++++++++++++++- pkg/cluster/k8sres_test.go | 54 ++++++++++++++++++++ pkg/util/config/config.go | 1 + pkg/util/constants/kubernetes.go | 1 + pkg/util/constants/postgresql.go | 3 ++ 10 files changed, 137 insertions(+), 7 deletions(-) diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index 75de35097..efc850aff 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -96,7 +96,19 @@ Those are parameters grouped directly under the `spec` key in the manifest. that should be assigned to the cluster pods. When not specified, the value is taken from the `pod_priority_class_name` operator parameter, if not set then the default priority class is taken. The priority class itself must be defined in advance. - + +* **enableShmVolume** + Start a database pod without limitations on shm memory. By default docker + limit `/dev/shm` to `64M` (see e.g. the [docker + issue](https://github.com/docker-library/postgres/issues/416), which could be + not enough if PostgreSQL uses parallel workers heavily. If this option is + present and value is `true`, to the target database pod will be mounted a new + tmpfs volume to remove this limitation. If it's not present, the decision + about mounting a volume will be made based on operator configuration + (`enable_shm_volume`, which is `true` by default). It it's present and value + is `false`, then no volume will be mounted no matter how operator was + configured (so you can override the operator configuration). + ## Postgres parameters Those parameters are grouped under the `postgresql` top-level key. @@ -112,6 +124,7 @@ Those parameters are grouped under the `postgresql` top-level key. cluster. Optional (Spilo automatically sets reasonable defaults for parameters like work_mem or max_connections). + ## Patroni parameters Those parameters are grouped under the `patroni` top-level key. See the [patroni diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 47f67228c..3f96b450c 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -224,6 +224,14 @@ CRD-based configuration. * **set_memory_request_to_limit** Set `memory_request` to `memory_limit` for all Postgres clusters (the default value is also increased). This prevents certain cases of memory overcommitment at the cost of overprovisioning memory and potential scheduling problems for containers with high memory limits due to the lack of memory on Kubernetes cluster nodes. This affects all containers (Postgres, Scalyr sidecar, and other sidecars). The default is `false`. +* **enable_shm_volume** + Instruct operator to start any new database pod without limitations on shm + memory. If this option is enabled, to the target database pod will be mounted + a new tmpfs volume to remove shm memory limitation (see e.g. the [docker + issue](https://github.com/docker-library/postgres/issues/416)). This option + is global for an operator object, and can be overwritten by `enableShmVolume` + parameter from Postgres manifest. The default is `true` + ## Operator timeouts This set of parameters define various timeouts related to some operator diff --git a/manifests/complete-postgres-manifest.yaml b/manifests/complete-postgres-manifest.yaml index e0f76e4d4..c5f80f373 100644 --- a/manifests/complete-postgres-manifest.yaml +++ b/manifests/complete-postgres-manifest.yaml @@ -13,12 +13,13 @@ spec: - superuser - createdb enableMasterLoadBalancer: true - enableReplicaLoadBalancer: true + enableReplicaLoadBalancer: true allowedSourceRanges: # load balancers' source ranges for both master and replica services - 127.0.0.1/32 databases: foo: zalando #Expert section + enableShmVolume: true postgresql: version: "10" parameters: diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index aedb0512f..2a8f60f71 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -51,6 +51,7 @@ type PostgresSpec struct { Tolerations []v1.Toleration `json:"tolerations,omitempty"` Sidecars []Sidecar `json:"sidecars,omitempty"` PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` + ShmVolume *bool `json:"enableShmVolume,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/acid.zalan.do/v1/util_test.go b/pkg/apis/acid.zalan.do/v1/util_test.go index b6a27542c..01be31e88 100644 --- a/pkg/apis/acid.zalan.do/v1/util_test.go +++ b/pkg/apis/acid.zalan.do/v1/util_test.go @@ -499,7 +499,7 @@ func TestMarshal(t *testing.T) { t.Errorf("Marshal error: %v", err) } if !bytes.Equal(m, tt.marshal) { - t.Errorf("Marshal Postgresql expected: %q, got: %q", string(tt.marshal), string(m)) + t.Errorf("Marshal Postgresql \nexpected: %q, \ngot: %q", string(tt.marshal), string(m)) } } } @@ -507,11 +507,11 @@ func TestMarshal(t *testing.T) { func TestPostgresMeta(t *testing.T) { for _, tt := range unmarshalCluster { if a := tt.out.GetObjectKind(); a != &tt.out.TypeMeta { - t.Errorf("GetObjectKindMeta expected: %v, got: %v", tt.out.TypeMeta, a) + t.Errorf("GetObjectKindMeta \nexpected: %v, \ngot: %v", tt.out.TypeMeta, a) } if a := tt.out.GetObjectMeta(); reflect.DeepEqual(a, tt.out.ObjectMeta) { - t.Errorf("GetObjectMeta expected: %v, got: %v", tt.out.ObjectMeta, a) + t.Errorf("GetObjectMeta \nexpected: %v, \ngot: %v", tt.out.ObjectMeta, a) } } } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index b775ee636..6a3a052bd 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -18,6 +18,7 @@ import ( acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1" "github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/util" + "github.com/zalando-incubator/postgres-operator/pkg/util/config" "github.com/zalando-incubator/postgres-operator/pkg/util/constants" "k8s.io/apimachinery/pkg/labels" ) @@ -396,6 +397,16 @@ func generateSidecarContainers(sidecars []acidv1.Sidecar, return nil, nil } +// Check whether or not we're requested to mount an shm volume, +// taking into account that PostgreSQL manifest has precedence. +func mountShmVolumeNeeded(opConfig config.Config, pgSpec *acidv1.PostgresSpec) bool { + if pgSpec.ShmVolume != nil { + return *pgSpec.ShmVolume + } + + return opConfig.ShmVolume +} + func generatePodTemplate( namespace string, labels labels.Set, @@ -407,6 +418,7 @@ func generatePodTemplate( podServiceAccountName string, kubeIAMRole string, priorityClassName string, + shmVolume bool, ) (*v1.PodTemplateSpec, error) { terminateGracePeriodSeconds := terminateGracePeriod @@ -420,6 +432,10 @@ func generatePodTemplate( Tolerations: *tolerationsSpec, } + if shmVolume { + addShmVolume(&podSpec) + } + if nodeAffinity != nil { podSpec.Affinity = nodeAffinity } @@ -733,7 +749,12 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State volumeMounts := generateVolumeMounts() // generate the spilo container - spiloContainer := generateSpiloContainer(c.containerName(), &effectiveDockerImage, resourceRequirements, spiloEnvVars, volumeMounts) + spiloContainer := generateSpiloContainer(c.containerName(), + &effectiveDockerImage, + resourceRequirements, + spiloEnvVars, + volumeMounts, + ) // resolve conflicts between operator-global and per-cluster sidecards sideCars := c.mergeSidecars(spec.Sidecars) @@ -775,7 +796,8 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State int64(c.OpConfig.PodTerminateGracePeriod.Seconds()), c.OpConfig.PodServiceAccountName, c.OpConfig.KubeIAMRole, - effectivePodPriorityClassName); err != nil { + effectivePodPriorityClassName, + mountShmVolumeNeeded(c.OpConfig, spec)); err != nil { return nil, fmt.Errorf("could not generate pod template: %v", err) } @@ -882,6 +904,32 @@ func (c *Cluster) getNumberOfInstances(spec *acidv1.PostgresSpec) int32 { return newcur } +// To avoid issues with limited /dev/shm inside docker environment, when +// PostgreSQL can't allocate enough of dsa segments from it, we can +// mount an extra memory volume +// +// see https://docs.okd.io/latest/dev_guide/shared_memory.html +func addShmVolume(podSpec *v1.PodSpec) { + volumes := append(podSpec.Volumes, v1.Volume{ + Name: constants.ShmVolumeName, + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{ + Medium: "Memory", + }, + }, + }) + + pgIdx := constants.PostgresContainerIdx + mounts := append(podSpec.Containers[pgIdx].VolumeMounts, + v1.VolumeMount{ + Name: constants.ShmVolumeName, + MountPath: constants.ShmVolumePath, + }) + + podSpec.Containers[0].VolumeMounts = mounts + podSpec.Volumes = volumes +} + func generatePersistentVolumeClaimTemplate(volumeSize, volumeStorageClass string) (*v1.PersistentVolumeClaim, error) { var storageClassName *string diff --git a/pkg/cluster/k8sres_test.go b/pkg/cluster/k8sres_test.go index 12e145c04..92946ab2b 100644 --- a/pkg/cluster/k8sres_test.go +++ b/pkg/cluster/k8sres_test.go @@ -1,8 +1,11 @@ package cluster import ( + "k8s.io/api/core/v1" + acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1" "github.com/zalando-incubator/postgres-operator/pkg/util/config" + "github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil" "testing" ) @@ -75,3 +78,54 @@ func TestCreateLoadBalancerLogic(t *testing.T) { } } } + +func TestShmVolume(t *testing.T) { + testName := "TestShmVolume" + tests := []struct { + subTest string + podSpec *v1.PodSpec + shmPos int + }{ + { + subTest: "empty PodSpec", + podSpec: &v1.PodSpec{ + Volumes: []v1.Volume{}, + Containers: []v1.Container{ + v1.Container{ + VolumeMounts: []v1.VolumeMount{}, + }, + }, + }, + shmPos: 0, + }, + { + subTest: "non empty PodSpec", + podSpec: &v1.PodSpec{ + Volumes: []v1.Volume{v1.Volume{}}, + Containers: []v1.Container{ + v1.Container{ + VolumeMounts: []v1.VolumeMount{ + v1.VolumeMount{}, + }, + }, + }, + }, + shmPos: 1, + }, + } + for _, tt := range tests { + addShmVolume(tt.podSpec) + + volumeName := tt.podSpec.Volumes[tt.shmPos].Name + volumeMountName := tt.podSpec.Containers[0].VolumeMounts[tt.shmPos].Name + + if volumeName != constants.ShmVolumeName { + t.Errorf("%s %s: Expected volume %s was not created, have %s instead", + testName, tt.subTest, constants.ShmVolumeName, volumeName) + } + if volumeMountName != constants.ShmVolumeName { + t.Errorf("%s %s: Expected mount %s was not created, have %s instead", + testName, tt.subTest, constants.ShmVolumeName, volumeMountName) + } + } +} diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 2bd7924ad..d855e0a2a 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -38,6 +38,7 @@ type Resources struct { NodeReadinessLabel map[string]string `name:"node_readiness_label" default:""` MaxInstances int32 `name:"max_instances" default:"-1"` MinInstances int32 `name:"min_instances" default:"-1"` + ShmVolume bool `name:"enable_shm_volume" default:"true"` } // Auth describes authentication specific configuration parameters diff --git a/pkg/util/constants/kubernetes.go b/pkg/util/constants/kubernetes.go index 2604f124d..a4ea73e80 100644 --- a/pkg/util/constants/kubernetes.go +++ b/pkg/util/constants/kubernetes.go @@ -5,6 +5,7 @@ import "time" // General kubernetes-related constants const ( PostgresContainerName = "postgres" + PostgresContainerIdx = 0 K8sAPIPath = "/apis" StatefulsetDeletionInterval = 1 * time.Second StatefulsetDeletionTimeout = 30 * time.Second diff --git a/pkg/util/constants/postgresql.go b/pkg/util/constants/postgresql.go index 7556e8858..e39fd423f 100644 --- a/pkg/util/constants/postgresql.go +++ b/pkg/util/constants/postgresql.go @@ -10,4 +10,7 @@ const ( PostgresConnectRetryTimeout = 2 * time.Minute PostgresConnectTimeout = 15 * time.Second + + ShmVolumeName = "dshm" + ShmVolumePath = "/dev/shm" ) From 4fa09e0dcbe556106beaed4078e6c2756245e931 Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Fri, 21 Dec 2018 16:44:31 +0100 Subject: [PATCH 06/33] Unify warnings about unmovable pods (#389) * Unify warnings about unmovable pods * Log conditions that prevent master pod migration --- pkg/controller/node.go | 68 +++++++++++++++++++++++++---------------- run_operator_locally.sh | 2 +- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/pkg/controller/node.go b/pkg/controller/node.go index dc919c450..b3e30cc9b 100644 --- a/pkg/controller/node.go +++ b/pkg/controller/node.go @@ -7,7 +7,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" + "fmt" + "github.com/zalando-incubator/postgres-operator/pkg/cluster" + "github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/util" ) @@ -55,15 +58,16 @@ func (c *Controller) nodeUpdate(prev, cur interface{}) { return } - if util.MapContains(nodeCur.Labels, map[string]string{"master": "true"}) { + if !c.nodeIsReady(nodePrev) { + c.logger.Debugf("The decommissioned node %v should have already triggered master pod migration. Previous k8s-reported state of the node: %v", util.NameFromMeta(nodePrev.ObjectMeta), nodePrev) return } - // do nothing if the node should have already triggered an update or - // if only one of the label and the unschedulability criteria are met. - if !c.nodeIsReady(nodePrev) || c.nodeIsReady(nodeCur) { + if c.nodeIsReady(nodeCur) { + c.logger.Debugf("The decommissioned node %v become schedulable again. Current k8s-reported state of the node: %v", util.NameFromMeta(nodeCur.ObjectMeta), nodeCur) return } + c.moveMasterPodsOffNode(nodeCur) } @@ -73,8 +77,9 @@ func (c *Controller) nodeIsReady(node *v1.Node) bool { } func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { + nodeName := util.NameFromMeta(node.ObjectMeta) - c.logger.Infof("moving pods: node %q became unschedulable and does not have a ready label: %q", + c.logger.Infof("moving pods: node %q became unschedulable and does not have a ready label %q", nodeName, c.opConfig.NodeReadinessLabel) opts := metav1.ListOptions{ @@ -82,7 +87,7 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { } podList, err := c.KubeClient.Pods(c.opConfig.WatchedNamespace).List(opts) if err != nil { - c.logger.Errorf("could not fetch list of the pods: %v", err) + c.logger.Errorf("could not fetch the list of Spilo pods: %v", err) return } @@ -93,17 +98,25 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { } } + movedMasterPods := 0 + movableMasterPods := make(map[*v1.Pod]*cluster.Cluster) + unmovablePods := make(map[spec.NamespacedName]string) + clusters := make(map[*cluster.Cluster]bool) - masterPods := make(map[*v1.Pod]*cluster.Cluster) - movedPods := 0 + for _, pod := range nodePods { + podName := util.NameFromMeta(pod.ObjectMeta) role, ok := pod.Labels[c.opConfig.PodRoleLabel] - if !ok || cluster.PostgresRole(role) != cluster.Master { - if !ok { - c.logger.Warningf("could not move pod %q: pod has no role", podName) - } + if !ok { + // pods with an unknown role cannot be safely moved to another node + unmovablePods[podName] = fmt.Sprintf("could not move pod %q from node %q: pod has no role label %q", podName, nodeName, c.opConfig.PodRoleLabel) + continue + } + + // deployments can transparently re-create replicas so we do not move away such pods + if cluster.PostgresRole(role) == cluster.Replica { continue } @@ -113,7 +126,7 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { cl, ok := c.clusters[clusterName] c.clustersMu.RUnlock() if !ok { - c.logger.Warningf("could not move pod %q: pod does not belong to a known cluster", podName) + unmovablePods[podName] = fmt.Sprintf("could not move master pod %q from node %q: pod belongs to an unknown Postgres cluster %q", podName, nodeName, clusterName) continue } @@ -121,20 +134,20 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { clusters[cl] = true } - masterPods[pod] = cl + movableMasterPods[pod] = cl } for cl := range clusters { cl.Lock() } - for pod, cl := range masterPods { - podName := util.NameFromMeta(pod.ObjectMeta) + for pod, cl := range movableMasterPods { - if err := cl.MigrateMasterPod(podName); err != nil { - c.logger.Errorf("could not move master pod %q: %v", podName, err) + podName := util.NameFromMeta(pod.ObjectMeta) + if err := cl.MigrateMasterPod(podName); err == nil { + movedMasterPods++ } else { - movedPods++ + unmovablePods[podName] = fmt.Sprintf("could not move master pod %q from node %q: %v", podName, nodeName, err) } } @@ -142,15 +155,16 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { cl.Unlock() } - totalPods := len(masterPods) - - c.logger.Infof("%d/%d master pods have been moved out from the %q node", - movedPods, totalPods, nodeName) - - if leftPods := totalPods - movedPods; leftPods > 0 { - c.logger.Warnf("could not move master %d/%d pods from the %q node", - leftPods, totalPods, nodeName) + if leftPods := len(unmovablePods); leftPods > 0 { + c.logger.Warnf("could not move %d master or unknown role pods from the node %q, you may have to delete them manually", + leftPods, nodeName) + for _, reason := range unmovablePods { + c.logger.Warning(reason) + } } + + c.logger.Infof("%d master pods have been moved out from the node %q", movedMasterPods, nodeName) + } func (c *Controller) nodeDelete(obj interface{}) { diff --git a/run_operator_locally.sh b/run_operator_locally.sh index 301803c35..d6c416d56 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -121,7 +121,7 @@ function deploy_self_built_image() { # update the tag in the postgres operator conf # since the image with this tag already exists on the machine, # docker should not attempt to fetch it from the registry due to imagePullPolicy - sed --expression "s/\(image\:.*\:\).*$/\1$TAG/" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" + sed --expression "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" retry "kubectl create -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" } From 26670408c48612e92cbb59f1f02d78783e642096 Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Fri, 21 Dec 2018 17:39:34 +0100 Subject: [PATCH 07/33] Revert "Unify warnings about unmovable pods (#389)" (#430) This reverts commit 4fa09e0dcbe556106beaed4078e6c2756245e931. Reason: the reverted commit bloats the logs --- pkg/controller/node.go | 68 ++++++++++++++++------------------------- run_operator_locally.sh | 2 +- 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/pkg/controller/node.go b/pkg/controller/node.go index b3e30cc9b..dc919c450 100644 --- a/pkg/controller/node.go +++ b/pkg/controller/node.go @@ -7,10 +7,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" - "fmt" - "github.com/zalando-incubator/postgres-operator/pkg/cluster" - "github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/util" ) @@ -58,16 +55,15 @@ func (c *Controller) nodeUpdate(prev, cur interface{}) { return } - if !c.nodeIsReady(nodePrev) { - c.logger.Debugf("The decommissioned node %v should have already triggered master pod migration. Previous k8s-reported state of the node: %v", util.NameFromMeta(nodePrev.ObjectMeta), nodePrev) + if util.MapContains(nodeCur.Labels, map[string]string{"master": "true"}) { return } - if c.nodeIsReady(nodeCur) { - c.logger.Debugf("The decommissioned node %v become schedulable again. Current k8s-reported state of the node: %v", util.NameFromMeta(nodeCur.ObjectMeta), nodeCur) + // do nothing if the node should have already triggered an update or + // if only one of the label and the unschedulability criteria are met. + if !c.nodeIsReady(nodePrev) || c.nodeIsReady(nodeCur) { return } - c.moveMasterPodsOffNode(nodeCur) } @@ -77,9 +73,8 @@ func (c *Controller) nodeIsReady(node *v1.Node) bool { } func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { - nodeName := util.NameFromMeta(node.ObjectMeta) - c.logger.Infof("moving pods: node %q became unschedulable and does not have a ready label %q", + c.logger.Infof("moving pods: node %q became unschedulable and does not have a ready label: %q", nodeName, c.opConfig.NodeReadinessLabel) opts := metav1.ListOptions{ @@ -87,7 +82,7 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { } podList, err := c.KubeClient.Pods(c.opConfig.WatchedNamespace).List(opts) if err != nil { - c.logger.Errorf("could not fetch the list of Spilo pods: %v", err) + c.logger.Errorf("could not fetch list of the pods: %v", err) return } @@ -98,25 +93,17 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { } } - movedMasterPods := 0 - movableMasterPods := make(map[*v1.Pod]*cluster.Cluster) - unmovablePods := make(map[spec.NamespacedName]string) - clusters := make(map[*cluster.Cluster]bool) - + masterPods := make(map[*v1.Pod]*cluster.Cluster) + movedPods := 0 for _, pod := range nodePods { - podName := util.NameFromMeta(pod.ObjectMeta) role, ok := pod.Labels[c.opConfig.PodRoleLabel] - if !ok { - // pods with an unknown role cannot be safely moved to another node - unmovablePods[podName] = fmt.Sprintf("could not move pod %q from node %q: pod has no role label %q", podName, nodeName, c.opConfig.PodRoleLabel) - continue - } - - // deployments can transparently re-create replicas so we do not move away such pods - if cluster.PostgresRole(role) == cluster.Replica { + if !ok || cluster.PostgresRole(role) != cluster.Master { + if !ok { + c.logger.Warningf("could not move pod %q: pod has no role", podName) + } continue } @@ -126,7 +113,7 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { cl, ok := c.clusters[clusterName] c.clustersMu.RUnlock() if !ok { - unmovablePods[podName] = fmt.Sprintf("could not move master pod %q from node %q: pod belongs to an unknown Postgres cluster %q", podName, nodeName, clusterName) + c.logger.Warningf("could not move pod %q: pod does not belong to a known cluster", podName) continue } @@ -134,20 +121,20 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { clusters[cl] = true } - movableMasterPods[pod] = cl + masterPods[pod] = cl } for cl := range clusters { cl.Lock() } - for pod, cl := range movableMasterPods { - + for pod, cl := range masterPods { podName := util.NameFromMeta(pod.ObjectMeta) - if err := cl.MigrateMasterPod(podName); err == nil { - movedMasterPods++ + + if err := cl.MigrateMasterPod(podName); err != nil { + c.logger.Errorf("could not move master pod %q: %v", podName, err) } else { - unmovablePods[podName] = fmt.Sprintf("could not move master pod %q from node %q: %v", podName, nodeName, err) + movedPods++ } } @@ -155,16 +142,15 @@ func (c *Controller) moveMasterPodsOffNode(node *v1.Node) { cl.Unlock() } - if leftPods := len(unmovablePods); leftPods > 0 { - c.logger.Warnf("could not move %d master or unknown role pods from the node %q, you may have to delete them manually", - leftPods, nodeName) - for _, reason := range unmovablePods { - c.logger.Warning(reason) - } + totalPods := len(masterPods) + + c.logger.Infof("%d/%d master pods have been moved out from the %q node", + movedPods, totalPods, nodeName) + + if leftPods := totalPods - movedPods; leftPods > 0 { + c.logger.Warnf("could not move master %d/%d pods from the %q node", + leftPods, totalPods, nodeName) } - - c.logger.Infof("%d master pods have been moved out from the node %q", movedMasterPods, nodeName) - } func (c *Controller) nodeDelete(obj interface{}) { diff --git a/run_operator_locally.sh b/run_operator_locally.sh index d6c416d56..301803c35 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -121,7 +121,7 @@ function deploy_self_built_image() { # update the tag in the postgres operator conf # since the image with this tag already exists on the machine, # docker should not attempt to fetch it from the registry due to imagePullPolicy - sed --expression "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" + sed --expression "s/\(image\:.*\:\).*$/\1$TAG/" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" retry "kubectl create -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" } From c0b0b9a83282f8a0cbb089f68f011744a58e2e41 Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Thu, 27 Dec 2018 10:14:33 +0100 Subject: [PATCH 08/33] [WIP] Add 'admin' option to create role (#425) * Add 'admin' option to create role * Fix run_locally_script --- docs/reference/operator_parameters.md | 3 +++ manifests/configmap.yaml | 1 + pkg/cluster/cluster.go | 13 +++++++++---- pkg/spec/types.go | 1 + pkg/util/config/config.go | 1 + pkg/util/users/users.go | 7 ++++++- run_operator_locally.sh | 2 +- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 3f96b450c..23c625bcb 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -373,6 +373,9 @@ key. role name to grant to team members created from the Teams API. The default is `admin`, that role is created by Spilo as a `NOLOGIN` role. +* **enable_admin_role_for_users** + if `true`, the `team_admin_role` will have the rights to grant roles coming from PG manifests. Such roles will be created as in "CREATE ROLE 'role_from_manifest' ... ADMIN 'team_admin_role'". The default is `true`. + * **pam_role_name** when set, the operator will add all team member roles to this group and add a `pg_hba` line to authenticate members of that role via `pam`. The default is diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index d127e72f2..be72ce2c5 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -19,6 +19,7 @@ data: # postgres_superuser_teams: "postgres_superusers" # enable_team_superuser: "false" # team_admin_role: "admin" + # enable_admin_role_for_users: "true" # teams_api_url: http://fake-teams-api.default.svc.cluster.local # team_api_role_configuration: "log_statement:all" # infrastructure_roles_secret_name: postgresql-infrastructure-roles diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index b2208705a..7eaa873fd 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -709,11 +709,16 @@ func (c *Cluster) initRobotUsers() error { if err != nil { return fmt.Errorf("invalid flags for user %q: %v", username, err) } + adminRole := "" + if c.OpConfig.EnableAdminRoleForUsers { + adminRole = c.OpConfig.TeamAdminRole + } newRole := spec.PgUser{ - Origin: spec.RoleOriginManifest, - Name: username, - Password: util.RandomPassword(constants.PasswordLength), - Flags: flags, + Origin: spec.RoleOriginManifest, + Name: username, + Password: util.RandomPassword(constants.PasswordLength), + Flags: flags, + AdminRole: adminRole, } if currentRole, present := c.pgUsers[username]; present { c.pgUsers[username] = c.resolveNameConflict(¤tRole, &newRole) diff --git a/pkg/spec/types.go b/pkg/spec/types.go index e394462d4..edcde5a3b 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -49,6 +49,7 @@ type PgUser struct { Flags []string `yaml:"user_flags"` MemberOf []string `yaml:"inrole"` Parameters map[string]string `yaml:"db_parameters"` + AdminRole string `yaml:"admin_role"` } // PgUserMap maps user names to the definitions. diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index d855e0a2a..124935a03 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -90,6 +90,7 @@ type Config struct { EnableTeamsAPI bool `name:"enable_teams_api" default:"true"` EnableTeamSuperuser bool `name:"enable_team_superuser" default:"false"` TeamAdminRole string `name:"team_admin_role" default:"admin"` + EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"` EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"` EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` // deprecated and kept for backward compatibility diff --git a/pkg/util/users/users.go b/pkg/util/users/users.go index cd76c621d..b436595ef 100644 --- a/pkg/util/users/users.go +++ b/pkg/util/users/users.go @@ -5,9 +5,10 @@ import ( "fmt" "strings" + "reflect" + "github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/util" - "reflect" ) const ( @@ -19,6 +20,7 @@ const ( doBlockStmt = `SET LOCAL synchronous_commit = 'local'; DO $$ BEGIN %s; END;$$;` passwordTemplate = "ENCRYPTED PASSWORD '%s'" inRoleTemplate = `IN ROLE %s` + adminTemplate = `ADMIN %s` ) // DefaultUserSyncStrategy implements a user sync strategy that merges already existing database users @@ -113,6 +115,9 @@ func (strategy DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.D if len(user.MemberOf) > 0 { userFlags = append(userFlags, fmt.Sprintf(inRoleTemplate, quoteMemberList(user))) } + if user.AdminRole != "" { + userFlags = append(userFlags, fmt.Sprintf(adminTemplate, user.AdminRole)) + } if user.Password == "" { userPassword = "PASSWORD NULL" diff --git a/run_operator_locally.sh b/run_operator_locally.sh index 301803c35..d6c416d56 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -121,7 +121,7 @@ function deploy_self_built_image() { # update the tag in the postgres operator conf # since the image with this tag already exists on the machine, # docker should not attempt to fetch it from the registry due to imagePullPolicy - sed --expression "s/\(image\:.*\:\).*$/\1$TAG/" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" + sed --expression "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" retry "kubectl create -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" } From 8d766e020c81deb5db365b44154126bc14626fb3 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Wed, 2 Jan 2019 10:31:28 +0100 Subject: [PATCH 09/33] Fix reference to enable_database_access in operator_parameters.md (#435) --- docs/reference/operator_parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 23c625bcb..5192f7f36 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -334,7 +334,7 @@ Options to aid debugging of the operator itself. Grouped under the `debug` key. boolean parameter that toggles verbose debug logs from the operator. The default is `true`. -* **enable_db_access** +* **enable_database_access** boolean parameter that toggles the functionality of the operator that require access to the postgres database, i.e. creating databases and users. The default is `true`. From 5cfcc453a90e2a8d12b9a916d62aecbd6f867708 Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Wed, 2 Jan 2019 12:01:47 +0100 Subject: [PATCH 10/33] Update CRD configuration docs and fix the CDP build (#414) * Update CRD configuration docs * document resource consumption of the operator * Add talks by Oleksii --- docs/index.md | 4 ++- docs/reference/operator_parameters.md | 33 ++++++++++++++---------- manifests/minimal-postgres-manifest.yaml | 3 ++- manifests/postgres-operator.yaml | 7 +++++ pkg/cluster/k8sres.go | 1 + 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/docs/index.md b/docs/index.md index 397dbea0d..e038f713e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,9 @@ Please, report any issues discovered to https://github.com/zalando-incubator/pos ## Talks -1. "PostgreSQL High Availability on Kubernetes with Patroni" talk by Oleksii Kliukin, Atmosphere 2018: [video](https://www.youtube.com/watch?v=cFlwQOPPkeg) | [slides](https://speakerdeck.com/alexeyklyukin/postgresql-high-availability-on-kubernetes-with-patroni) +1. "PostgreSQL and Kubernetes: DBaaS without a vendor-lock" talk by Oleksii Kliukin, PostgreSQL Sessions 2018: [slides](https://speakerdeck.com/alexeyklyukin/postgresql-and-kubernetes-dbaas-without-a-vendor-lock) + +2. "PostgreSQL High Availability on Kubernetes with Patroni" talk by Oleksii Kliukin, Atmosphere 2018: [video](https://www.youtube.com/watch?v=cFlwQOPPkeg) | [slides](https://speakerdeck.com/alexeyklyukin/postgresql-high-availability-on-kubernetes-with-patroni) 2. "Blue elephant on-demand: Postgres + Kubernetes" talk by Oleksii Kliukin and Jan Mussler, FOSDEM 2018: [video](https://fosdem.org/2018/schedule/event/blue_elephant_on_demand_postgres_kubernetes/) | [slides (pdf)](https://www.postgresql.eu/events/fosdem2018/sessions/session/1735/slides/59/FOSDEM%202018_%20Blue_Elephant_On_Demand.pdf) diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 5192f7f36..e76a3627a 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -10,29 +10,37 @@ configuration. configuration structure. There is an [example](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/configmap.yaml) -* CRD-based configuration. The configuration is stored in the custom YAML - manifest, an instance of the custom resource definition (CRD) called - `OperatorConfiguration`. This CRD is registered by the operator - during the start when `POSTGRES_OPERATOR_CONFIGURATION_OBJECT` variable is - set to a non-empty value. The CRD-based configuration is a regular YAML - document; non-scalar keys are simply represented in the usual YAML way. The - usage of the CRD-based configuration is triggered by setting the - `POSTGRES_OPERATOR_CONFIGURATION_OBJECT` variable, which should point to the - `postgresql-operator-configuration` object name in the operators namespace. +* CRD-based configuration. The configuration is stored in a custom YAML + manifest. The manifest is an instance of the custom resource definition (CRD) called + `OperatorConfiguration`. The operator registers this CRD + during the start and uses it for configuration if the [operator deployment manifest ](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgres-operator.yaml#L21) sets the `POSTGRES_OPERATOR_CONFIGURATION_OBJECT` env variable to a non-empty value. The variable should point to the + `postgresql-operator-configuration` object in the operator's namespace. + + The CRD-based configuration is a regular YAML + document; non-scalar keys are simply represented in the usual YAML way. There are no default values built-in in the operator, each parameter that is not supplied in the configuration receives an empty value. In order to create your own configuration just copy the [default one](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml) and change it. -CRD-based configuration is more natural and powerful then the one based on + To test the CRD-based configuration locally, use the following + ```bash + kubectl create -f manifests/operator-service-account-rbac.yaml + kubectl create -f manifests/postgres-operator.yaml # set the env var as mentioned above + kubectl create -f manifests/postgresql-operator-default-configuration.yaml + kubectl get operatorconfigurations postgresql-operator-default-configuration -o yaml + ``` + Note that the operator first registers the definition of the CRD `OperatorConfiguration` and then waits for an instance of the CRD to be created. In between these two event the operator pod may be failing since it cannot fetch the not-yet-existing `OperatorConfiguration` instance. + +The CRD-based configuration is more powerful than the one based on ConfigMaps and should be used unless there is a compatibility requirement to use an already existing configuration. Even in that case, it should be rather straightforward to convert the configmap based configuration into the CRD-based one and restart the operator. The ConfigMaps-based configuration will be deprecated and subsequently removed in future releases. -Note that for the CRD-based configuration configuration groups below correspond +Note that for the CRD-based configuration groups of configuration options below correspond to the non-leaf keys in the target YAML (i.e. for the Kubernetes resources the key is `kubernetes`). The key is mentioned alongside the group description. The ConfigMap-based configuration is flat and does not allow non-leaf keys. @@ -46,7 +54,6 @@ They will be deprecated and removed in the future. Variable names are underscore-separated words. - ## General Those are top-level keys, containing both leaf keys and groups. @@ -222,7 +229,7 @@ CRD-based configuration. settings. The default is `1Gi`. * **set_memory_request_to_limit** - Set `memory_request` to `memory_limit` for all Postgres clusters (the default value is also increased). This prevents certain cases of memory overcommitment at the cost of overprovisioning memory and potential scheduling problems for containers with high memory limits due to the lack of memory on Kubernetes cluster nodes. This affects all containers (Postgres, Scalyr sidecar, and other sidecars). The default is `false`. + Set `memory_request` to `memory_limit` for all Postgres clusters (the default value is also increased). This prevents certain cases of memory overcommitment at the cost of overprovisioning memory and potential scheduling problems for containers with high memory limits due to the lack of memory on Kubernetes cluster nodes. This affects all containers created by the operator (Postgres, Scalyr sidecar, and other sidecars); to set resources for the operator's own container, change the [operator deployment manually](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgres-operator.yaml#L13). The default is `false`. * **enable_shm_volume** Instruct operator to start any new database pod without limitations on shm diff --git a/manifests/minimal-postgres-manifest.yaml b/manifests/minimal-postgres-manifest.yaml index ae5d36cbc..402946b09 100644 --- a/manifests/minimal-postgres-manifest.yaml +++ b/manifests/minimal-postgres-manifest.yaml @@ -15,7 +15,8 @@ spec: - createdb # role for application foo - foo_user: + foo_user: [] + #databases: name->owner databases: diff --git a/manifests/postgres-operator.yaml b/manifests/postgres-operator.yaml index d8a4a6ac4..fffb8ede8 100644 --- a/manifests/postgres-operator.yaml +++ b/manifests/postgres-operator.yaml @@ -14,6 +14,13 @@ spec: - name: postgres-operator image: registry.opensource.zalan.do/acid/smoke-tested-postgres-operator:v1.0.0-21-ge39915c imagePullPolicy: IfNotPresent + resources: + requests: + cpu: 500m + memory: 250Mi + limits: + cpu: 2000m + memory: 500Mi env: # provided additional ENV vars can overwrite individual config map entries - name: CONFIG_MAP_NAME diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 6a3a052bd..bfd5ccb01 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -661,6 +661,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State volumeClaimTemplate *v1.PersistentVolumeClaim ) + // Improve me. Please. if c.OpConfig.SetMemoryRequestToLimit { // controller adjusts the default memory request at operator startup From 744567826115680bbadff90f8ea2a45f5dcb61df Mon Sep 17 00:00:00 2001 From: Jan Mussler Date: Fri, 4 Jan 2019 12:25:38 +0100 Subject: [PATCH 11/33] bump spilo versions. (#439) --- manifests/configmap.yaml | 2 +- manifests/postgresql-operator-default-configuration.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index be72ce2c5..30fbbb63d 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -10,7 +10,7 @@ data: debug_logging: "true" workers: "4" - docker_image: registry.opensource.zalan.do/acid/spilo-cdp-10:1.5-p35 + docker_image: registry.opensource.zalan.do/acid/spilo-cdp-11:1.5-p42 pod_service_account_name: "zalando-postgres-operator" secret_name_template: '{username}.{cluster}.credentials' super_username: postgres diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index 391702cdc..6d3c819b7 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -4,7 +4,7 @@ metadata: name: postgresql-operator-default-configuration configuration: etcd_host: "" - docker_image: registry.opensource.zalan.do/acid/spilo-cdp-10:1.4-p29 + docker_image: registry.opensource.zalan.do/acid/spilo-cdp-11:1.5-p42 workers: 4 min_instances: -1 max_instances: -1 From f7058c754d69127b3ce6cc45c301ac2c59cc6f97 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Fri, 4 Jan 2019 13:42:52 +0100 Subject: [PATCH 12/33] Pass more variables to Spilo container (#437) Pass KUBERNETES_SCOPE_LABEL, KUBERNETES_ROLE_LABEL and KUBERNETES_LABELS to spilo container, so that they could be changed. Fix for #411 --- pkg/cluster/k8sres.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index bfd5ccb01..fec795ad0 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -339,7 +339,6 @@ func generateSpiloContainer( envVars []v1.EnvVar, volumeMounts []v1.VolumeMount, ) *v1.Container { - privilegedMode := true return &v1.Container{ Name: name, @@ -491,6 +490,18 @@ func (c *Cluster) generateSpiloPodEnvVars(uid types.UID, spiloConfiguration stri Name: "PGUSER_SUPERUSER", Value: c.OpConfig.SuperUsername, }, + { + Name: "KUBERNETES_SCOPE_LABEL", + Value: c.OpConfig.ClusterNameLabel, + }, + { + Name: "KUBERNETES_ROLE_LABEL", + Value: c.OpConfig.PodRoleLabel, + }, + { + Name: "KUBERNETES_LABELS", + Value: labels.Set(c.OpConfig.ClusterLabels).String(), + }, { Name: "PGPASSWORD_SUPERUSER", ValueFrom: &v1.EnvVarSource{ @@ -741,8 +752,8 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State // generate environment variables for the spilo container spiloEnvVars := deduplicateEnvVars( - c.generateSpiloPodEnvVars(c.Postgresql.GetUID(), spiloConfiguration, &spec.Clone, customPodEnvVarsList), - c.containerName(), c.logger) + c.generateSpiloPodEnvVars(c.Postgresql.GetUID(), spiloConfiguration, &spec.Clone, + customPodEnvVarsList), c.containerName(), c.logger) // pickup the docker image for the spilo container effectiveDockerImage := util.Coalesce(spec.DockerImage, c.OpConfig.DockerImage) @@ -750,6 +761,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State volumeMounts := generateVolumeMounts() // generate the spilo container + c.logger.Debugf("Generating Spilo container, environment variables: %v", spiloEnvVars) spiloContainer := generateSpiloContainer(c.containerName(), &effectiveDockerImage, resourceRequirements, @@ -757,7 +769,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State volumeMounts, ) - // resolve conflicts between operator-global and per-cluster sidecards + // resolve conflicts between operator-global and per-cluster sidecars sideCars := c.mergeSidecars(spec.Sidecars) resourceRequirementsScalyrSidecar := makeResources( @@ -786,7 +798,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State tolerationSpec := tolerations(&spec.Tolerations, c.OpConfig.PodToleration) effectivePodPriorityClassName := util.Coalesce(spec.PodPriorityClassName, c.OpConfig.PodPriorityClassName) - // generate pod template for the statefulset, based on the spilo container and sidecards + // generate pod template for the statefulset, based on the spilo container and sidecars if podTemplate, err = generatePodTemplate( c.Namespace, c.labelsSet(true), From 4b5d3cd121762786b707c8c7b2034971c6cf3958 Mon Sep 17 00:00:00 2001 From: zerg-junior Date: Tue, 8 Jan 2019 13:04:48 +0100 Subject: [PATCH 13/33] Fix golint failures * Fix golint fails based on the original work from the user u5surf * Skip installing Docker as CDP now have one pre-installed (repairs builds on CDP) --- cmd/main.go | 8 ++++---- delivery.yaml | 3 --- docs/reference/operator_parameters.md | 6 +++--- pkg/apis/acid.zalan.do/v1/const.go | 11 +++++++---- pkg/apis/acid.zalan.do/v1/crds.go | 3 +++ pkg/apis/acid.zalan.do/v1/doc.go | 2 +- pkg/apis/acid.zalan.do/v1/marshal.go | 1 + .../v1/operator_configuration_type.go | 18 ++++++++++++++++++ pkg/apis/acid.zalan.do/v1/postgresql_type.go | 4 +++- pkg/apis/acid.zalan.do/v1/register.go | 7 ++++++- pkg/apis/acid.zalan.do/v1/util.go | 2 ++ pkg/cluster/pod.go | 6 +----- pkg/cluster/types.go | 4 +++- pkg/cluster/util.go | 1 + pkg/spec/types.go | 1 + pkg/util/config/util.go | 4 ++++ pkg/util/retryutil/retry_util.go | 2 ++ pkg/util/teams/teams.go | 1 + 18 files changed, 61 insertions(+), 23 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index b400630f6..09ab40a87 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -47,14 +47,14 @@ func init() { log.Printf("Fully qualified configmap name: %v", config.ConfigMapName) } - if crd_interval := os.Getenv("CRD_READY_WAIT_INTERVAL"); crd_interval != "" { - config.CRDReadyWaitInterval = mustParseDuration(crd_interval) + if crdInterval := os.Getenv("CRD_READY_WAIT_INTERVAL"); crdInterval != "" { + config.CRDReadyWaitInterval = mustParseDuration(crdInterval) } else { config.CRDReadyWaitInterval = 4 * time.Second } - if crd_timeout := os.Getenv("CRD_READY_WAIT_TIMEOUT"); crd_timeout != "" { - config.CRDReadyWaitTimeout = mustParseDuration(crd_timeout) + if crdTimeout := os.Getenv("CRD_READY_WAIT_TIMEOUT"); crdTimeout != "" { + config.CRDReadyWaitTimeout = mustParseDuration(crdTimeout) } else { config.CRDReadyWaitTimeout = 30 * time.Second } diff --git a/delivery.yaml b/delivery.yaml index c939e64f0..5f1f5384f 100644 --- a/delivery.yaml +++ b/delivery.yaml @@ -20,9 +20,6 @@ pipeline: mv go /usr/local ln -s /usr/local/go/bin/go /usr/bin/go go version - - desc: 'Install Docker' - cmd: | - curl -fLOsS https://delivery.cloud.zalando.com/utils/ensure-docker && sh ensure-docker && rm ensure-docker - desc: 'Symlink sources into the GOPATH' cmd: | mkdir -p $OPERATOR_TOP_DIR diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index e76a3627a..81920b342 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -308,12 +308,12 @@ In the CRD-based configuration they are grouped under the `load_balancer` key. replaced with the hosted zone (the value of the `db_hosted_zone` parameter). No other placeholders are allowed. -## AWS or GSC interaction +## AWS or GCP interaction The options in this group configure operator interactions with non-Kubernetes -objects from AWS or Google cloud. They have no effect unless you are using +objects from Amazon Web Services (AWS) or Google Cloud Platform (GCP). They have no effect unless you are using either. In the CRD-based configuration those options are grouped under the -`aws_or_gcp` key. +`aws_or_gcp` key. Note the GCP integration is not yet officially supported. * **wal_s3_bucket** S3 bucket to use for shipping WAL segments with WAL-E. A bucket has to be diff --git a/pkg/apis/acid.zalan.do/v1/const.go b/pkg/apis/acid.zalan.do/v1/const.go index 4592a2d68..59d6c1406 100644 --- a/pkg/apis/acid.zalan.do/v1/const.go +++ b/pkg/apis/acid.zalan.do/v1/const.go @@ -1,10 +1,7 @@ package v1 +// ClusterStatusUnknown etc : status of a Postgres cluster known to the operator const ( - serviceNameMaxLength = 63 - clusterNameMaxLength = serviceNameMaxLength - len("-repl") - serviceNameRegexString = `^[a-z]([-a-z0-9]*[a-z0-9])?$` - ClusterStatusUnknown PostgresStatus = "" ClusterStatusCreating PostgresStatus = "Creating" ClusterStatusUpdating PostgresStatus = "Updating" @@ -14,3 +11,9 @@ const ( ClusterStatusRunning PostgresStatus = "Running" ClusterStatusInvalid PostgresStatus = "Invalid" ) + +const ( + serviceNameMaxLength = 63 + clusterNameMaxLength = serviceNameMaxLength - len("-repl") + serviceNameRegexString = `^[a-z]([-a-z0-9]*[a-z0-9])?$` +) diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go index 5cefa1c83..5f1704527 100644 --- a/pkg/apis/acid.zalan.do/v1/crds.go +++ b/pkg/apis/acid.zalan.do/v1/crds.go @@ -6,6 +6,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// CRDResource* define names necesssary for the k8s CRD API const ( PostgresCRDResourceKind = "postgresql" PostgresCRDResourcePlural = "postgresqls" @@ -39,6 +40,7 @@ func buildCRD(name, kind, plural, short string) *apiextv1beta1.CustomResourceDef } } +// PostgresCRD returns CustomResourceDefinition built from PostgresCRDResource func PostgresCRD() *apiextv1beta1.CustomResourceDefinition { return buildCRD(PostgresCRDResouceName, PostgresCRDResourceKind, @@ -46,6 +48,7 @@ func PostgresCRD() *apiextv1beta1.CustomResourceDefinition { PostgresCRDResourceShort) } +// ConfigurationCRD returns CustomResourceDefinition built from OperatorConfigCRDResource func ConfigurationCRD() *apiextv1beta1.CustomResourceDefinition { return buildCRD(OperatorConfigCRDResourceName, OperatorConfigCRDResouceKind, diff --git a/pkg/apis/acid.zalan.do/v1/doc.go b/pkg/apis/acid.zalan.do/v1/doc.go index 5accd806d..159378752 100644 --- a/pkg/apis/acid.zalan.do/v1/doc.go +++ b/pkg/apis/acid.zalan.do/v1/doc.go @@ -1,6 +1,6 @@ +// Package v1 is the v1 version of the API. // +k8s:deepcopy-gen=package,register -// Package v1 is the v1 version of the API. // +groupName=acid.zalan.do package v1 diff --git a/pkg/apis/acid.zalan.do/v1/marshal.go b/pkg/apis/acid.zalan.do/v1/marshal.go index b24c4e49d..823ff0ef2 100644 --- a/pkg/apis/acid.zalan.do/v1/marshal.go +++ b/pkg/apis/acid.zalan.do/v1/marshal.go @@ -104,6 +104,7 @@ func (p *Postgresql) UnmarshalJSON(data []byte) error { return nil } +// UnmarshalJSON convert to Duration from byte slice of json func (d *Duration) UnmarshalJSON(b []byte) error { var ( v interface{} 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 da163620b..f2759f5ad 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -13,6 +13,8 @@ import ( // +genclient:onlyVerbs=get // +genclient:noStatus // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OperatorConfiguration defines the specification for the OperatorConfiguration. type OperatorConfiguration struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata"` @@ -21,6 +23,8 @@ type OperatorConfiguration struct { } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OperatorConfigurationList is used in the k8s API calls type OperatorConfigurationList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata"` @@ -28,11 +32,13 @@ type OperatorConfigurationList struct { Items []OperatorConfiguration `json:"items"` } +// PostgresUsersConfiguration defines the system users of Postgres. type PostgresUsersConfiguration struct { SuperUsername string `json:"super_username,omitempty"` ReplicationUsername string `json:"replication_username,omitempty"` } +// KubernetesMetaConfiguration defines k8s conf required for all Postgres clusters and the operator itself type KubernetesMetaConfiguration struct { PodServiceAccountName string `json:"pod_service_account_name,omitempty"` // TODO: change it to the proper json @@ -55,6 +61,7 @@ type KubernetesMetaConfiguration struct { PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` } +// PostgresPodResourcesDefaults defines the spec of default resources type PostgresPodResourcesDefaults struct { DefaultCPURequest string `json:"default_cpu_request,omitempty"` DefaultMemoryRequest string `json:"default_memory_request,omitempty"` @@ -62,6 +69,7 @@ type PostgresPodResourcesDefaults struct { DefaultMemoryLimit string `json:"default_memory_limit,omitempty"` } +// OperatorTimeouts defines the timeout of ResourceCheck, PodWait, ReadyWait type OperatorTimeouts struct { ResourceCheckInterval Duration `json:"resource_check_interval,omitempty"` ResourceCheckTimeout Duration `json:"resource_check_timeout,omitempty"` @@ -71,6 +79,7 @@ type OperatorTimeouts struct { ReadyWaitTimeout Duration `json:"ready_wait_timeout,omitempty"` } +// LoadBalancerConfiguration defines the LB configuration type LoadBalancerConfiguration struct { DbHostedZone string `json:"db_hosted_zone,omitempty"` EnableMasterLoadBalancer bool `json:"enable_master_load_balancer,omitempty"` @@ -79,6 +88,8 @@ type LoadBalancerConfiguration struct { ReplicaDNSNameFormat config.StringTemplate `json:"replica_dns_name_format,omitempty"` } +// AWSGCPConfiguration defines the configuration for AWS +// TODO complete Google Cloud Platform (GCP) configuration type AWSGCPConfiguration struct { WALES3Bucket string `json:"wal_s3_bucket,omitempty"` AWSRegion string `json:"aws_region,omitempty"` @@ -86,11 +97,13 @@ type AWSGCPConfiguration struct { KubeIAMRole string `json:"kube_iam_role,omitempty"` } +// OperatorDebugConfiguration defines options for the debug mode type OperatorDebugConfiguration struct { DebugLogging bool `json:"debug_logging,omitempty"` EnableDBAccess bool `json:"enable_database_access,omitempty"` } +// TeamsAPIConfiguration defines the configration of TeamsAPI type TeamsAPIConfiguration struct { EnableTeamsAPI bool `json:"enable_teams_api,omitempty"` TeamsAPIUrl string `json:"teams_api_url,omitempty"` @@ -103,12 +116,14 @@ type TeamsAPIConfiguration struct { PostgresSuperuserTeams []string `json:"postgres_superuser_teams,omitempty"` } +// LoggingRESTAPIConfiguration defines Logging API conf type LoggingRESTAPIConfiguration struct { APIPort int `json:"api_port,omitempty"` RingLogLines int `json:"ring_log_lines,omitempty"` ClusterHistoryEntries int `json:"cluster_history_entries,omitempty"` } +// ScalyrConfiguration defines the configuration for ScalyrAPI type ScalyrConfiguration struct { ScalyrAPIKey string `json:"scalyr_api_key,omitempty"` ScalyrImage string `json:"scalyr_image,omitempty"` @@ -119,6 +134,7 @@ type ScalyrConfiguration struct { ScalyrMemoryLimit string `json:"scalyr_memory_limit,omitempty"` } +// OperatorConfigurationData defines the operation config type OperatorConfigurationData struct { EtcdHost string `json:"etcd_host,omitempty"` DockerImage string `json:"docker_image,omitempty"` @@ -141,6 +157,7 @@ type OperatorConfigurationData struct { Scalyr ScalyrConfiguration `json:"scalyr"` } +// OperatorConfigurationUsers defines configration for super user type OperatorConfigurationUsers struct { SuperUserName string `json:"superuser_name,omitempty"` Replication string `json:"replication_user_name,omitempty"` @@ -148,4 +165,5 @@ type OperatorConfigurationUsers struct { TeamAPIRoleConfiguration map[string]string `json:"team_api_role_configuration,omitempty"` } +//Duration shortens this frequently used name type Duration time.Duration diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 2a8f60f71..4315faeca 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -9,7 +9,8 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -//Postgresql defines PostgreSQL Custom Resource Definition Object. + +// Postgresql defines PostgreSQL Custom Resource Definition Object. type Postgresql struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -55,6 +56,7 @@ type PostgresSpec struct { } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + // PostgresqlList defines a list of PostgreSQL clusters. type PostgresqlList struct { metav1.TypeMeta `json:",inline"` diff --git a/pkg/apis/acid.zalan.do/v1/register.go b/pkg/apis/acid.zalan.do/v1/register.go index 7dd03fad1..165981a68 100644 --- a/pkg/apis/acid.zalan.do/v1/register.go +++ b/pkg/apis/acid.zalan.do/v1/register.go @@ -8,15 +8,20 @@ import ( "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do" ) +// APIVersion of the `postgresql` and `operator` CRDs const ( APIVersion = "v1" ) var ( // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + + // An instance of runtime.SchemeBuilder, global for this package SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + //AddToScheme is localSchemeBuilder.AddToScheme + AddToScheme = localSchemeBuilder.AddToScheme + //SchemeGroupVersion has GroupName and APIVersion SchemeGroupVersion = schema.GroupVersion{Group: acidzalando.GroupName, Version: APIVersion} ) diff --git a/pkg/apis/acid.zalan.do/v1/util.go b/pkg/apis/acid.zalan.do/v1/util.go index 2d3c90db8..0a3267972 100644 --- a/pkg/apis/acid.zalan.do/v1/util.go +++ b/pkg/apis/acid.zalan.do/v1/util.go @@ -14,6 +14,7 @@ var ( serviceNameRegex = regexp.MustCompile(serviceNameRegexString) ) +// Clone convenience wrapper around DeepCopy func (p *Postgresql) Clone() *Postgresql { if p == nil { return nil @@ -83,6 +84,7 @@ func validateCloneClusterDescription(clone *CloneDescription) error { return nil } +// Success of the current Status func (status PostgresStatus) Success() bool { return status != ClusterStatusAddFailed && status != ClusterStatusUpdateFailed && diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index ab282b6b9..6256da6bf 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -77,11 +77,7 @@ func (c *Cluster) deletePod(podName spec.NamespacedName) error { return err } - if err := c.waitForPodDeletion(ch); err != nil { - return err - } - - return nil + return c.waitForPodDeletion(ch) } func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) { diff --git a/pkg/cluster/types.go b/pkg/cluster/types.go index 83b7e73fb..681f99e1f 100644 --- a/pkg/cluster/types.go +++ b/pkg/cluster/types.go @@ -1,12 +1,13 @@ package cluster import ( + "time" + acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1" "k8s.io/api/apps/v1beta1" "k8s.io/api/core/v1" policybeta1 "k8s.io/api/policy/v1beta1" "k8s.io/apimachinery/pkg/types" - "time" ) // PostgresRole describes role of the node @@ -20,6 +21,7 @@ const ( Replica PostgresRole = "replica" ) +// PodEventType represents the type of a pod-related event type PodEventType string // Possible values for the EventType diff --git a/pkg/cluster/util.go b/pkg/cluster/util.go index dbfda1c0e..f6e2ff096 100644 --- a/pkg/cluster/util.go +++ b/pkg/cluster/util.go @@ -460,6 +460,7 @@ func (c *Cluster) setSpec(newSpec *acidv1.Postgresql) { c.specMu.Unlock() } +// GetSpec returns a copy of the operator-side spec of a Postgres cluster in a thread-safe manner func (c *Cluster) GetSpec() (*acidv1.Postgresql, error) { c.specMu.RLock() defer c.specMu.RUnlock() diff --git a/pkg/spec/types.go b/pkg/spec/types.go index edcde5a3b..3e6bec8db 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -126,6 +126,7 @@ func (n *NamespacedName) Decode(value string) error { return n.DecodeWorker(value, GetOperatorNamespace()) } +// UnmarshalJSON converts a byte slice to NamespacedName func (n *NamespacedName) UnmarshalJSON(data []byte) error { result := NamespacedName{} var tmp string diff --git a/pkg/util/config/util.go b/pkg/util/config/util.go index 498810bb7..4c1bdf7e0 100644 --- a/pkg/util/config/util.go +++ b/pkg/util/config/util.go @@ -19,6 +19,7 @@ type fieldInfo struct { Field reflect.Value } +// StringTemplate is a convenience alias type StringTemplate string func decoderFrom(field reflect.Value) (d decoder) { @@ -221,12 +222,14 @@ func getMapPairsFromString(value string) (pairs []string, err error) { return } +// Decode cast value to StringTemplate func (f *StringTemplate) Decode(value string) error { *f = StringTemplate(value) return nil } +// Format formatted string from StringTemplate func (f *StringTemplate) Format(a ...string) string { res := string(*f) @@ -237,6 +240,7 @@ func (f *StringTemplate) Format(a ...string) string { return res } +// MarshalJSON converts a StringTemplate to byte slice func (f StringTemplate) MarshalJSON() ([]byte, error) { return json.Marshal(string(f)) } diff --git a/pkg/util/retryutil/retry_util.go b/pkg/util/retryutil/retry_util.go index cbae3bb1b..f8b61fc39 100644 --- a/pkg/util/retryutil/retry_util.go +++ b/pkg/util/retryutil/retry_util.go @@ -17,8 +17,10 @@ type Ticker struct { ticker *time.Ticker } +// Stop is a convenience wrapper around ticker.Stop func (t *Ticker) Stop() { t.ticker.Stop() } +// Tick is a convenience wrapper around ticker.C func (t *Ticker) Tick() { <-t.ticker.C } // Retry is a wrapper around RetryWorker that provides a real RetryTicker diff --git a/pkg/util/teams/teams.go b/pkg/util/teams/teams.go index 8afcd1a3b..d7413ab9c 100644 --- a/pkg/util/teams/teams.go +++ b/pkg/util/teams/teams.go @@ -43,6 +43,7 @@ type httpClient interface { Do(req *http.Request) (*http.Response, error) } +// Interface to the TeamsAPIClient type Interface interface { TeamInfo(teamID, token string) (tm *Team, err error) } From c70905ae8b443c62322287a5e2f356cce7d00f15 Mon Sep 17 00:00:00 2001 From: Jan Mussler Date: Tue, 8 Jan 2019 13:07:36 +0100 Subject: [PATCH 14/33] Modifying some of the logging to be more descriptive. (#440) * Modifying some of the logging to be more descriptive. --- pkg/cluster/cluster.go | 8 ++++---- pkg/cluster/pod.go | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 7eaa873fd..93a67226f 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -12,7 +12,7 @@ import ( "github.com/sirupsen/logrus" "k8s.io/api/apps/v1beta1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" policybeta1 "k8s.io/api/policy/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -877,7 +877,7 @@ func (c *Cluster) GetStatus() *ClusterStatus { func (c *Cluster) Switchover(curMaster *v1.Pod, candidate spec.NamespacedName) error { var err error - c.logger.Debugf("failing over from %q to %q", curMaster.Name, candidate) + c.logger.Debugf("switching over from %q to %q", curMaster.Name, candidate) var wg sync.WaitGroup @@ -903,12 +903,12 @@ func (c *Cluster) Switchover(curMaster *v1.Pod, candidate spec.NamespacedName) e }() if err = c.patroni.Switchover(curMaster, candidate.Name); err == nil { - c.logger.Debugf("successfully failed over from %q to %q", curMaster.Name, candidate) + c.logger.Debugf("successfully switched over from %q to %q", curMaster.Name, candidate) if err = <-podLabelErr; err != nil { err = fmt.Errorf("could not get master pod label: %v", err) } } else { - err = fmt.Errorf("could not failover: %v", err) + err = fmt.Errorf("could not switch over: %v", err) } // signal the role label waiting goroutine to close the shop and go home diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 6256da6bf..7fc068bf2 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -4,7 +4,7 @@ import ( "fmt" "math/rand" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/zalando-incubator/postgres-operator/pkg/spec" @@ -118,7 +118,7 @@ func (c *Cluster) movePodFromEndOfLifeNode(pod *v1.Pod) (*v1.Pod, error) { if eol, err = c.podIsEndOfLife(pod); err != nil { return nil, fmt.Errorf("could not get node %q: %v", pod.Spec.NodeName, err) } else if !eol { - c.logger.Infof("pod %q is already on a live node", podName) + c.logger.Infof("check failed: pod %q is already on a live node", podName) return pod, nil } @@ -158,7 +158,7 @@ func (c *Cluster) masterCandidate(oldNodeName string) (*v1.Pod, error) { } if len(replicas) == 0 { - c.logger.Warningf("no available master candidates, migration will cause longer downtime of the master instance") + c.logger.Warningf("no available master candidates, migration will cause longer downtime of Postgres cluster") return nil, nil } @@ -189,18 +189,18 @@ func (c *Cluster) MigrateMasterPod(podName spec.NamespacedName) error { return fmt.Errorf("could not get pod: %v", err) } - c.logger.Infof("migrating master pod %q", podName) + c.logger.Infof("starting process to migrate master pod %q", podName) if eol, err = c.podIsEndOfLife(oldMaster); err != nil { return fmt.Errorf("could not get node %q: %v", oldMaster.Spec.NodeName, err) } if !eol { - c.logger.Debugf("pod is already on a live node") + c.logger.Debugf("no action needed: master pod is already on a live node") return nil } if role := PostgresRole(oldMaster.Labels[c.OpConfig.PodRoleLabel]); role != Master { - c.logger.Warningf("pod %q is not a master", podName) + c.logger.Warningf("no action needed: pod %q is not the master (anymore)", podName) return nil } // we must have a statefulset in the cluster for the migration to work @@ -215,10 +215,10 @@ func (c *Cluster) MigrateMasterPod(podName spec.NamespacedName) error { // We may not have a cached statefulset if the initial cluster sync has aborted, revert to the spec in that case. if *c.Statefulset.Spec.Replicas > 1 { if masterCandidatePod, err = c.masterCandidate(oldMaster.Spec.NodeName); err != nil { - return fmt.Errorf("could not get new master candidate: %v", err) + return fmt.Errorf("could not find suitable replica pod as candidate for failover: %v", err) } } else { - c.logger.Warningf("single master pod for cluster %q, migration will cause longer downtime of the master instance", c.clusterName()) + c.logger.Warningf("migrating single pod cluster %q, this will cause downtime of the Postgres cluster until pod is back", c.clusterName()) } // there are two cases for each postgres cluster that has its master pod on the node to migrate from: @@ -252,15 +252,15 @@ func (c *Cluster) MigrateReplicaPod(podName spec.NamespacedName, fromNodeName st return fmt.Errorf("could not get pod: %v", err) } - c.logger.Infof("migrating replica pod %q", podName) + c.logger.Infof("migrating replica pod %q to live node", podName) if replicaPod.Spec.NodeName != fromNodeName { - c.logger.Infof("pod %q has already migrated to node %q", podName, replicaPod.Spec.NodeName) + c.logger.Infof("check failed: pod %q has already migrated to node %q", podName, replicaPod.Spec.NodeName) return nil } if role := PostgresRole(replicaPod.Labels[c.OpConfig.PodRoleLabel]); role != Replica { - return fmt.Errorf("pod %q is not a replica", podName) + return fmt.Errorf("check failed: pod %q is not a replica", podName) } _, err = c.movePodFromEndOfLifeNode(replicaPod) @@ -292,7 +292,7 @@ func (c *Cluster) recreatePod(podName spec.NamespacedName) (*v1.Pod, error) { } func (c *Cluster) recreatePods() error { - c.setProcessName("recreating pods") + c.setProcessName("starting to recreate pods") ls := c.labelsSet(false) namespace := c.Namespace @@ -333,10 +333,10 @@ func (c *Cluster) recreatePods() error { // failover if we have not observed a master pod when re-creating former replicas. if newMasterPod == nil && len(replicas) > 0 { if err := c.Switchover(masterPod, masterCandidate(replicas)); err != nil { - c.logger.Warningf("could not perform failover: %v", err) + c.logger.Warningf("could not perform switch over: %v", err) } } else if newMasterPod == nil && len(replicas) == 0 { - c.logger.Warningf("cannot switch master role before re-creating the pod: no replicas") + c.logger.Warningf("cannot perform switch over before re-creating the pod: no replicas") } c.logger.Infof("recreating old master pod %q", util.NameFromMeta(masterPod.ObjectMeta)) From 0921c065e86719a4fa4bc6e4cd04bccb447277ee Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Wed, 16 Jan 2019 10:50:29 +0100 Subject: [PATCH 15/33] Fixed endpoints description for debug API (#453) --- docs/developer.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/developer.md b/docs/developer.md index 5d766b023..220d764d0 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -188,13 +188,13 @@ defaults to 4) * /workers/$id/logs - log of the operations performed by a given worker * /clusters/ - list of teams and clusters known to the operator * /clusters/$team - list of clusters for the given team -* /cluster/$team/$clustername - detailed status of the cluster, including the +* /clusters/$team/$namespace/$clustername - detailed status of the cluster, including the specifications for CRD, master and replica services, endpoints and statefulsets, as well as any errors and the worker that cluster is assigned to. -* /cluster/$team/$clustername/logs/ - logs of all operations performed to the +* /clusters/$team/$namespace/$clustername/logs/ - logs of all operations performed to the cluster so far. -* /cluster/$team/$clustername/history/ - history of cluster changes triggered +* /clusters/$team/$namespace/$clustername/history/ - history of cluster changes triggered by the changes of the manifest (shows the somewhat obscure diff and what exactly has triggered the change) From 2422d72b76049efd46b52ac72f45ddcfb2007ff6 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Wed, 16 Jan 2019 10:59:32 +0100 Subject: [PATCH 16/33] Edited Roles section in User documentation (#454) --- docs/user.md | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/docs/user.md b/docs/user.md index ae6abcbe9..8c93449c3 100644 --- a/docs/user.md +++ b/docs/user.md @@ -57,12 +57,11 @@ $ psql -U postgres Postgres operator allows defining roles to be created in the resulting database cluster. It covers three use-cases: -* create application roles specific to the cluster described in the manifest: - `manifest roles`. -* create application roles that should be automatically created on every - cluster managed by the operator: `infrastructure roles`. -* automatically create users for every member of the team owning the database - cluster: `teams API roles`. +* `manifest roles`: create application roles specific to the cluster described in the manifest. +* `infrastructure roles`: create application roles that should be automatically created on every + cluster managed by the operator. +* `teams API roles`: automatically create users for every member of the team owning the database + cluster. In the next sections, we will cover those use cases in more details. @@ -75,7 +74,7 @@ flags. Manifest roles are defined as a dictionary, with a role name as a key and a list of role options as a value. For a role without any options it is best to supply the empty -list `[]`. It is also possible to leave this field empty as in our example manifests, but in certain cases such empty field may removed by Kubernetes [due to the `null` value it gets](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes) (`foobar_user:` is equivalent to `foobar_user: null`). +list `[]`. It is also possible to leave this field empty as in our example manifests, but in certain cases such empty field may removed by Kubernetes [due to the `null` value it gets](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes) (`foobar_user:` is equivalent to `foobar_user: null`). The operator accepts the following options: `superuser`, `inherit`, `login`, `nologin`, `createrole`, `createdb`, `replication`, `bypassrls`. @@ -99,10 +98,13 @@ An infrastructure role is a role that should be present on every PostgreSQL cluster managed by the operator. An example of such a role is a monitoring user. There are two ways to define them: -* Exclusively via the infrastructure roles secret (specified by the - `infrastructure_roles_secret_name` parameter). +* With the infrastructure roles secret only +* With both the the secret and the infrastructure role ConfigMap. -The role definition looks like this (values are base64 encoded): +### Infrastructure roles secret + +The infrastructure roles secret is specified by the `infrastructure_roles_secret_name` +parameter. The role definition looks like this (values are base64 encoded): ```yaml user1: ZGJ1c2Vy @@ -110,25 +112,29 @@ The role definition looks like this (values are base64 encoded): inrole1: b3BlcmF0b3I= ``` -A block above describes the infrastructure role 'dbuser' with the password -'secret' that is the member of the 'operator' role. For the following +The block above describes the infrastructure role 'dbuser' with password +'secret' that is a member of the 'operator' role. For the following definitions one must increase the index, i.e. the next role will be defined as -'user2' and so on. Note that there is no way to specify role options (like -superuser or nologin) this way, and the resulting role will automatically be a -login role. +'user2' and so on. The resulting role will automatically be a login role. -* Via both the infrastructure roles secret and the infrastructure role - configmap (with the same name as the infrastructure roles secret). +Note that with definitions that solely use the infrastructure roles secret +there is no way to specify role options (like superuser or nologin) or role +memberships. This is where the ConfigMap comes into play. -The infrastructure roles secret should contain an entry with 'rolename: -rolepassword' for each role, and the role description should be specified in -the configmap. Below is the example: +### Secret plus ConfigMap + +A [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) +allows for defining more details regarding the infrastructure roles. +Therefore, one should use the new style that specifies infrastructure roles +using both the secret and a ConfigMap. The ConfigMap must have the same name as +the secret. The secret should contain an entry with 'rolename:rolepassword' for +each role. ```yaml dbuser: c2VjcmV0 ``` -and the configmap definition for that user: +And the role description for that user should be specified in the ConfigMap. ```yaml data: @@ -140,18 +146,13 @@ and the configmap definition for that user: log_statement: all ``` -Note that the definition above allows for more details than the one that relies -solely on the infrastructure role secret. In particular, one can allow -membership in multiple roles via the `inrole` array parameter, define role -flags via the `user_flags` list and supply per-role options through the -`db_parameters` dictionary. All those parameters are optional. +One can allow membership in multiple roles via the `inrole` array parameter, +define role flags via the `user_flags` list and supply per-role options through +the `db_parameters` dictionary. All those parameters are optional. -The definitions that solely use the infrastructure roles secret are more -limited and considered legacy ones; one should use the new style that specifies -infrastructure roles using both the secret and the configmap. You can mix both -in the infrastructure role secret, as long as your new-style definition can be -clearly distinguished from the old-style one (for instance, do not name -new-style roles`userN`). +Both definitions can be mixed in the infrastructure role secret, as long as +your new-style definition can be clearly distinguished from the old-style one +(for instance, do not name new-style roles `userN`). Since an infrastructure role is created uniformly on all clusters managed by the operator, it makes no sense to define it without the password. Such From 1ac279b8adeef43aa27832fed8bdce5ef893b2da Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Fri, 18 Jan 2019 12:48:44 +0100 Subject: [PATCH 17/33] Update CODEOWNERS (#457) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 7e6db5933..42b83593a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,2 @@ # global owners -* @alexeyklyukin @erthalion @zerg-junior @Jan-M @CyberDem0n @avaczi +* @alexeyklyukin @erthalion @sdudoladov @Jan-M @CyberDem0n @avaczi From 38f7a3dac699a79af32e2f9b89fc05447c6ecfab Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Fri, 18 Jan 2019 12:50:07 +0100 Subject: [PATCH 18/33] Minor changes to Admin doc (#455) Fixing links and small errors Some homogenization of naming things Added line breaks in some paragraphs --- docs/administrator.md | 88 +++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/docs/administrator.md b/docs/administrator.md index f2c747cce..a69dc99cf 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -1,6 +1,6 @@ ## Create ConfigMap -ConfigMap is used to store the configuration of the operator +A ConfigMap is used to store the configuration of the operator. ```bash $ kubectl create -f manifests/configmap.yaml @@ -46,7 +46,9 @@ manifests: All subsequent `kubectl` commands will work with the `test` namespace. The operator will run in this namespace and look up needed resources - such as its -config map - there. Please note that the namespace for service accounts and cluster role bindings in [operator RBAC rules](manifests/operator-service-account-rbac.yaml) needs to be adjusted to the non-default value. +ConfigMap - there. Please note that the namespace for service accounts and +cluster role bindings in [operator RBAC rules](../manifests/operator-service-account-rbac.yaml) +needs to be adjusted to the non-default value. ## Specify the namespace to watch @@ -56,8 +58,10 @@ replicas to 5" and reacting to the requests, in this example by actually scaling up. By default, the operator watches the namespace it is deployed to. You can -change this by altering the `WATCHED_NAMESPACE` env var in the operator -deployment manifest or the `watched_namespace` field in the operator configmap. +change this by setting the `WATCHED_NAMESPACE` var in the `env` section of the +[operator deployment](../manifests/postgres-operator.yaml) manifest or by +altering the `watched_namespace` field in the operator +[ConfigMap](../manifests/configmap.yaml#L6). In the case both are set, the env var takes the precedence. To make the operator listen to all namespaces, explicitly set the field/env var to "`*`". @@ -75,7 +79,7 @@ in the case database pods need to talk to the Kubernetes API (e.g. when using Kubernetes-native configuration of Patroni). The operator checks that the `pod_service_account_name` exists in the target namespace, and, if not, deploys there the `pod_service_account_definition` from the operator -[`Config`](pkg/util/config/config.go) with the default value of: +[`Config`](../pkg/util/config/config.go) with the default value of: ```yaml apiVersion: v1 @@ -86,13 +90,13 @@ metadata: In this definition, the operator overwrites the account's name to match `pod_service_account_name` and the `default` namespace to match the target -namespace. The operator performs **no** further syncing of this account. +namespace. The operator performs **no** further syncing of this account. ## Role-based access control for the operator -The `manifests/operator-service-account-rbac.yaml` defines cluster roles and bindings needed -for the operator to function under access control restrictions. To deploy the -operator with this RBAC policy use: +The `manifests/operator-service-account-rbac.yaml` defines cluster roles and +bindings needed for the operator to function under access control restrictions. +To deploy the operator with this RBAC policy use: ```bash $ kubectl create -f manifests/configmap.yaml @@ -103,18 +107,18 @@ operator with this RBAC policy use: Note that the service account in `operator-rbac.yaml` is named `zalando-postgres-operator`. You may have to change the `service_account_name` -in the operator configmap and `serviceAccountName` in the postgres-operator +in the operator ConfigMap and `serviceAccountName` in the postgres-operator deployment appropriately. -This is done intentionally, as to avoid breaking those setups that already work +This is done intentionally to avoid breaking those setups that already work with the default `operator` account. In the future the operator should ideally be run under the `zalando-postgres-operator` service account. -The service account defined in `operator-rbac.yaml` acquires some privileges -not really used by the operator (i.e. we only need list and watch on -configmaps), this is also done intentionally to avoid breaking things if -someone decides to configure the same service account in the operator's -configmap to run postgres clusters. +The service account defined in `operator-rbac.yaml` acquires some privileges +not really used by the operator (i.e. we only need `list` and `watch` on +`configmaps` resources), this is also done intentionally to avoid breaking +things if someone decides to configure the same service account in the +operator's ConfigMap to run postgres clusters. ### Use taints and tolerations for dedicated PostgreSQL nodes @@ -144,12 +148,12 @@ data: ## Custom Pod Environment Variables -It is possible to configure a config map which is used by the Postgres pods as +It is possible to configure a ConfigMap which is used by the Postgres pods as an additional provider for environment variables. One use case is to customize the Spilo image and configure it with environment -variables. The config map with the additional settings is configured in the -operator's main config map: +variables. The ConfigMap with the additional settings is configured in the +operator's main ConfigMap: **postgres-operator ConfigMap** @@ -186,12 +190,12 @@ instances permitted by each Postgres cluster managed by the operator. If either `min_instances` or `max_instances` is set to a non-zero value, the operator may adjust the number of instances specified in the cluster manifest to match either the min or the max boundary. For instance, of a cluster manifest has 1 -instance and the min_instances is set to 3, the cluster will be created with 3 -instances. By default, both parameters are set to -1. +instance and the `min_instances` is set to 3, the cluster will be created with 3 +instances. By default, both parameters are set to `-1`. ## Load balancers -For any Postgresql/Spilo cluster, the operator creates two separate k8s +For any Postgresql/Spilo cluster, the operator creates two separate Kubernetes services: one for the master pod and one for replica pods. To expose these services to an outer network, one can attach load balancers to them by setting `enableMasterLoadBalancer` and/or `enableReplicaLoadBalancer` to `true` in the @@ -200,29 +204,47 @@ manifest, the operator configmap's settings `enable_master_load_balancer` and `enable_replica_load_balancer` apply. Note that the operator settings affect all Postgresql services running in all namespaces watched by the operator. -To limit the range of IP adresses that can reach a load balancer, specify desired ranges in the `allowedSourceRanges` field (applies to both master and replica LBs). To prevent exposing LBs to the entire Internet, this field is set at cluster creation time to `127.0.0.1/32` unless overwritten explicitly. If you want to revoke all IP ranges from an existing cluster, please set the `allowedSourceRanges` field to `127.0.0.1/32` or to the empty sequence `[]`. Setting the field to `null` or omitting entirely may lead to k8s removing this field from the manifest due to [the k8s handling of null fields](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes). Then the resultant manifest will not have the necessary change, and the operator will respectively do noting with the existing source ranges. +To limit the range of IP adresses that can reach a load balancer, specify the +desired ranges in the `allowedSourceRanges` field (applies to both master and +replica load balancers). To prevent exposing load balancers to the entire +Internet, this field is set at cluster creation time to `127.0.0.1/32` unless +overwritten explicitly. If you want to revoke all IP ranges from an existing +cluster, please set the `allowedSourceRanges` field to `127.0.0.1/32` or to an +empty sequence `[]`. Setting the field to `null` or omitting it entirely may +lead to Kubernetes removing this field from the manifest due to its +[handling of null fields](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes). +Then the resultant manifest will not contain the necessary change, and the +operator will respectively do noting with the existing source ranges. ## Running periodic 'autorepair' scans of Kubernetes objects The Postgres operator periodically scans all Kubernetes objects belonging to each cluster and repairs all discrepancies between them and the definitions -generated from the current cluster manifest. There are two types of scans: a -`sync scan`, running every `resync_period` seconds for every cluster, and the -`repair scan`, coming every `repair_period` only for those clusters that didn't -report success as a result of the last operation applied to them. +generated from the current cluster manifest. There are two types of scans: + +* `sync scan`, running every `resync_period` seconds for every cluster + +* `repair scan`, coming every `repair_period` only for those clusters that didn't +report success as a result of the last operation applied to them. ## Postgres roles supported by the operator -The operator is capable of maintaining roles of multiple kinds within a Postgres database cluster: +The operator is capable of maintaining roles of multiple kinds within a +Postgres database cluster: -1. **System roles** are roles necessary for the proper work of Postgres itself such as a replication role or the initial superuser role. The operator delegates creating such roles to Patroni and only establishes relevant secrets. +* **System roles** are roles necessary for the proper work of Postgres itself such as a replication role or the initial superuser role. The operator delegates creating such roles to Patroni and only establishes relevant secrets. -2. **Infrastructure roles** are roles for processes originating from external systems, e.g. monitoring robots. The operator creates such roles in all PG clusters it manages assuming k8s secrets with the relevant credentials exist beforehand. +* **Infrastructure roles** are roles for processes originating from external systems, e.g. monitoring robots. The operator creates such roles in all Postgres clusters it manages assuming that Kubernetes secrets with the relevant credentials exist beforehand. -3. **Per-cluster robot users** are also roles for processes originating from external systems but defined for an individual Postgres cluster in its manifest. A typical example is a role for connections from an application that uses the database. +* **Per-cluster robot users** are also roles for processes originating from external systems but defined for an individual Postgres cluster in its manifest. A typical example is a role for connections from an application that uses the database. -4. **Human users** originate from the Teams API that returns list of the team members given a team id. Operator differentiates between (a) product teams that own a particular Postgres cluster and are granted admin rights to maintain it, and (b) Postgres superuser teams that get the superuser access to all PG databases running in a k8s cluster for the purposes of maintaining and troubleshooting. +* **Human users** originate from the Teams API that returns a list of the team members given a team id. The operator differentiates between (a) product teams that own a particular Postgres cluster and are granted admin rights to maintain it, and (b) Postgres superuser teams that get the superuser access to all Postgres databases running in a Kubernetes cluster for the purposes of maintaining and troubleshooting. ## Understanding rolling update of Spilo pods -The operator logs reasons for a rolling update with the `info` level and a diff between the old and new StatefulSet specs with the `debug` level. To benefit from numerous escape characters in the latter log entry, view it in CLI with `echo -e`. Note that the resultant message will contain some noise because the `PodTemplate` used by the operator is yet to be updated with the default values used internally in Kubernetes. +The operator logs reasons for a rolling update with the `info` level and +a diff between the old and new StatefulSet specs with the `debug` level. +To read the latter log entry with the escaped characters rendered, view it +in CLI with `echo -e`. Note that the resultant message will contain some +noise because the `PodTemplate` used by the operator is yet to be updated +with the default values used internally in Kubernetes. From 1109c861fb82ae90f4f58b152d46552b2b22a285 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Fri, 18 Jan 2019 12:36:44 +0000 Subject: [PATCH 19/33] Report new Postgres CR error when previously incorrect one is being updated (#449) --- pkg/controller/postgresql.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/controller/postgresql.go b/pkg/controller/postgresql.go index e67b47193..e551930bd 100644 --- a/pkg/controller/postgresql.go +++ b/pkg/controller/postgresql.go @@ -385,8 +385,14 @@ func (c *Controller) queueClusterEvent(informerOldSpec, informerNewSpec *acidv1. if informerOldSpec != nil { //update, delete uid = informerOldSpec.GetUID() clusterName = util.NameFromMeta(informerOldSpec.ObjectMeta) + + // user is fixing previously incorrect spec if eventType == EventUpdate && informerNewSpec.Error == "" && informerOldSpec.Error != "" { eventType = EventSync + } + + // set current error to be one of the new spec if present + if informerNewSpec != nil { clusterError = informerNewSpec.Error } else { clusterError = informerOldSpec.Error From 8330905ce7dbafcdcc4376dc15d52b85f6326dcb Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Fri, 18 Jan 2019 12:38:47 +0000 Subject: [PATCH 20/33] Don't panic if Service for the role was not found (#451) --- pkg/cluster/resources.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/cluster/resources.go b/pkg/cluster/resources.go index 10e4201cb..886a4bac9 100644 --- a/pkg/cluster/resources.go +++ b/pkg/cluster/resources.go @@ -437,7 +437,11 @@ func (c *Cluster) updateService(role PostgresRole, newService *v1.Service) error func (c *Cluster) deleteService(role PostgresRole) error { c.logger.Debugf("deleting service %s", role) - service := c.Services[role] + service, ok := c.Services[role] + if !ok { + c.logger.Debugf("No service for %s role was found, nothing to delete", role) + return nil + } if err := c.KubeClient.Services(service.Namespace).Delete(service.Name, c.deleteOptions); err != nil { return err From 9c7558816cdb0bfdbf65a52b624f23ae834a6c48 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Fri, 18 Jan 2019 15:00:48 +0100 Subject: [PATCH 21/33] Update CODEOWNERS (#458) add new team member --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 42b83593a..98d9cd7bb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,2 @@ # global owners -* @alexeyklyukin @erthalion @sdudoladov @Jan-M @CyberDem0n @avaczi +* @alexeyklyukin @erthalion @sdudoladov @Jan-M @CyberDem0n @avaczi @FxKu From 6f6a599c9038885b1598272e983ff20de665c0f4 Mon Sep 17 00:00:00 2001 From: Armin Nesiren Date: Fri, 25 Jan 2019 11:35:27 +0100 Subject: [PATCH 22/33] Added possibility to add custom annotations to LoadBalancer service. (#461) * Added possibility to add custom annotations to LoadBalancer service. --- docs/reference/operator_parameters.md | 5 +++++ manifests/configmap.yaml | 2 ++ manifests/postgresql-operator-default-configuration.yaml | 3 +++ pkg/apis/acid.zalan.do/v1/operator_configuration_type.go | 1 + pkg/cluster/k8sres.go | 7 +++++++ pkg/controller/operator_config.go | 1 + pkg/util/config/config.go | 1 + run_operator_locally.sh | 6 +++--- 8 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 81920b342..39320fa76 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -294,6 +294,11 @@ In the CRD-based configuration they are grouped under the `load_balancer` key. cluster. Can be overridden by individual cluster settings. The default is `false`. +* **custom_service_annotations** + when load balancing is enabled, LoadBalancer service is created and + this parameter takes service annotations that are applied to service. + Optional. + * **master_dns_name_format** defines the DNS name string template for the master load balancer cluster. The default is `{cluster}.{team}.{hostedzone}`, where `{cluster}` is replaced by the cluster diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index 30fbbb63d..37b174755 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -15,6 +15,8 @@ data: secret_name_template: '{username}.{cluster}.credentials' super_username: postgres enable_teams_api: "false" + # custom_service_annotations: + # "keyx:valuez,keya:valuea" # set_memory_request_to_limit: "true" # postgres_superuser_teams: "postgres_superusers" # enable_team_superuser: "false" diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index 6d3c819b7..cba8ea38e 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -46,6 +46,9 @@ configuration: load_balancer: enable_master_load_balancer: false enable_replica_load_balancer: false + # custom_service_annotations: + # keyx: valuex + # keyy: valuey master_dns_name_format: "{cluster}.{team}.{hostedzone}" replica_dns_name_format: "{cluster}-repl.{team}.{hostedzone}" aws_or_gcp: 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 f2759f5ad..f5aac03b6 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -84,6 +84,7 @@ type LoadBalancerConfiguration struct { DbHostedZone string `json:"db_hosted_zone,omitempty"` EnableMasterLoadBalancer bool `json:"enable_master_load_balancer,omitempty"` EnableReplicaLoadBalancer bool `json:"enable_replica_load_balancer,omitempty"` + CustomServiceAnnotations map[string]string `json:"custom_service_annotations,omitempty"` MasterDNSNameFormat config.StringTemplate `json:"master_dns_name_format,omitempty"` ReplicaDNSNameFormat config.StringTemplate `json:"replica_dns_name_format,omitempty"` } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index fec795ad0..681795d2f 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -1093,6 +1093,13 @@ func (c *Cluster) generateService(role PostgresRole, spec *acidv1.PostgresSpec) constants.ZalandoDNSNameAnnotation: dnsName, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, } + + if len(c.OpConfig.CustomServiceAnnotations) != 0 { + c.logger.Debugf("There are custom annotations defined, creating them.") + for customAnnotationKey, customAnnotationValue := range c.OpConfig.CustomServiceAnnotations { + annotations[customAnnotationKey] = customAnnotationValue + } + } } else if role == Replica { // before PR #258, the replica service was only created if allocated a LB // now we always create the service but warn if the LB is absent diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 006cfd2d1..dae651b1d 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -67,6 +67,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.DbHostedZone = fromCRD.LoadBalancer.DbHostedZone result.EnableMasterLoadBalancer = fromCRD.LoadBalancer.EnableMasterLoadBalancer result.EnableReplicaLoadBalancer = fromCRD.LoadBalancer.EnableReplicaLoadBalancer + result.CustomServiceAnnotations = fromCRD.LoadBalancer.CustomServiceAnnotations result.MasterDNSNameFormat = fromCRD.LoadBalancer.MasterDNSNameFormat result.ReplicaDNSNameFormat = fromCRD.LoadBalancer.ReplicaDNSNameFormat diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 124935a03..31cda4b98 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -93,6 +93,7 @@ type Config struct { EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"` EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"` EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` + CustomServiceAnnotations map[string]string `name:"custom_service_annotations"` // deprecated and kept for backward compatibility EnableLoadBalancer *bool `name:"enable_load_balancer"` MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{team}.{hostedzone}"` diff --git a/run_operator_locally.sh b/run_operator_locally.sh index d6c416d56..8601f4fbc 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -56,7 +56,7 @@ function clean_up(){ fi if [[ -e "$PATH_TO_LOCAL_OPERATOR_MANIFEST" ]]; then - rm --verbose "$PATH_TO_LOCAL_OPERATOR_MANIFEST" + rm -v "$PATH_TO_LOCAL_OPERATOR_MANIFEST" fi # the kubectl process does the port-forwarding between operator and local ports @@ -70,7 +70,7 @@ function clean_up(){ if kill "$pid" > /dev/null 2>&1; then echo "Kill the kubectl process responsible for port forwarding for minikube so that we can re-use the same ports for forwarding later..." fi - rm --verbose "$PATH_TO_PORT_FORWARED_KUBECTL_PID" + rm -v "$PATH_TO_PORT_FORWARED_KUBECTL_PID" fi } @@ -121,7 +121,7 @@ function deploy_self_built_image() { # update the tag in the postgres operator conf # since the image with this tag already exists on the machine, # docker should not attempt to fetch it from the registry due to imagePullPolicy - sed --expression "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" + sed -e "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" retry "kubectl create -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" } From 3544cc90faeca5b425bdb447e65d669165301cfe Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Tue, 29 Jan 2019 10:08:44 +0000 Subject: [PATCH 23/33] Allow specifying init_containers in Postgres CRD (#445) * Add support for init_containers --- docs/user.md | 26 +++++++++++++++++++ manifests/complete-postgres-manifest.yaml | 4 +++ pkg/apis/acid.zalan.do/v1/postgresql_type.go | 1 + .../acid.zalan.do/v1/zz_generated.deepcopy.go | 14 +++++++++- pkg/cluster/k8sres.go | 3 +++ .../clientset/versioned/clientset.go | 2 +- pkg/generated/clientset/versioned/doc.go | 2 +- .../versioned/fake/clientset_generated.go | 2 +- pkg/generated/clientset/versioned/fake/doc.go | 2 +- .../clientset/versioned/fake/register.go | 2 +- .../clientset/versioned/scheme/doc.go | 2 +- .../clientset/versioned/scheme/register.go | 2 +- .../acid.zalan.do/v1/acid.zalan.do_client.go | 2 +- .../versioned/typed/acid.zalan.do/v1/doc.go | 2 +- .../typed/acid.zalan.do/v1/fake/doc.go | 2 +- .../v1/fake/fake_acid.zalan.do_client.go | 2 +- .../v1/fake/fake_operatorconfiguration.go | 2 +- .../acid.zalan.do/v1/fake/fake_postgresql.go | 2 +- .../acid.zalan.do/v1/generated_expansion.go | 2 +- .../acid.zalan.do/v1/operatorconfiguration.go | 2 +- .../typed/acid.zalan.do/v1/postgresql.go | 2 +- .../acid.zalan.do/interface.go | 2 +- .../acid.zalan.do/v1/interface.go | 2 +- .../acid.zalan.do/v1/postgresql.go | 2 +- .../informers/externalversions/factory.go | 2 +- .../informers/externalversions/generic.go | 2 +- .../internalinterfaces/factory_interfaces.go | 2 +- .../acid.zalan.do/v1/expansion_generated.go | 2 +- .../listers/acid.zalan.do/v1/postgresql.go | 2 +- 29 files changed, 71 insertions(+), 25 deletions(-) diff --git a/docs/user.md b/docs/user.md index 8c93449c3..ba91530eb 100644 --- a/docs/user.md +++ b/docs/user.md @@ -273,6 +273,32 @@ are always passed to sidecars: The PostgreSQL volume is shared with sidecars and is mounted at `/home/postgres/pgdata`. + +## InitContainers Support + +Each cluster can specify arbitrary init containers to run. These containers can be +used to run custom actions before any normal and sidecar containers start. +An init container can be specified like this: + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: postgresql + +metadata: + name: acid-minimal-cluster +spec: + ... + init_containers: + - name: "container-name" + image: "company/image:tag" + env: + - name: "ENV_VAR_NAME" + value: "any-k8s-env-things" +``` + +`init_containers` accepts full `v1.Container` definition. + + ## Increase volume size PostgreSQL operator supports statefulset volume resize if you're using the diff --git a/manifests/complete-postgres-manifest.yaml b/manifests/complete-postgres-manifest.yaml index c5f80f373..4a4c6078a 100644 --- a/manifests/complete-postgres-manifest.yaml +++ b/manifests/complete-postgres-manifest.yaml @@ -4,6 +4,10 @@ kind: postgresql metadata: name: acid-test-cluster spec: + init_containers: + - name: date + image: busybox + command: [ "/bin/date" ] teamId: "ACID" volume: size: 1Gi diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 4315faeca..ccd7fe08c 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -51,6 +51,7 @@ type PostgresSpec struct { Databases map[string]string `json:"databases,omitempty"` Tolerations []v1.Toleration `json:"tolerations,omitempty"` Sidecars []Sidecar `json:"sidecars,omitempty"` + InitContainers []v1.Container `json:"init_containers,omitempty"` PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` ShmVolume *bool `json:"enableShmVolume,omitempty"` } diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index 55a5ac075..66cef6e6d 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -442,6 +442,18 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.InitContainers != nil { + in, out := &in.InitContainers, &out.InitContainers + *out = make([]corev1.Container, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ShmVolume != nil { + in, out := &in.ShmVolume, &out.ShmVolume + *out = new(bool) + **out = **in + } return } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 681795d2f..cbc5f8bd7 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -410,6 +410,7 @@ func generatePodTemplate( namespace string, labels labels.Set, spiloContainer *v1.Container, + initContainers []v1.Container, sidecarContainers []v1.Container, tolerationsSpec *[]v1.Toleration, nodeAffinity *v1.Affinity, @@ -428,6 +429,7 @@ func generatePodTemplate( ServiceAccountName: podServiceAccountName, TerminationGracePeriodSeconds: &terminateGracePeriodSeconds, Containers: containers, + InitContainers: initContainers, Tolerations: *tolerationsSpec, } @@ -803,6 +805,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State c.Namespace, c.labelsSet(true), spiloContainer, + spec.InitContainers, sidecarContainers, &tolerationSpec, nodeAffinity(c.OpConfig.NodeReadinessLabel), diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index d42fa3b21..4bddb3eed 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/doc.go b/pkg/generated/clientset/versioned/doc.go index 4ef8c1bb8..d514b90a4 100644 --- a/pkg/generated/clientset/versioned/doc.go +++ b/pkg/generated/clientset/versioned/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go index 19d9ab805..defa99ce7 100644 --- a/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/fake/doc.go b/pkg/generated/clientset/versioned/fake/doc.go index c249c43fa..960df4951 100644 --- a/pkg/generated/clientset/versioned/fake/doc.go +++ b/pkg/generated/clientset/versioned/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go index 5269b757a..a2c11fe33 100644 --- a/pkg/generated/clientset/versioned/fake/register.go +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/scheme/doc.go b/pkg/generated/clientset/versioned/scheme/doc.go index d17209947..ea0df2783 100644 --- a/pkg/generated/clientset/versioned/scheme/doc.go +++ b/pkg/generated/clientset/versioned/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go index 346cd4b16..8d1fea84f 100644 --- a/pkg/generated/clientset/versioned/scheme/register.go +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/acid.zalan.do_client.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/acid.zalan.do_client.go index 4e73a425f..23623ad26 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/acid.zalan.do_client.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/acid.zalan.do_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/doc.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/doc.go index 97d91a36a..8bff3bf2d 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/doc.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/doc.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/doc.go index 58640649f..c9373b6d8 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/doc.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_acid.zalan.do_client.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_acid.zalan.do_client.go index 9d401ef7c..310e1435e 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_acid.zalan.do_client.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_acid.zalan.do_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_operatorconfiguration.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_operatorconfiguration.go index b2fada626..f3587f267 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_operatorconfiguration.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_operatorconfiguration.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_postgresql.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_postgresql.go index 6feb72eb8..6cc46d47c 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_postgresql.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_postgresql.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/generated_expansion.go index 775a4b21f..e1d824486 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/operatorconfiguration.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/operatorconfiguration.go index 2541f0e3f..873ecf0b4 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/operatorconfiguration.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/operatorconfiguration.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/postgresql.go b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/postgresql.go index df1045ee3..4a7acac79 100644 --- a/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/postgresql.go +++ b/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/postgresql.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/acid.zalan.do/interface.go b/pkg/generated/informers/externalversions/acid.zalan.do/interface.go index 9dfa60021..4407c1cde 100644 --- a/pkg/generated/informers/externalversions/acid.zalan.do/interface.go +++ b/pkg/generated/informers/externalversions/acid.zalan.do/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/acid.zalan.do/v1/interface.go b/pkg/generated/informers/externalversions/acid.zalan.do/v1/interface.go index f0f35b65c..e519b9716 100644 --- a/pkg/generated/informers/externalversions/acid.zalan.do/v1/interface.go +++ b/pkg/generated/informers/externalversions/acid.zalan.do/v1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/acid.zalan.do/v1/postgresql.go b/pkg/generated/informers/externalversions/acid.zalan.do/v1/postgresql.go index 50f3126cf..f44fccbc2 100644 --- a/pkg/generated/informers/externalversions/acid.zalan.do/v1/postgresql.go +++ b/pkg/generated/informers/externalversions/acid.zalan.do/v1/postgresql.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/factory.go b/pkg/generated/informers/externalversions/factory.go index 395bc25b5..30dd7b8d0 100644 --- a/pkg/generated/informers/externalversions/factory.go +++ b/pkg/generated/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index 1b1988212..3ee0f89b6 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go index f3b4ab9fa..37857d2bc 100644 --- a/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/listers/acid.zalan.do/v1/expansion_generated.go b/pkg/generated/listers/acid.zalan.do/v1/expansion_generated.go index 071a413d6..4c353bec3 100644 --- a/pkg/generated/listers/acid.zalan.do/v1/expansion_generated.go +++ b/pkg/generated/listers/acid.zalan.do/v1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/generated/listers/acid.zalan.do/v1/postgresql.go b/pkg/generated/listers/acid.zalan.do/v1/postgresql.go index c8603bc79..a9028987b 100644 --- a/pkg/generated/listers/acid.zalan.do/v1/postgresql.go +++ b/pkg/generated/listers/acid.zalan.do/v1/postgresql.go @@ -1,5 +1,5 @@ /* -Copyright 2018 Compose, Zalando SE +Copyright 2019 Compose, Zalando SE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 43e82887510c213878afe85e26d5293cf60e0f1a Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 29 Jan 2019 11:10:14 +0100 Subject: [PATCH 24/33] Fix run operator locally (#462) * make test namespace optional * Update spilo/operator images * Add a command to replace operator image w/o minikube restart --- manifests/configmap.yaml | 2 +- manifests/minimal-postgres-manifest.yaml | 2 +- manifests/postgres-operator.yaml | 2 +- run_operator_locally.sh | 62 +++++++++++++++++++----- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index 37b174755..19eb3f5de 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -10,7 +10,7 @@ data: debug_logging: "true" workers: "4" - docker_image: registry.opensource.zalan.do/acid/spilo-cdp-11:1.5-p42 + docker_image: registry.opensource.zalan.do/acid/spilo-11:1.5-p4 pod_service_account_name: "zalando-postgres-operator" secret_name_template: '{username}.{cluster}.credentials' super_username: postgres diff --git a/manifests/minimal-postgres-manifest.yaml b/manifests/minimal-postgres-manifest.yaml index 402946b09..37d772567 100644 --- a/manifests/minimal-postgres-manifest.yaml +++ b/manifests/minimal-postgres-manifest.yaml @@ -2,7 +2,7 @@ apiVersion: "acid.zalan.do/v1" kind: postgresql metadata: name: acid-minimal-cluster - namespace: test # assumes namespace exists beforehand + namespace: default spec: teamId: "ACID" volume: diff --git a/manifests/postgres-operator.yaml b/manifests/postgres-operator.yaml index fffb8ede8..d43c0f8a8 100644 --- a/manifests/postgres-operator.yaml +++ b/manifests/postgres-operator.yaml @@ -12,7 +12,7 @@ spec: serviceAccountName: zalando-postgres-operator containers: - name: postgres-operator - image: registry.opensource.zalan.do/acid/smoke-tested-postgres-operator:v1.0.0-21-ge39915c + image: registry.opensource.zalan.do/acid/smoke-tested-postgres-operator:v1.0.0-37-g2422d72 imagePullPolicy: IfNotPresent resources: requests: diff --git a/run_operator_locally.sh b/run_operator_locally.sh index 8601f4fbc..2594097b2 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -3,6 +3,11 @@ # Deploy a Postgres operator to a minikube aka local Kubernetes cluster # Optionally re-build the operator binary beforehand to test local changes +# Known limitations: +# 1) minikube provides a single node k8s cluster. That is, you will not be able test functions like pod +# migration between multiple nodes locally +# 2) this script configures the operator via configmap, not the operator CRD + # enable unofficial bash strict mode set -o errexit @@ -13,6 +18,7 @@ IFS=$'\n\t' readonly PATH_TO_LOCAL_OPERATOR_MANIFEST="/tmp/local-postgres-operator-manifest.yaml" readonly PATH_TO_PORT_FORWARED_KUBECTL_PID="/tmp/kubectl-port-forward.pid" +readonly PATH_TO_THE_PG_CLUSTER_MANIFEST="/tmp/minimal-postgres-manifest.yaml" readonly LOCAL_PORT="8080" readonly OPERATOR_PORT="8080" @@ -37,18 +43,16 @@ function retry(){ return 1 } - function display_help(){ - echo "Usage: $0 [ -r | --rebuild-operator ] [ -h | --help ]" + echo "Usage: $0 [ -r | --rebuild-operator ] [ -h | --help ] [ -n | --deploy-new-operator-image ] [ -t | --deploy-pg-to-namespace-test ]" } - function clean_up(){ echo "==== CLEAN UP PREVIOUS RUN ==== " local status - status=$(minikube status --format "{{.MinikubeStatus}}" || true) + status=$(minikube status --format "{{.Host}}" || true) if [[ "$status" = "Running" ]] || [[ "$status" = "Stopped" ]]; then echo "Delete the existing local cluster so that we can cleanly apply resources from scratch..." @@ -123,7 +127,7 @@ function deploy_self_built_image() { # docker should not attempt to fetch it from the registry due to imagePullPolicy sed -e "s/\(image\:.*\:\).*$/\1$TAG/; s/smoke-tested-//" manifests/postgres-operator.yaml > "$PATH_TO_LOCAL_OPERATOR_MANIFEST" - retry "kubectl create -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" + retry "kubectl apply -f \"$PATH_TO_LOCAL_OPERATOR_MANIFEST\"" "attempt to create $PATH_TO_LOCAL_OPERATOR_MANIFEST resource" } @@ -139,17 +143,18 @@ function start_operator(){ retry "kubectl create -f manifests/\"$file\"" "attempt to create $file resource" done + cp manifests/postgres-operator.yaml $PATH_TO_LOCAL_OPERATOR_MANIFEST + if [[ "$should_build_custom_operator" = true ]]; then # set in main() deploy_self_built_image else - retry "kubectl create -f manifests/postgres-operator.yaml" "attempt to create /postgres-operator.yaml resource" + retry "kubectl create -f ${PATH_TO_LOCAL_OPERATOR_MANIFEST}" "attempt to create ${PATH_TO_LOCAL_OPERATOR_MANIFEST} resource" fi local -r msg="Wait for the postgresql custom resource definition to register..." local -r cmd="kubectl get crd | grep --quiet 'postgresqls.acid.zalan.do'" retry "$cmd" "$msg " - kubectl create -f manifests/minimal-postgres-manifest.yaml } @@ -186,16 +191,38 @@ function check_health(){ } +function submit_postgresql_manifest(){ + + echo "==== SUBMIT MINIMAL POSTGRES MANIFEST ==== " + + local namespace="default" + cp manifests/minimal-postgres-manifest.yaml $PATH_TO_THE_PG_CLUSTER_MANIFEST + + if $should_deploy_pg_to_namespace_test; then + kubectl create namespace test + namespace="test" + sed --in-place 's/namespace: default/namespace: test/' $PATH_TO_THE_PG_CLUSTER_MANIFEST + fi + + kubectl create -f $PATH_TO_THE_PG_CLUSTER_MANIFEST + echo "The operator will create the PG cluster with minimal manifest $PATH_TO_THE_PG_CLUSTER_MANIFEST in the ${namespace} namespace" + +} + + function main(){ if ! [[ $(basename "$PWD") == "postgres-operator" ]]; then - echo "Please execute the script only from the root directory of the Postgres opepator repo." + echo "Please execute the script only from the root directory of the Postgres operator repo." exit 1 fi trap "echo 'If you observe issues with minikube VM not starting/not proceeding, consider deleting the .minikube dir and/or rebooting before re-running the script'" EXIT - local should_build_custom_operator=false # used in start_operator() + local should_build_custom_operator=false + local should_deploy_pg_to_namespace_test=false + local should_replace_operator_image=false + while true do # if the 1st param is unset, use the empty string as a default value @@ -204,19 +231,32 @@ function main(){ display_help exit 0 ;; - -r | --rebuild-operator) + -r | --rebuild-operator) # with minikube restart should_build_custom_operator=true break ;; + -n | --deploy-new-operator-image) # without minikube restart that takes minutes + should_replace_operator_image=true + break + ;; + -t | --deploy-pg-to-namespace-test) # to test multi-namespace support locally + should_deploy_pg_to_namespace_test=true + break + ;; *) break ;; esac done + if ${should_replace_operator_image}; then + deploy_self_built_image + exit 0 + fi + clean_up start_minikube - kubectl create namespace test start_operator + submit_postgresql_manifest forward_ports check_health From 44895939f33fbba21054bd500c34ec4980095dcd Mon Sep 17 00:00:00 2001 From: Dmitry Dolgov <9erthalion6@gmail.com> Date: Tue, 29 Jan 2019 21:42:13 +0100 Subject: [PATCH 25/33] Overview diagrams (#466) Add overview diagram of what would be created for a postgres cluster by operator --- README.md | 5 +++++ docs/diagrams/operator.png | Bin 0 -> 259075 bytes 2 files changed, 5 insertions(+) create mode 100644 docs/diagrams/operator.png diff --git a/README.md b/README.md index d96458eec..403d63e7f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,11 @@ manages PostgreSQL clusters on Kubernetes: 3. Finally, the operator periodically synchronizes the actual state of each Postgres cluster with the desired state defined in the cluster's manifest. +Here is a diagram, that summarizes what would be created by the operator, when a +new Postgres cluster CRD was submitted: + +![postgresql-operator](docs/diagrams/operator.png "K8S resources, created by operator") + There is a browser-friendly version of this documentation at [postgres-operator.readthedocs.io](https://postgres-operator.readthedocs.io) diff --git a/docs/diagrams/operator.png b/docs/diagrams/operator.png new file mode 100644 index 0000000000000000000000000000000000000000..af51bbf08102a6e304fa2340e47c561b80ec97ba GIT binary patch literal 259075 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 z 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
O$IA!372ifz{>*qY&3B_gRN@t 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%0AQL7MaVk`%B4_A zhrMf_DD-P0SOJCO&Z;)JX3MI2aM_ITH6#J)vsH8-g2rR`?_GWBF@)sYS=T66XkYMv^V7Zv zz&Ix;LRZI`?s>IiJ4J^9?P^=*`balyG|*U{a<>R)KaxDGk3(Gn*q&eC7gz9%+OwwW zJXnE#&l#QL-J$*B;N0kFh4c6G>qL&kXok=-%Jm#`2&nzVn{`P_Yt*{WW$H55_I^g= ziLq?v`b_h#=&wQ;2MZJLV53K1cUQa`6vwAI-!!Rgm~fXxNtE?X4_ zWJm0i1`+*`Mt@D-^5Sa`p-6

7UEPXj8($vv4)0*|N$M28(N>N-jKP9X=!jwKTzt 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 Date: Thu, 31 Jan 2019 12:16:05 +0100 Subject: [PATCH 26/33] + video of Oleksii's talk (#473) https://twitter.com/PostgreSQL/status/1087681292416630785 --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index e038f713e..f17dbf11b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Please, report any issues discovered to https://github.com/zalando-incubator/pos ## Talks -1. "PostgreSQL and Kubernetes: DBaaS without a vendor-lock" talk by Oleksii Kliukin, PostgreSQL Sessions 2018: [slides](https://speakerdeck.com/alexeyklyukin/postgresql-and-kubernetes-dbaas-without-a-vendor-lock) +1. "PostgreSQL and Kubernetes: DBaaS without a vendor-lock" talk by Oleksii Kliukin, PostgreSQL Sessions 2018: [video](https://www.youtube.com/watch?v=q26U2rQcqMw) | [slides](https://speakerdeck.com/alexeyklyukin/postgresql-and-kubernetes-dbaas-without-a-vendor-lock) 2. "PostgreSQL High Availability on Kubernetes with Patroni" talk by Oleksii Kliukin, Atmosphere 2018: [video](https://www.youtube.com/watch?v=cFlwQOPPkeg) | [slides](https://speakerdeck.com/alexeyklyukin/postgresql-high-availability-on-kubernetes-with-patroni) From 90c25038d73b7a5d647f5cb49799a0bd3f8d1bd6 Mon Sep 17 00:00:00 2001 From: Dmitry Dolgov <9erthalion6@gmail.com> Date: Thu, 31 Jan 2019 12:17:11 +0100 Subject: [PATCH 27/33] Add pod diagram and tex sources (#472) --- .gitignore | 4 ++ README.md | 12 ++++- docs/diagrams/Makefile | 11 ++++ docs/diagrams/operator.png | Bin 259075 -> 259075 bytes docs/diagrams/operator.tex | 101 +++++++++++++++++++++++++++++++++++++ docs/diagrams/pod.png | Bin 0 -> 241573 bytes docs/diagrams/pod.tex | 92 +++++++++++++++++++++++++++++++++ 7 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 docs/diagrams/Makefile create mode 100644 docs/diagrams/operator.tex create mode 100644 docs/diagrams/pod.png create mode 100644 docs/diagrams/pod.tex diff --git a/.gitignore b/.gitignore index ad08aa383..e09b6644b 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ _testmain.go .idea scm-source.json + +# diagrams +*.aux +*.log diff --git a/README.md b/README.md index 403d63e7f..9ea029183 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,16 @@ new Postgres cluster CRD was submitted: ![postgresql-operator](docs/diagrams/operator.png "K8S resources, created by operator") -There is a browser-friendly version of this documentation at -[postgres-operator.readthedocs.io](https://postgres-operator.readthedocs.io) +This picture is not complete without an overview of what is inside a pod, so +let's zoom in: + +![pod](docs/diagrams/pod.png "Database pod components") + +These two diagrams should help you to understand the basics of what kind of +functionality the operator provides. Below we discuss all everything in more +details. + +There is a browser-friendly version of this documentation at [postgres-operator.readthedocs.io](https://postgres-operator.readthedocs.io) ## Table of contents diff --git a/docs/diagrams/Makefile b/docs/diagrams/Makefile new file mode 100644 index 000000000..0c0c7c918 --- /dev/null +++ b/docs/diagrams/Makefile @@ -0,0 +1,11 @@ +OBJ=$(patsubst %.tex, %.png, $(wildcard *.tex)) + +.PHONY: all + +all: $(OBJ) + +%.pdf: %.tex + lualatex $< -shell-escape $@ + +%.png: %.pdf + convert -flatten -density 300 $< -quality 90 $@ diff --git a/docs/diagrams/operator.png b/docs/diagrams/operator.png index af51bbf08102a6e304fa2340e47c561b80ec97ba..5e1cbfe8379966e9494aa9180c1989fc0dfc75d3 100644 GIT binary patch delta 106 zcmZpE!QcFXe?mWpoRA9t`f$gcjniAFGqz4=+B%*2*C#h)gAhY=D`PV&LsM-7Ln{LV wrX%&w85kH;OI#yLQW8s2t#b2IGSeyhEUXKbC$v~@c3uTO49mLY~FRtDx)hQ`_khE@g! wAC%v1WME)WEpd$~Nl7e8waU#;$xN$cFfuT-)HN{F#n8}L7sfmN`e$Yx0QNK^EC2ui diff --git a/docs/diagrams/operator.tex b/docs/diagrams/operator.tex new file mode 100644 index 000000000..a8ee0a05f --- /dev/null +++ b/docs/diagrams/operator.tex @@ -0,0 +1,101 @@ +\documentclass{article} +\usepackage{tikz} +\usepackage[graphics,tightpage,active]{preview} +\usetikzlibrary{arrows, shadows.blur, positioning, fit, calc, backgrounds} +\usepackage{lscape} + +\pagenumbering{gobble} + +\PreviewEnvironment{tikzpicture} +\PreviewEnvironment{equation} +\PreviewEnvironment{equation*} +\newlength{\imagewidth} +\newlength{\imagescale} +\pagestyle{empty} +\thispagestyle{empty} + +\begin{document} +\begin{center} +\begin{tikzpicture}[ + scale=0.5,transform shape, + font=\sffamily, + every matrix/.style={ampersand replacement=\&,column sep=2cm,row sep=2cm}, + operator/.style={draw,solid,thick,circle,fill=red!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + component/.style={draw,solid,thick,rounded corners,fill=yellow!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + border/.style={draw,dashed,rounded corners,fill=gray!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + pod/.style={draw,solid,thick,rounded corners,fill=blue!20, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + service/.style={draw,solid,thick,rounded corners,fill=blue!20, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + endpoint/.style={draw,solid,thick,rounded corners,fill=blue!20, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + secret/.style={draw,solid,thick,rounded corners,fill=blue!20, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + pvc/.style={draw,solid,thick,rounded corners,fill=blue!20, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + label/.style={rectangle,inner sep=0,outer sep=0}, + to/.style={->,>=stealth',shorten >=1pt,semithick,font=\sffamily\footnotesize}, + every node/.style={align=center}] + + % Position the nodes using a matrix layout + + \matrix{ + \& \node[component] (crd) {CRD}; \\ + \& \node[operator] (operator) {Operator}; \\ + \path + node[service] (service-master) {Master} + node[label, right of=service-master] (service-middle) {} + node[label, below of=service-middle] (services-label) {Services} + node[service, right=.5cm of service-master] (service-replica) {Replica} + node[border, behind path, + fit=(service-master)(service-replica)(services-label) + ] (services) {}; + \& + \node[component] (sts) {Statefulset}; \& \node[component] (pdb) {Pod Disruption Budget}; \\ + \path + node[service] (master-endpoint) {Master} + node[service, right=.5cm of master-endpoint] (replica-endpoint) {Replica} + node[label, right of=master-endpoint] (endpoint-middle) {} + node[label, below of=endpoint-middle] (endpoint-label) {Endpoints} + node[border, behind path, + fit=(master-endpoint)(replica-endpoint)(endpoint-label) + ] (endpoints) {}; \& + \node[component] (pod-template) {Pod Template}; \& + \node[border] (secrets) { + \begin{tikzpicture}[] + \node[secret] (users-secret) at (0, 0) {Users}; + \node[secret] (robots-secret) at (2, 0) {Robots}; + \node[secret] (standby-secret) at (4, 0) {Standby}; + \end{tikzpicture} \\ + Secrets + }; \\ \& + \path + node[pod] (replica1-pod) {Replica} + node[pod, left=.5cm of replica1-pod] (master-pod) {Master} + node[pod, right=.5cm of replica1-pod] (replica2-pod) {Replica} + node[label, below of=replica1-pod] (pod-label) {Pods} + node[border, behind path, + fit=(master-pod)(replica1-pod)(replica2-pod)(pod-label) + ] (pods) {}; \\ \& + \path + node[pvc] (replica1-pvc) {Replica} + node[pvc, left=.5cm of replica1-pvc] (master-pvc) {Master} + node[pvc, right=.5cm of replica1-pvc] (replica2-pvc) {Replica} + node[label, below of=replica1-pvc] (pvc-label) {Persistent Volume Claims} + node[border, behind path, + fit=(master-pvc)(replica1-pvc)(replica2-pvc)(pvc-label) + ] (pvcs) {}; \& + \\ \& \\ + }; + + % Draw the arrows between the nodes and label them. + \draw[to] (crd) -- node[midway,above] {} node[midway,below] {} (operator); + \draw[to] (operator) -- node[midway,above] {} node[midway,below] {} (sts); + \draw[to] (operator) -- node[midway,above] {} node[midway,below] {} (secrets); + \draw[to] (operator) -| node[midway,above] {} node[midway,below] {} (pdb); + \draw[to] (service-master) -- node[midway,above] {} node[midway,below] {} (master-endpoint); + \draw[to] (service-replica) -- node[midway,above] {} node[midway,below] {} (replica-endpoint); + \draw[to] (master-pod) -- node[midway,above] {} node[midway,below] {} (master-pvc); + \draw[to] (replica1-pod) -- node[midway,above] {} node[midway,below] {} (replica1-pvc); + \draw[to] (replica2-pod) -- node[midway,above] {} node[midway,below] {} (replica2-pvc); + \draw[to] (operator) -| node[midway,above] {} node[midway,below] {} (services); + \draw[to] (sts) -- node[midway,above] {} node[midway,below] {} (pod-template); + \draw[to] (pod-template) -- node[midway,above] {} node[midway,below] {} (pods); +\end{tikzpicture} +\end{center} +\end{document} diff --git a/docs/diagrams/pod.png b/docs/diagrams/pod.png new file mode 100644 index 0000000000000000000000000000000000000000..f54d1a2bdd684fd3c77242ca332e6278ea35ca1e GIT binary patch literal 241573 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�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π{PJ$TGR)x1Pk@G=ETU&6w`-6&b9|Vmc^aHe*)XA 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/pod.tex b/docs/diagrams/pod.tex new file mode 100644 index 000000000..f4451399a --- /dev/null +++ b/docs/diagrams/pod.tex @@ -0,0 +1,92 @@ +\documentclass{article} +\usepackage{tikz} +\usepackage[graphics,tightpage,active]{preview} +\usetikzlibrary{arrows, shadows.blur, positioning, fit, calc, backgrounds} +\usepackage{lscape} + +\pagenumbering{gobble} + +\PreviewEnvironment{tikzpicture} +\PreviewEnvironment{equation} +\PreviewEnvironment{equation*} +\newlength{\imagewidth} +\newlength{\imagescale} +\pagestyle{empty} +\thispagestyle{empty} + +\begin{document} +\begin{center} +\begin{tikzpicture}[ + scale=0.5,transform shape, + font=\sffamily, + every matrix/.style={ampersand replacement=\&,column sep=2cm,row sep=2cm}, + pod/.style={draw,solid,thick,circle,fill=red!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + component/.style={draw,solid,thick,rounded corners,fill=yellow!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + border/.style={draw,dashed,rounded corners,fill=gray!20,inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + volume/.style={draw,solid,thick,rounded corners,fill=blue!20, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + sidecar/.style={draw,solid,thick,rounded corners,fill=blue!20, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + k8s-label/.style={draw,solid,thick,rounded corners,fill=blue!20, minimum width=1.5cm, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + affinity/.style={draw,solid,thick,rounded corners,fill=blue!20, minimum width=2cm, inner sep=.3cm, blur shadow={shadow blur steps=5,shadow blur extra rounding=1.3pt}}, + label/.style={rectangle,inner sep=0,outer sep=0}, + to/.style={->,>=stealth',shorten >=1pt,semithick,font=\sffamily\footnotesize}, + every node/.style={align=center}] + + % Position the nodes using a matrix layout + + \matrix{ + \path + node[k8s-label] (app-label) {App} + node[k8s-label, right=.25cm of app-label] (role-label) {Role} + node[k8s-label, right=.25cm of role-label] (custom-label) {Custom} + node[label, below of=role-label] (k8s-label-label) {K8S Labels} + node[border, behind path, + fit=(app-label)(role-label)(custom-label)(k8s-label-label) + ] (k8s-labels) {}; \& \& + \path + node[affinity] (affinity) {Affinity} + node[label, right=.25cm of affinity] (affinity-middle) {} + node[affinity, right=.25cm of affinity-middle] (anti-affinity) {Anti-affinity} + node[label, below of=affinity-middle] (affinity-label) {Assigning to nodes} + node[border, behind path, + fit=(affinity)(anti-affinity)(affinity-label) + ] (affinity) {}; \\ + \& \node[pod] (pod) {Pod}; \& \\ + \path + node[volume, minimum width={width("shm-volume")}] (data-volume) {Data} + node[volume, right=.25cm of data-volume, minimum width={width("shm-volume")}] (tokens-volume) {Tokens} + node[volume, right=.25cm of tokens-volume] (shm-volume) {/dev/shm} + node[label, below of=tokens-volume] (volumes-label) {Volumes} + node[border, behind path, + fit=(data-volume)(shm-volume)(tokens-volume)(volumes-label) + ] (volumes) {}; \& + \node[component] (spilo) {Spilo}; \& + \node[sidecar] (scalyr) {Scalyr}; \& \\ \& + \path + node[component] (patroni) {Patroni} + node[component, below=.25cm of patroni] (postgres) {PostgreSQL} + node[border, behind path, + fit=(postgres)(patroni) + ] (spilo-components) {}; \& + \path + node[sidecar] (custom-sidecar1) {User defined} + node[label, right=.25cm of custom-sidecar1] (sidecars-middle) {} + node[sidecar, right=.25cm of sidecars-middle] (custom-sidecar2) {User defined} + node[label, below of=sidecars-middle] (sidecars-label) {Custom sidecars} + node[border, behind path, + fit=(custom-sidecar1)(custom-sidecar2)(sidecars-label) + ] (sidecars) {}; + \\ \& \\ + }; + + % Draw the arrows between the nodes and label them. + \draw[to] (pod) to [bend left=25] (volumes); + \draw[to] (pod) to [bend left=25] (k8s-labels); + \draw[to] (pod) to [bend right=25] (affinity); + \draw[to] (pod) to [bend right=25] (scalyr); + \draw[to] (pod) to [bend right=25] (sidecars); + \draw[to] (pod) -- node[midway,above] {} node[midway,below] {} (spilo); + \draw[to] (spilo) -- node[midway,above] {} node[midway,below] {} (spilo-components); + +\end{tikzpicture} +\end{center} +\end{document} From ed6acc117804e7edea9fe2346d4bff5487227078 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Thu, 31 Jan 2019 12:09:17 +0000 Subject: [PATCH 28/33] Correctly report success in .status on Update (#469) --- pkg/cluster/cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 93a67226f..0230f0c18 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -494,7 +494,7 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error { defer func() { if updateFailed { c.setStatus(acidv1.ClusterStatusUpdateFailed) - } else if c.Status != acidv1.ClusterStatusRunning { + } else { c.setStatus(acidv1.ClusterStatusRunning) } }() From ba23de3d1753d00776e430d8ef5cdb317bad8c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Kupka?= <324064+kupson@users.noreply.github.com> Date: Mon, 4 Feb 2019 11:24:49 +0000 Subject: [PATCH 29/33] Pass PodEnvironmentConfigMap (#477) --- pkg/controller/operator_config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index dae651b1d..179a9dee7 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -39,6 +39,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.PodServiceAccountName = fromCRD.Kubernetes.PodServiceAccountName result.PodServiceAccountDefinition = fromCRD.Kubernetes.PodServiceAccountDefinition result.PodServiceAccountRoleBindingDefinition = fromCRD.Kubernetes.PodServiceAccountRoleBindingDefinition + result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap result.PodTerminateGracePeriod = time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod) result.WatchedNamespace = fromCRD.Kubernetes.WatchedNamespace result.PDBNameFormat = fromCRD.Kubernetes.PDBNameFormat From f2dddb0f2bea3951181566b30d4560b49c684d08 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 6 Feb 2019 14:40:12 +0100 Subject: [PATCH 30/33] Add GSoC 2019 project ideas (#470) * Add GSoC 2019 project ideas * Add community section * Add application steps * Add logo --- README.md | 11 +++++++ docs/diagrams/logo.png | Bin 0 -> 7772 bytes docs/gsoc-2019/ideas.md | 64 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 docs/diagrams/logo.png create mode 100644 docs/gsoc-2019/ideas.md diff --git a/README.md b/README.md index 9ea029183..432588b27 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ [![GoDoc](https://godoc.org/github.com/zalando-incubator/postgres-operator?status.svg)](https://godoc.org/github.com/zalando-incubator/postgres-operator) [![golangci](https://golangci.com/badges/github.com/zalando-incubator/postgres-operator.svg)](https://golangci.com/r/github.com/zalando-incubator/postgres-operator) + + + ## Introduction The Postgres [operator](https://coreos.com/blog/introducing-operators.html) @@ -44,6 +47,7 @@ details. There is a browser-friendly version of this documentation at [postgres-operator.readthedocs.io](https://postgres-operator.readthedocs.io) + ## Table of contents * [concepts](docs/index.md) @@ -56,6 +60,13 @@ There is a browser-friendly version of this documentation at [postgres-operator. the rest of the document is a tutorial to get you up and running with the operator on Minikube. + +## Community + +There are two places to get in touch with the community: +1. The [GitHub issue tracker](https://github.com/zalando-incubator/postgres-operator/issues) +2. The #postgres-operator slack channel under [Postgres Slack](https://postgres-slack.herokuapp.com) + ## Quickstart Prerequisites: diff --git a/docs/diagrams/logo.png b/docs/diagrams/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8b8372fa3e0860c239cf3f4094fa7f5904aba371 GIT binary patch literal 7772 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 Date: Thu, 14 Feb 2019 11:29:06 +0000 Subject: [PATCH 31/33] Add inherited_labels (#459) * add support for inherited_labels Signed-off-by: Stephane Tang * update docs with inherited_labels Signed-off-by: Stephane Tang --- docs/administrator.md | 51 +++++++++++++++++++ docs/reference/cluster_manifest.md | 18 +++++-- docs/reference/operator_parameters.md | 20 +++++--- ...gresql-operator-default-configuration.yaml | 11 ++-- .../v1/operator_configuration_type.go | 1 + pkg/cluster/k8sres.go | 8 +-- pkg/cluster/pod.go | 2 +- pkg/cluster/util.go | 17 ++++++- pkg/controller/operator_config.go | 1 + pkg/util/config/config.go | 1 + 10 files changed, 108 insertions(+), 22 deletions(-) diff --git a/docs/administrator.md b/docs/administrator.md index a69dc99cf..8abd31c55 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -146,6 +146,57 @@ data: ... ``` +### Add cluster-specific labels + +In some cases, you might want to add `labels` that are specific to a given +postgres cluster, in order to identify its child objects. +The typical use case is to add labels that identifies the `Pods` created by the +operator, in order to implement fine-controlled `NetworkPolicies`. + +**OperatorConfiguration** + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: OperatorConfiguration +metadata: + name: postgresql-operator-configuration +configuration: + kubernetes: + inherited_labels: + - application + - environment +... +``` + +**cluster manifest** + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: postgresql +metadata: + name: demo-cluster + labels: + application: my-app + environment: demo +spec: +... +``` + +**network policy** + +```yaml +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: netpol-example +spec: + podSelector: + matchLabels: + application: my-app + environment: demo +... +``` + ## Custom Pod Environment Variables It is possible to configure a ConfigMap which is used by the Postgres pods as diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index efc850aff..a7c0e9840 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -33,7 +33,15 @@ Those parameters are grouped under the `metadata` top-level key. services, secrets) for the cluster. Changing it after the cluster creation results in deploying or updating a completely separate cluster in the target namespace. Optional (if present, should match the namespace where the - manifest is applied). + manifest is applied). + +* **labels** + if labels are matching one of the `inherited_labels` [configured in the + operator parameters](operator_parameters.md#kubernetes-resources), + they will automatically be added to all the objects (StatefulSet, Service, + Endpoints, etc.) that are created by the operator. + Labels that are set here but not listed as `inherited_labels` in the operator + parameters are ignored. ## Top-level parameters @@ -89,7 +97,7 @@ Those are parameters grouped directly under the `spec` key in the manifest. examples](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) for details on tolerations and possible values of those keys. When set, this value overrides the `pod_toleration` setting from the operator. Optional. - + * **podPriorityClassName** a name of the [priority class](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass) @@ -135,7 +143,7 @@ explanation of `ttl` and `loop_wait` parameters. a map of key-value pairs describing initdb parameters. For `data-checksum`, `debug`, `no-locale`, `noclean`, `nosync` and `sync-only` parameters use `true` as the value if you want to set them. Changes to this option do not - affect the already initialized clusters. Optional. + affect the already initialized clusters. Optional. * **pg_hba** list of custom `pg_hba` lines to replace default ones. Note that the default @@ -215,7 +223,7 @@ under the `clone` top-level key and do not affect the already running cluster. different namespaces) , the operator uses UID in the S3 bucket name in order to guarantee uniqueness. Has no effect when cloning from the running clusters. Optional. - + * **timestamp** the timestamp up to which the recovery should proceed. The operator always configures non-inclusive recovery target, stopping right before the given @@ -235,7 +243,7 @@ properties of the persistent storage that stores postgres data. the name of the Kubernetes storage class to draw the persistent volume from. See [Kubernetes documentation](https://kubernetes.io/docs/concepts/storage/storage-classes/) - for the details on storage classes. Optional. + for the details on storage classes. Optional. ### Sidecar definitions diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 39320fa76..06a779c1e 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -12,12 +12,12 @@ configuration. * CRD-based configuration. The configuration is stored in a custom YAML manifest. The manifest is an instance of the custom resource definition (CRD) called - `OperatorConfiguration`. The operator registers this CRD + `OperatorConfiguration`. The operator registers this CRD during the start and uses it for configuration if the [operator deployment manifest ](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgres-operator.yaml#L21) sets the `POSTGRES_OPERATOR_CONFIGURATION_OBJECT` env variable to a non-empty value. The variable should point to the `postgresql-operator-configuration` object in the operator's namespace. The CRD-based configuration is a regular YAML - document; non-scalar keys are simply represented in the usual YAML way. + document; non-scalar keys are simply represented in the usual YAML way. There are no default values built-in in the operator, each parameter that is not supplied in the configuration receives an empty value. In order to create your own configuration just copy the [default @@ -172,6 +172,14 @@ configuration they are grouped under the `kubernetes` key. list of `name:value` pairs for additional labels assigned to the cluster objects. The default is `application:spilo`. +* **inherited_labels** + list of labels that can be inherited from the cluster manifest, and added to + each child objects (`StatefulSet`, `Pod`, `Service` and `Endpoints`) created by + the opertor. + Typical use case is to dynamically pass labels that are specific to a given + postgres cluster, in order to implement `NetworkPolicy`. + The default is empty. + * **cluster_name_label** name of the label assigned to Kubernetes objects created by the operator that indicates which cluster a given object belongs to. The default is @@ -198,13 +206,13 @@ configuration they are grouped under the `kubernetes` key. All variables from that ConfigMap are injected to the pod's environment, on conflicts they are overridden by the environment variables generated by the operator. The default is empty. - + * **pod_priority_class_name** a name of the [priority class](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass) that should be assigned to the Postgres pods. The priority class itself must be defined in advance. Default is empty (use the default priority class). - + ## Kubernetes resource requests @@ -350,7 +358,7 @@ Options to aid debugging of the operator itself. Grouped under the `debug` key. boolean parameter that toggles the functionality of the operator that require access to the postgres database, i.e. creating databases and users. The default is `true`. - + ## Automatic creation of human users in the database Options to automate creation of human users with the aid of the teams API @@ -448,4 +456,4 @@ scalyr sidecar. In the CRD-based configuration they are grouped under the Memory limit value for the Scalyr sidecar. The default is `1Gi`. -For the configmap operator configuration, the [default parameter values](https://github.com/zalando-incubator/postgres-operator/blob/master/pkg/util/config/config.go#L14) mentioned here are likely to be overwritten in your local operator installation via your local version of the operator configmap. In the case you use the operator CRD, all the CRD defaults are provided in the [operator's default configuration manifest](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml) \ No newline at end of file +For the configmap operator configuration, the [default parameter values](https://github.com/zalando-incubator/postgres-operator/blob/master/pkg/util/config/config.go#L14) mentioned here are likely to be overwritten in your local operator installation via your local version of the operator configmap. In the case you use the operator CRD, all the CRD defaults are provided in the [operator's default configuration manifest](https://github.com/zalando-incubator/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml) diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index cba8ea38e..5b9de1073 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -25,8 +25,11 @@ configuration: pod_role_label: spilo-role cluster_labels: application: spilo + # inherited_labels: + # - application + # - app cluster_name_label: cluster-name - # watched_namespace:"" + # watched_namespace:"" # node_readiness_label: "" # toleration: {} # infrastructure_roles_secret_name: "" @@ -53,7 +56,7 @@ configuration: replica_dns_name_format: "{cluster}-repl.{team}.{hostedzone}" aws_or_gcp: # db_hosted_zone: "" - # wal_s3_bucket: "" + # wal_s3_bucket: "" # log_s3_bucket: "" # kube_iam_role: "" aws_region: eu-central-1 @@ -62,13 +65,13 @@ configuration: enable_database_access: true teams_api: enable_teams_api: false - team_api_role_configuration: + team_api_role_configuration: log_statement: all enable_team_superuser: false team_admin_role: admin pam_role_name: zalandos # pam_configuration: "" - protected_role_names: + protected_role_names: - admin # teams_api_url: "" # postgres_superuser_teams: "postgres_superusers" 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 f5aac03b6..1b6939dfa 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -52,6 +52,7 @@ type KubernetesMetaConfiguration struct { InfrastructureRolesSecretName spec.NamespacedName `json:"infrastructure_roles_secret_name,omitempty"` PodRoleLabel string `json:"pod_role_label,omitempty"` ClusterLabels map[string]string `json:"cluster_labels,omitempty"` + InheritedLabels []string `json:"inherited_labels,omitempty"` ClusterNameLabel string `json:"cluster_name_label,omitempty"` NodeReadinessLabel map[string]string `json:"node_readiness_label,omitempty"` // TODO: use a proper toleration structure? diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index cbc5f8bd7..c0ae1648c 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -1073,7 +1073,7 @@ func (c *Cluster) generateService(role PostgresRole, spec *acidv1.PostgresSpec) } if role == Replica { - serviceSpec.Selector = c.roleLabelsSet(role) + serviceSpec.Selector = c.roleLabelsSet(false, role) } var annotations map[string]string @@ -1113,7 +1113,7 @@ func (c *Cluster) generateService(role PostgresRole, spec *acidv1.PostgresSpec) ObjectMeta: metav1.ObjectMeta{ Name: c.serviceName(role), Namespace: c.Namespace, - Labels: c.roleLabelsSet(role), + Labels: c.roleLabelsSet(true, role), Annotations: annotations, }, Spec: serviceSpec, @@ -1127,7 +1127,7 @@ func (c *Cluster) generateEndpoint(role PostgresRole, subsets []v1.EndpointSubse ObjectMeta: metav1.ObjectMeta{ Name: c.endpointName(role), Namespace: c.Namespace, - Labels: c.roleLabelsSet(role), + Labels: c.roleLabelsSet(true, role), }, } if len(subsets) > 0 { @@ -1191,7 +1191,7 @@ func (c *Cluster) generatePodDisruptionBudget() *policybeta1.PodDisruptionBudget Spec: policybeta1.PodDisruptionBudgetSpec{ MinAvailable: &minAvailable, Selector: &metav1.LabelSelector{ - MatchLabels: c.roleLabelsSet(Master), + MatchLabels: c.roleLabelsSet(false, Master), }, }, } diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 7fc068bf2..52b8b4e09 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -27,7 +27,7 @@ func (c *Cluster) listPods() ([]v1.Pod, error) { func (c *Cluster) getRolePods(role PostgresRole) ([]v1.Pod, error) { listOptions := metav1.ListOptions{ - LabelSelector: c.roleLabelsSet(role).String(), + LabelSelector: c.roleLabelsSet(false, role).String(), } pods, err := c.KubeClient.Pods(c.Namespace).List(listOptions) diff --git a/pkg/cluster/util.go b/pkg/cluster/util.go index f6e2ff096..74a009d2c 100644 --- a/pkg/cluster/util.go +++ b/pkg/cluster/util.go @@ -389,6 +389,19 @@ func (c *Cluster) labelsSet(shouldAddExtraLabels bool) labels.Set { if shouldAddExtraLabels { // enables filtering resources owned by a team lbls["team"] = c.Postgresql.Spec.TeamID + + // allow to inherit certain labels from the 'postgres' object + if spec, err := c.GetSpec(); err == nil { + for k, v := range spec.ObjectMeta.Labels { + for _, match := range c.OpConfig.InheritedLabels { + if k == match { + lbls[k] = v + } + } + } + } else { + c.logger.Warningf("could not get the list of InheritedLabels for cluster %q: %v", c.Name, err) + } } return labels.Set(lbls) @@ -398,8 +411,8 @@ func (c *Cluster) labelsSelector() *metav1.LabelSelector { return &metav1.LabelSelector{MatchLabels: c.labelsSet(false), MatchExpressions: nil} } -func (c *Cluster) roleLabelsSet(role PostgresRole) labels.Set { - lbls := c.labelsSet(false) +func (c *Cluster) roleLabelsSet(shouldAddExtraLabels bool, role PostgresRole) labels.Set { + lbls := c.labelsSet(shouldAddExtraLabels) lbls[c.OpConfig.PodRoleLabel] = string(role) return lbls } diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 179a9dee7..74549cbb8 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -48,6 +48,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.InfrastructureRolesSecretName = fromCRD.Kubernetes.InfrastructureRolesSecretName result.PodRoleLabel = fromCRD.Kubernetes.PodRoleLabel result.ClusterLabels = fromCRD.Kubernetes.ClusterLabels + result.InheritedLabels = fromCRD.Kubernetes.InheritedLabels result.ClusterNameLabel = fromCRD.Kubernetes.ClusterNameLabel result.NodeReadinessLabel = fromCRD.Kubernetes.NodeReadinessLabel result.PodPriorityClassName = fromCRD.Kubernetes.PodPriorityClassName diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 31cda4b98..371b7cb65 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -27,6 +27,7 @@ type Resources struct { PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"` PodPriorityClassName string `name:"pod_priority_class_name"` ClusterLabels map[string]string `name:"cluster_labels" default:"application:spilo"` + InheritedLabels []string `name:"inherited_labels" default:""` ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"` PodRoleLabel string `name:"pod_role_label" default:"spilo-role"` PodToleration map[string]string `name:"toleration" default:""` From 2e9b6533e7d5e7b42762542185612e609bc7b9f5 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 20 Feb 2019 10:19:15 +0100 Subject: [PATCH 32/33] Document taint-based eviction (#468) * Document taint-based eviction --- docs/administrator.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/administrator.md b/docs/administrator.md index 8abd31c55..be53eaf2d 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -146,6 +146,11 @@ data: ... ``` +Note that the Kubernetes version 1.13 brings [taint-based eviction](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/#taint-based-evictions) to the beta stage and enables it by default. +Postgres pods by default receive tolerations for `unreachable` and `noExecute` taints with the timeout of `5m`. +Depending on your setup, you may want to adjust these parameters to prevent master pods from being evicted by the Kubernetes runtime. +To prevent eviction completely, specify the toleration by leaving out the `tolerationSeconds` value (similar to how Kubernetes' own DaemonSets are configured) + ### Add cluster-specific labels In some cases, you might want to add `labels` that are specific to a given @@ -197,6 +202,7 @@ spec: ... ``` + ## Custom Pod Environment Variables It is possible to configure a ConfigMap which is used by the Postgres pods as From 26a7fdfa9f4b6ff1acbba59108e3c1e159cf4d44 Mon Sep 17 00:00:00 2001 From: "teuto.net Netzdienste GmbH" Date: Thu, 21 Feb 2019 16:37:03 +0100 Subject: [PATCH 33/33] Add Pod Anti Affinity (#489) * Add Pod Anti Affinity --- docs/administrator.md | 30 +++++++++++++++++++ docs/reference/operator_parameters.md | 8 +++++ .../v1/operator_configuration_type.go | 2 ++ pkg/cluster/k8sres.go | 30 +++++++++++++++++-- pkg/controller/operator_config.go | 3 ++ pkg/util/config/config.go | 2 ++ 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/docs/administrator.md b/docs/administrator.md index be53eaf2d..208e9ddb9 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -151,6 +151,36 @@ Postgres pods by default receive tolerations for `unreachable` and `noExecute` t Depending on your setup, you may want to adjust these parameters to prevent master pods from being evicted by the Kubernetes runtime. To prevent eviction completely, specify the toleration by leaving out the `tolerationSeconds` value (similar to how Kubernetes' own DaemonSets are configured) +### Enable pod anti affinity + +To ensure Postgres pods are running on different topologies, you can use [pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) +and configure the required topology in the operator ConfigMap. + +Enable pod anti affinity by adding following line to the operator ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-operator +data: + enable_pod_antiaffinity: "true" +``` + +By default the topology key for the pod anti affinity is set to `kubernetes.io/hostname`, +you can set another topology key e.g. `failure-domain.beta.kubernetes.io/zone` by adding following line +to the operator ConfigMap, see [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-operator +data: + enable_pod_antiaffinity: "true" + pod_antiaffinity_topology_key: "failure-domain.beta.kubernetes.io/zone" +``` + ### Add cluster-specific labels In some cases, you might want to add `labels` that are specific to a given diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 06a779c1e..69d903427 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -213,6 +213,14 @@ configuration they are grouped under the `kubernetes` key. that should be assigned to the Postgres pods. The priority class itself must be defined in advance. Default is empty (use the default priority class). +* **enable_pod_antiaffinity** + toggles [pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) on the Postgres pods, to avoid multiple pods + of the same Postgres cluster in the same topology , e.g. node. The default is `false`. + +* **pod_antiaffinity_topology_key** + override + [topology key](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) + for pod anti affinity. The default is `kubernetes.io/hostname`. ## Kubernetes resource requests 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 1b6939dfa..99d79b64b 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -60,6 +60,8 @@ type KubernetesMetaConfiguration struct { // TODO: use namespacedname PodEnvironmentConfigMap string `json:"pod_environment_configmap,omitempty"` PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` + EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity" default:"false"` + PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"` } // PostgresPodResourcesDefaults defines the spec of default resources diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index c0ae1648c..9a58f0516 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -290,6 +290,26 @@ func nodeAffinity(nodeReadinessLabel map[string]string) *v1.Affinity { } } +func generatePodAffinity(labels labels.Set, topologyKey string, nodeAffinity *v1.Affinity) *v1.Affinity { + // generate pod anti-affinity to avoid multiple pods of the same Postgres cluster in the same topology , e.g. node + podAffinity := v1.Affinity{ + PodAntiAffinity: &v1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: labels, + }, + TopologyKey: topologyKey, + }}, + }, + } + + if nodeAffinity != nil && nodeAffinity.NodeAffinity != nil { + podAffinity.NodeAffinity = nodeAffinity.NodeAffinity + } + + return &podAffinity +} + func tolerations(tolerationsSpec *[]v1.Toleration, podToleration map[string]string) []v1.Toleration { // allow to override tolerations by postgresql manifest if len(*tolerationsSpec) > 0 { @@ -419,6 +439,8 @@ func generatePodTemplate( kubeIAMRole string, priorityClassName string, shmVolume bool, + podAntiAffinity bool, + podAntiAffinityTopologyKey string, ) (*v1.PodTemplateSpec, error) { terminateGracePeriodSeconds := terminateGracePeriod @@ -437,7 +459,9 @@ func generatePodTemplate( addShmVolume(&podSpec) } - if nodeAffinity != nil { + if podAntiAffinity { + podSpec.Affinity = generatePodAffinity(labels, podAntiAffinityTopologyKey, nodeAffinity) + } else if nodeAffinity != nil { podSpec.Affinity = nodeAffinity } @@ -813,7 +837,9 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State c.OpConfig.PodServiceAccountName, c.OpConfig.KubeIAMRole, effectivePodPriorityClassName, - mountShmVolumeNeeded(c.OpConfig, spec)); err != nil { + mountShmVolumeNeeded(c.OpConfig, spec), + c.OpConfig.EnablePodAntiAffinity, + c.OpConfig.PodAntiAffinityTopologyKey); err != nil { return nil, fmt.Errorf("could not generate pod template: %v", err) } diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 74549cbb8..08df7e97c 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -53,6 +53,9 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.NodeReadinessLabel = fromCRD.Kubernetes.NodeReadinessLabel result.PodPriorityClassName = fromCRD.Kubernetes.PodPriorityClassName + result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity; + result.PodAntiAffinityTopologyKey = fromCRD.Kubernetes.PodAntiAffinityTopologyKey; + result.DefaultCPURequest = fromCRD.PostgresPodResources.DefaultCPURequest result.DefaultMemoryRequest = fromCRD.PostgresPodResources.DefaultMemoryRequest result.DefaultCPULimit = fromCRD.PostgresPodResources.DefaultCPULimit diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 371b7cb65..a82f4c17d 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -95,6 +95,8 @@ type Config struct { EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"` EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` CustomServiceAnnotations map[string]string `name:"custom_service_annotations"` + EnablePodAntiAffinity bool `name:"enable_pod_antiaffinity" default:"false"` + PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"` // deprecated and kept for backward compatibility EnableLoadBalancer *bool `name:"enable_load_balancer"` MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{team}.{hostedzone}"`