Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for per-cluster and operator global sidecars #331

Merged
merged 15 commits into from
Jul 2, 2018

Conversation

alexeyklyukin
Copy link
Contributor

  • Based on the work of @theRealWardo to to implement per-cluster sidecards

  • Add support for operator-global sidecards (currently crude, as we only allow the list of docker images, and the optional variables (besides mandatory POD_NAME, POD_NAMESPACE, POSTGRES_USER and POSTGRES_PASSWORD ) can only be propagated via either pod_environment_configmap or Pod Presets. Should be improved once Allow configuring the operator via the YAML manifest. #326 is merged).

  • Do refactoring around the code that generates the statefulset, particularly, decouple most of the helper routines from the cluster object in order to simplify their testing in the future, as well as to convert the scalar configuration internally to a sidecar structure to use the common code path.

WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to'
EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use k8s as a DCS
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-cdp-10:1.4-p8"`
Sidecars map[string]string `name:"sidecars"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I see this right, this is a map of sidecar container name to docker images? Maybe we should make it more clear from the variable name? That is not sidecar name to yaml?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is documented I wouldn't mind a better name. Perhaps sidecar_docker_images?

@Jan-M
Copy link
Member

Jan-M commented Jun 27, 2018

How would this solution help us with our Scalyr Sidecar? I dont see how to inject the key on global level?

@alexeyklyukin
Copy link
Contributor Author

Well, outside of making the code less horrible by converting the scalyr hard-code to the same sidecar structure used to inject other sidecars so far it doesn't. However, I don't think it should be our goal to cram those things into the operator; what I propose instead is to rely on the Kubernetes feature called PodPresets to inject environment variables and remove all duplication of it (namely, https://postgres-operator.readthedocs.io/en/latest/administrator/#custom-pod-environment-variables) from the operator altogether.

Make it more explicit that this parameter only controls the docker
images, not the YAML manifest definiting other aspect of sidecar
configuration (such as environment variables.)
@alexeyklyukin
Copy link
Contributor Author

👍

* **sidecar_docker_images**
a map of sidecar names to docker images for the containers to run alongside
Spilo. In case of the name conflict with the definition in the cluster
manifest the cluster-specific one is preferred.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is preferred == is used ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

return envVars
}

// deduplicateEnvVars makes sure there are no duplicate in the target envVar array. While Kubernetes already does, it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Kubernetes already does,

already does deduplication i assume?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, looks like I've lost a word or two :-(

names[va.Name] += 1
result = append(result, input[i])
} else if names[va.Name] == 1 {
names[va.Name] += 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to count the number of definitions if we seem even not to log this number ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid producing this log message on each occurrences of the duplicate parameter (as opposed to only once when the duplicate is detected.)

result = append(result, input[i])
} else if names[va.Name] == 1 {
names[va.Name] += 1
logger.Warningf("variable %q is defined in %q more than once, the subsequent definitions are ignored",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it worth logging here the first definition here to showcase what is actually applied ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say the purpose of this warning is to prevent such cases, not to assist in constructing them to get what you want. I don't want to overload it with an extra debugging info.

// resolve conflicts between operator-global and per-cluster sidecards
sideCars := c.mergeSidecars(spec.Sidecars)

resourceRequirementsScalyrSidecar := makeResources(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generating the scalyr sidecar probably deserves a separate function; this method is already way too long

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, the function to generate Scalyr sidecars has only 5 parameters instead of 9. I preferred smaller functions that build parts of the manifest and them combine them all in a reasonably long generateStatefulSet, rather than a small generateStatefulSet that calls rather complex functions; the first approach makes the code easier to test and to understand.


// generate scalyr sidecar containers
if scalarSidecar, present :=
generateScalarSidecarSpec(c.Name,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scalar

Scalyr :)

}

func generateScalarSidecarSpec(clusterName, APIKey, serverURL, dockerImage string, containerResources *spec.Resources) (sidecar *spec.Sidecar, present bool) {
if APIKey == "" || serverURL == "" || dockerImage == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that if this particular sidecar is misconfigured, we silently ignore this fact w/o logging it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Probably the better solution would be to complain if one of those parameters is set but not all.

WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to'
EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use k8s as a DCS
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-cdp-10:1.4-p8"`
Sidecars map[string]string `name:"sidecar_docker_images"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about adding a short example to the operator manifest ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure it actually needs sidecars.

@coveralls
Copy link

coveralls commented Jul 2, 2018

Coverage Status

Coverage decreased (-0.2%) to 4.678% when pulling 98da75a on refactoring/sidecars into 74b19b4 on master.

@sdudoladov
Copy link
Member

👍

Per review by @zerg-junior
@alexeyklyukin
Copy link
Contributor Author

👍

1 similar comment
@sdudoladov
Copy link
Member

👍

@alexeyklyukin alexeyklyukin merged commit 25a3062 into master Jul 2, 2018
@alexeyklyukin alexeyklyukin deleted the refactoring/sidecars branch July 2, 2018 14:25
@theRealWardo
Copy link

awesome! thanks for carrying this through!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants