-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Proposal: Template object for in-container configuration files #30716
Comments
cc @smarterclayton @pmorie @bparees @eparis @derekwaynecarr @kubernetes/rh-cluster-infra |
How far can you get using an init-container? For example: init-container consumes data from a configmap, substitutes values, and writes the resulting complete config file to a a path in an EmptyDir. The main container reads the config file generated by the init container. |
@erictune two comments on init containers:
|
Image volumes have been requested - in the future that would address #2 as On Wed, Aug 17, 2016 at 3:00 PM, Josh Berkus notifications@github.com
|
Devils advocate - why can't you provide a custom Command to the container and apply the transformation in that container? The entrypoint would then be in the pod definition, not the image. While I'm sympathetic to templated config map, you can already templatize in Command and Args (IIRC), so this is already possible. |
Would be:
If config map was a valid target for env valueFrom (which it should be, because of secrets), then this should allow you to at least craft templates without changing the image. |
That strikes me as unsatisfying for a number of reasons: First, it means sharing the configuration is harder -- with a ConfigTemplate, you can just say Secondly, it makes sharing the config harder -- you can just share the config template as standalone object, you have to share it as part of the pod spec, and then the receiver has to extract the relevant parts from the pod spec. Also, it makes the entrypoint on an image much harder to read -- you go from just having a command to having a chain of commands that do |
Templates of config are pretty closely coupled to pods. You can always put the template in the config and combine them in the pod. The entrypoint is under the control of the pod author. If the pod author doesn't control the image, they can control the entrypoint via the pod definition. I'm fairly sure that we can provide an idiomatic representation of config templating in the pod template, which does allow references to other resources. I am very skeptical of configmaps that point to other configmaps, so it's a much harder argument to say that we want to support references between a config map and another resource AND support references between pods and config maps. |
Generally our answer to this has been - "init containers". Given that gives you access to a turing complete space, and everything we provide in a config map can be transformed, you can use any templating language you want, combine any config map you want, and control it all, without any changes to kubernetes. The alternative - implement |
As a note - my point here is not to dismiss ConfigTemplate out of hand, it is merely to ensure that the mechanisms that we have that should be able to solve this actually solve this in a clear and demonstrable way. If they don't, they absolutely must be fixed. |
@smarterclayton can you give an example of an init container implementation, using current Kubernetes? Because my experience is that they're more complicated than you describe. But maybe I'm doing them badly. |
A few thoughts. First, a new object on its own does nothing for you. You still need a new Second, there are tricks that can pull files from multiple volumes (secret, Third, there are ways to inject a new entrypoint.sh into a container. You Fourth, I didn't grok why a sidecar doesn't work? Declare an emptydir Lastly, nothing stops you from using third-party resource and flex volume On Wed, Aug 17, 2016 at 3:46 PM, Josh Berkus notifications@github.com
|
@thockin I'm not looking to make this possible, I'm looking to make it simple. It's possible now, but a large number of our users can't figure out how to do it. And this is a spec issue, so the purpose of this is "let's determine the spec for this". Projecting configuration files into running containers is something our users need to do for something like 3/4 of running containers. Right now the standard approach for that is hackish entrypoint.sh scripts, which is a terrible state of the art, and causes a lot of folks to legitimately question whether they made a mistake moving away from CMS and towards orchestration. Something which 80% of our users need to do 75% of the time shouldn't be complicated or require advanced Kubernetes knowledge. It should be simple, obvious, and there should be a recommended mainstream way to do it. Whether that's templates or config volumes or sidecars, I don't really care, provided that it's something which a new Kubernetes user can learn in 20 minutes. |
No disagreement, but we should first explore refinements on existing On Thu, Aug 18, 2016 at 9:03 AM, Josh Berkus notifications@github.com
|
I'm OK with that. Would you be willing to sketch out a doc on how you'd do it, now? Because you seem to find existing approaches easier than I do. And maybe I'm doing them in an unnecessessarily complicated way. If we can reduce this to a doc item, that would be a win for everyone. |
I have zero bandwidth for the next few weeks. We need community folks I appreciate your vociferous advocacy of the user in this issue, so far... On Thu, Aug 18, 2016 at 9:20 AM, Josh Berkus notifications@github.com
|
I have created a simple PoC for configmap templating here: #30502 My solution however uses downwardAPI volumes and the configfiles are simple another possible item type that can be used there. Your idea with bare files that can be placed anywhere seems to be superior. I don't know however how it would be with implementation. Also what would be the possibilities to implement some improved change propagation. |
@thockin I hear you. Well, anything I do on this will need to come after CNCF day ... |
Definitely +1 to @jberkus words. This is very important topic (that's why @zefciu and @nebril made PoCs), it definitely should be easy and understandable to end user. I'm pretty sure that assumption that you can store configs in In my opinion any solution which uses init-containers, custom init scripts, init-containers to do templating feels hacky and requires serious k8s knowledge or pollutes pod/container definition with logic that shouldn't be there. |
About initscripts: besides "feeling hacky" the problem is they lack DRY-ness. You need to specify the data twice. First in the pod definition. Second - in the script. So your deployments become harder to maintain. My proposalLet's add an ability to add config file templates. These templates will be able to consume data from the following sources:
The templates will use syntax based on https://golang.org/pkg/text/template/ package (I believe it is powerful enough for our needs). The template can be:
The files can be inserted to the pod in two ways
The "DownwardAPI" volume could be renamed if it is confusing to newcomers. Generally however the original DownwardAPI and ConfigMap volumes should become deprecated as much less powerful than templating. What we needThe current state of PoC implements a lot for this proposal. What is still missing is:
Questions
I would like to call @nebril and @nhlfr to pay attention to this thread as well. The next two weeks I will login irregularly, but please comment. |
Oh, also @RustyRobot - please comment if these requirements are enough for us. |
@zefciu +1 BTW, one of the examples I'm dealing with is PostgreSQL, where the config files need to go into a specific directory, which also contains files we want to inherit from the upstream image. Postgres also has specific permissions requirements for those files. So I think that's a good test case for any scheme; if it can handle Postgres, it can probably cover any service. |
It does seem to be at least tangentially related, though I think the topic of "what happens if the config map changes" is still orthogonal to "can templated config maps change if upstream data sources change?" The latter seems very relevant. IMO the inline config map vs external config map would also be irrelevant given a good templating solution. If the templating solution is complete, then either option should reasonably accept template placeholders. Also to address another of @kelseyhightower 's concerns:
I think we'd all agree with that (if I'm understanding you correctly). And I think the intent is still that in any case, given k8s objects with template expressions, the final product is k8s objects ready for consumption, e.g. mounting into the volume as a config file, resulting in a container image that does not need to be tailored beforehand to k8s. |
I think it's important to note that we already have solutions in the I don't think any template language we include will make those tools easier For instance, we don't want to put a template language under apply - we As another example, iterative config application (inputs to template change A template evaluation environment that is even partially or strongly turing The short term things already discussed in this thread have a lot of
Did I miss any? On Mon, Sep 12, 2016 at 8:23 PM, Andrew Stuart notifications@github.com
|
On Mon, Sep 12, 2016 at 4:13 PM, Clayton Coleman
I assume you mean "without bouncing the pod, and the app does not pick
Someone laid a land mine and was sad when they stepped on it. I 100% Conversely, if you had defined it as an inline volume, RC and RS would If you don't want a time bomb, you HAVE to actuate changes right away,
Is "I updated a config map" really more confusing than "I updated my
Mismatched config is a fact of life, no matter what - whether that is
This is why we generally tell people not to update configmaps, but
I don't buy it - you can lay almost the same traps with an inline, if
|
@smarterclayton, all: I'm inclined at this point to close this in favor of a proposal of "make init containers easier to use", which seems like the way to go. However, there have been a LOT of other proposals on this issue which aren't mine; is it OK to just close it nevertheless? |
I wonder if resource templating as a whole would be worth discussing on the community call ( cc @sarahnovotny ) (Or, is there an appropriate SIG?). For me, there are already too many in-motion proposals and implementations (the helm tool and this templating issue spring to mind) to keep track of. Even if it's just a "yes, we are going with 23896 for the foreseeable future" acknowledgement, it'd be helpful in my mind for some sort of consensus and communication about the project's direction on this matter. |
Afair there are (were?) some plans to discuss that on sig-apps. |
@michelleN @andrewstuart @jberkus @smarterclayton @thockin could we organize a short discussion in sig-apps about that? |
I don't usually attend sig-apps, please let me know if/when this is on the On Mon, Oct 3, 2016 at 2:39 AM, Jędrzej Nowak notifications@github.com
|
Also, you may want to comment on #23896 and/or kubernetes/enhancements#35 if there's going to be a generalized discussion as they will almost certainly have either made progress already or have opinions and suggestions of their own to add. |
@pmorie Is there any chance that there is more documentation beyond the examples you mentioned in #30716 (comment) ? I desperately want to share the available syntax with colleagues, but cannot be certain how much is implemented (and in which version).
|
Any decision has been made on this? |
No templates. |
Is there a recommended way to inject a configuration file with interpolated variables/secret into a container at the moment? |
@eyalzek Please ask on kubernetes-users and/or stackoverflow, or try to build a consensus within SIG Apps. |
So , as of now im assuming no we dont / can't encrypt data in configmaps. |
/mark |
Summary
I would like us to get rid of custom entrypoint.sh scripts by supporting templating of in-container files.
The Problem
Despite current ConfigMap features, it remains necessary for many or most container images under Kubernetes to include "entrypoint.sh" scripts and/or customizations to the containerized applications which are particular to the Kubernetes environment. This results in forking of upstream images and limits portability of images between environments. It also results in some very hackish startup scripts (see Kelsey's "init scripts for hipsters").
Based on feedback through numerous issues and PRs, the main shortcoming in ConfigMap which would allow elimination of entrypoint scripts is the inability to include elements into a configuration file which are only available at deployment time. For example, some services, such as clustered databases or load balancers, need to know the Pod IP or the pod name as part of their configuration.
Suggested Solution: ConfigTemplate
Several proposals have been made to enhance ConfigMaps to embrace templating functionality, and they have met with significant opposition.
My proposal is that we create a new object ... named here a "ConfigTemplate" as placeholder until someone suggests a better one. This Template object would produce a file inside the deployed container, and could consume the Downward API, Secrets, and ConfigMaps in order to populate a template. This would be largely the same as PR #30502, but with a new object type instead of overloading ConfigMaps.
At a sketch, a ConfigTemplate for an ini-style config file could be inlined, and might look like this:
Note: what syntax we use for the exact substitutions is unimportant; let's just use whatever is easiest to support/code.
For inline versions, it is likely that only key: $value substitutions would be supported. For more complex behavior, including differently-formatted configuration files, we'd support file-based substitution, ala:
The file in question would be some kind of text file, with substitution tags in whatever syntax we decide on. Either way, the ConfigTemplate would then be used inside Pod definitions like this:
Why not volumes?
You'll notice above that I'm not taking a regular "volume" approach to this. That's because in many cases ... including some cases I have personally ... the rendered config file needs to share directories with files which come from the container image. Doing this in a volume is complicated, and will lead (again) to custom entrypoint.sh scripts.
However, if there are strong reasons to handle this as a volume, that could be worked around.
Templating Engines and Sidecars
There is some discussion about how templating would be handled and what templating engine we'd use. This includes a suggestion by @thockin that this be entirely sidecar functionality.
I will argue that providing config file templates which allow containers to start inside Kubernetes pods without modification is fairly central functionality to what Kubernetes does, and as such the general Template object should be a core Kubernetes object. However, I can certainly see the value of allowing the user to plug in their choice of rendering library for the actual template rendering for file-based templates; if nothing else, it would forestall a lot of arguments about syntax.
Even in that case, however, I would like us to provide a built-in very simple template renderer, one which is capable of just swapping in upstream facts for some specific variable syntax, such as ${fact} or {{fact}} or similar, and nothing else. Such a built-in renderer would satisfy 90% of users, and not push the user into installing extra dependencies.
Alternatives
I cannot personally think of any alternatives which will lead to the elimination of the majority of entrypoint.sh scripts. Suggestions welcome.
References
The text was updated successfully, but these errors were encountered: