-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
Allow passing in extra user-data to cloud-init #3633
Allow passing in extra user-data to cloud-init #3633
Conversation
/assign @justinsb |
Hey @brdude. The PR looks good, however is there specific behaviour you're looking to achieve by adding to the user-data that couldn't already be done via use of Hooks within the Cluster Spec? https://github.com/kubernetes/kops/blob/master/docs/cluster_spec.md#hooks I think we should be cautious with allowing people to modify the user-data, as there is a 16KB limit with AWS so you could potentially break the cluster provisioning process. |
@KashifSaadat it's not so much that it could not be done but the fact that the level of engineering required to port everything that currently exists in the infrastructure that uses user-data would be a huge burden and take an immense amount of engineering. Examples of what currently is done by user-data and what it's used for in my infra:
Would checking the size of user-data at creation time and failing if it exceeds the size be an appropriate solution here? |
/assign @justinsb PTAL when you have a chance. I am kinda on the fence with this one. If it goes through we need to not have the user blow up there user data. |
@chrislovecnm when you say blow up their user data, are you referring to the size of the user data or if there is an error in their user data? For the first we can add a check to ensure the user-data does not exceed 16KB, for the second if a part of the user data is broken cloud-init will just fail for that piece but still run the other cloud-init data componets passed to it. |
^ yes Let @justinsb take a look and get his feedback. Not saying no, it just appears we are giving the user the same functionality to do the same thing. Just my thought. |
I think we're trying to encourage hooks and daemonsets. cloud-init isn't something I think we can support for the long-haul (e.g. the differences between what coreos supports & debian supports). As a compromise, how about we produce those example hooks or daemonsets for the use cases you're trying to achieve? e.g. there's a daemonset for NewRelic at https://github.com/kubernetes/examples/blob/master/staging/newrelic/README.md It is different from cloud-init, but it lets us use kubernetes management for these things, rather than having two classes of components. |
@justinsb at least for my use case unfortunately the NewRelic daemon set wouldn't solve our issues. We actually use user-data for other things besides cloud-init. We have daemon sets on boxes that do access management based on the user-data, since it cannot be changed without a reboot. We also have another daemon that uses other parts of user-data for identity management and ownership identification. These are just a couple examples. The reason I used cloud-init as the factor in the title is because that is what most people use it for. Unfortunately I had not realized that coreOS does not support multi-part mime. Would setting this up so that we only encode the user-data as a multipart mime if the user passes in EXTRA_USER_DATA be an acceptable middle ground? This way support for both types of user-data (Debian and CoreOS) would be possible. |
docs/extra_user-data.md
Outdated
|
||
### Adding additonal user-data | ||
|
||
Aditional user-user data can be passed to the host provissioning by utilizing the environment variable EXTRA_USER_DATA. By setting `EXTRA_USER_DATA` to `<file>:<content-type>` kops will load these aditional files and pass them on to the hosts. A list of valid content-types can be found [here](http://cloudinit.readthedocs.io/en/latest/topics/format.html#mime-multi-part-archive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typo provisioning
So actually I think this is OK, but with one tweak: I think we should not set up multipart if EXTRA_USER_DATA is not passed. Then for most people, there will be no change, and if you opt-in, you get multipart. Then a few suggestions:
Sorry this took so long for me to get my head around. If we can change it so that we don't do multipart unless the variable is set, lgtm! |
Going to close & reopen to retrigger e2e as well |
Going to close & reopen to retrigger e2e |
|
||
func validateExtraUserData(userData *kops.ExtraUserDataSpec) error { | ||
if userData.Name == "" { | ||
return field.Required(field.NewPath("ExtraUserData Name"), "extraUserData Name field must be set") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we are supposed to pass the parent field.Path into a validate function, and then it is fieldPath.Child("Name")
i.e. just the name of the field.
pkg/model/bootstrapscript.go
Outdated
@@ -160,7 +160,12 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cs *kops.Cluste | |||
}, | |||
} | |||
|
|||
templateResource, err := NewTemplateResource("nodeup", resources.AWSNodeUpTemplate, functions, nil) | |||
AWSNodeUpTemplate, err := resources.AWSNodeUpTemplate(ig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typically we prefer lower case for local variables, e.g. awsNodeUpTempler, err...
pkg/model/resources/nodeup.go
Outdated
@@ -170,3 +180,70 @@ __EOF_KUBE_ENV | |||
download-release | |||
echo "== nodeup node config done ==" | |||
` | |||
|
|||
// AWSNodeUpTemplate returns a Mime Multi Part Archive container the nodeup (bootstrap) script | |||
// and any aditional User Data passed to it in files using the env variable KOPS_EXTRA_USER_DATA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: comment is out of date (KOPS_EXTRA_USER_DATA)
pkg/model/resources/nodeup.go
Outdated
|
||
mimeWriter := multipart.NewWriter(writer) | ||
|
||
// we explicitly set the buoudaries to make testing easier. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typo in boundaries
case "text/cloud-config": | ||
case "text/part-handler": | ||
case "text/x-shellscript": | ||
case "text/cloud-boothook": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need all of these? My concern is that if we specify e.g. x-shellscript, it might interfere with normal boot in non-trivial ways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only one I need personally is "text/cloud-config". Just though I'd add all the valid types to have inclusive support since we're already putting support in. However I have nothibg against removing x-shellscript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we probably should, for safety, but I also want to get this PR in, so maybe we look at that in a separate PR :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(We can always add things to the set of permitted types, much harder to remove things)
@@ -17,15 +17,14 @@ limitations under the License. | |||
package scheme | |||
|
|||
import ( | |||
os "os" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're trying to move to goimports
formatted code... not sure what happened here :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah not sure what happened either I believe this was done when I generated the API for userData :-/
pkg/model/resources/nodeup.go
Outdated
// and any aditional User Data passed to it in files using the env variable KOPS_EXTRA_USER_DATA | ||
func AWSNodeUpTemplate(ig *kops.InstanceGroup) (string, error) { | ||
|
||
UserDataTemplate := NodeUpTemplate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: userDataTemplate
pkg/apis/kops/instancegroup.go
Outdated
@@ -109,6 +109,18 @@ type InstanceGroupSpec struct { | |||
Kubelet *KubeletConfigSpec `json:"kubelet,omitempty"` | |||
// Taints indicates the kubernetes taints for nodes in this group | |||
Taints []string `json:"taints,omitempty"` | |||
// ExtraUserData is any extra user-data to be passed to the host | |||
ExtraUserData []ExtraUserDataSpec `json:"extraUserData,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better or worse, we've called this additionalX
previously...
How do you feel about:
AdditionalUserData []UserDataSpec
json:"additionalUserData,omitempty"``
pkg/apis/kops/instancegroup.go
Outdated
} | ||
|
||
// ExtraUserDataSpec defines a user-data section | ||
type ExtraUserDataSpec struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can also be AdditionalUserDataSpec
or just UserDataSpec
, or maybe even UserData
.
My 2c: UserData
Looks great - API is the one thing we really can't change easily, so how would you feel about naming the field |
Quick note, looks like AdditionalSANs did not have API machinery ran on it so this includes changes for that as well. |
f077e79
to
6aa7de8
Compare
@brdude I will PR api machinery update ... and open api as well. |
6aa7de8
to
d85ea8e
Compare
d85ea8e
to
ef24cec
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: justinsb The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
/test all [submit-queue is verifying that this PR is safe to merge] |
Automatic merge from submit-queue. |
Looking at https://godoc.org/k8s.io/kops/pkg/apis/kops#InstanceGroupSpec and kubernetes#3633, the field is `AdditionalUserData` not `ExtraUserData`
Automatic merge from submit-queue. Update Additional user-data per #3853 Looking at https://godoc.org/k8s.io/kops/pkg/apis/kops#InstanceGroupSpec and #3633, the field is `AdditionalUserData` not `ExtraUserData` This addresses #3853
This allows for the utilization of multipart mime to pass extra data to cloud-init.
This gives you the ability to utilize cloud-init features such as setting up a CM or monitoring so that existing infrastructure components can be leveraged.