-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Write Kubelet flags as an option on openshift start node to support moving directly to kubelet #18322
Write Kubelet flags as an option on openshift start node to support moving directly to kubelet #18322
Conversation
90bda95
to
8f83e8c
Compare
// an empty string, `--enforce-node-allocatable=""` needs to be explicitly set | ||
// cgroups-per-qos defaults to true | ||
if cgroupArg, enforceAllocatable := args["cgroups-per-qos"], args["enforce-node-allocatable"]; len(cgroupArg) == 1 && cgroupArg[0] == "false" && len(enforceAllocatable) == 0 { | ||
args["enforce-node-allocatable"] = []string{""} |
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 isn't the same thing. Empty string fails validiation. Empty value works. I tried this before and it failed the networking test.
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.
Wait, --enforce-node-allocatable=
fails but --enforce-node-allocatable=""
succeeds?
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.
as I recall it. --enforce-node-allocatable=
worked, --enforce-node-allocatable=""
failed
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.
Hrm, both seem to work for me right now. testing more
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 is generating --enforce-node-allocatable=
when i test
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 is generating --enforce-node-allocatable= when i test
Oh, that's a happy accident.
@@ -52,6 +52,10 @@ type NodeArgs struct { | |||
// Components is the set of enabled components. | |||
Components *utilflags.ComponentFlag | |||
|
|||
// WriteFlagsOnly will print flags to run the Kubelet from the provided arguments rather than launching | |||
// the Kubelet itself. | |||
WriteFlagsOnly bool |
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.
@sdodson I knew it was only a matter of time....
pkg/cmd/server/start/start_node.go
Outdated
@@ -256,7 +267,7 @@ func (o NodeOptions) RunNode() error { | |||
return nil | |||
} | |||
|
|||
if err := StartNode(*nodeConfig, o.NodeArgs.Components); err != nil { | |||
if err := StartNode(*nodeConfig, o.NodeArgs.Components, o.NodeArgs.WriteFlagsOnly); err != nil { |
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.
Rather than passing an "behave differently flag" to StartNode
, you can detect and print out the options from a different method right above this.
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.
ok
} | ||
|
||
// convert current settings to flags | ||
args := append([]string{kubeletPath}, kubeletArgs...) | ||
for i := glog.Level(10); i > 0; i-- { |
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.
What is this actually doing? Why is it doing it? I couldn't sort it out and a few lines down on the --vmodule
the sprintf looks broken anyway.
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.
glog doesn't let you get the glog value directly, you have to test each level on your own.
If I'm reading the intent correctly, this change allows the kubelet to start up with failing transports to the Without a valid connection to the master, the kublet won't have a complete configuration unless the configuration exists on disk before starting the process. Are you counting on the dynamic configuration to work correctly in order for this to function? |
@openshift/sig-security |
The installer needs to write out a minimal config. That was already a requirement in practice for flags like |
e6350c7
to
27ae459
Compare
Updated with all feedback |
@@ -42,7 +43,9 @@ func ValidateInClusterNodeConfig(config *api.NodeConfig, fldPath *field.Path) Va | |||
validationResults.AddErrors(ValidateHostPort(config.DNSBindAddress, fldPath.Child("dnsBindAddress"))...) | |||
} | |||
if len(config.DNSIP) > 0 { | |||
validationResults.AddErrors(ValidateSpecifiedIP(config.DNSIP, fldPath.Child("dnsIP"))...) | |||
if !hasBootstrapConfig || config.DNSIP != "0.0.0.0" { |
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.
demorgans please.
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 don't think that's any easier to read. parenthesis are more confusing.
@@ -224,6 +235,17 @@ func (o NodeOptions) RunNode() error { | |||
if addr := o.NodeArgs.ListenArg.ListenAddr; addr.Provided { | |||
nodeConfig.ServingInfo.BindAddress = addr.HostPort(o.NodeArgs.ListenArg.ListenAddr.DefaultPort) | |||
} | |||
// do a local resolution of node config DNS IP, supports bootstrapping cases | |||
if nodeConfig.DNSIP == "0.0.0.0" { |
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 this is not a listen address, it is a connection address? Using 0.0.0.0
to do defaulting feels wrong. ***autodetect***
is an illegal value for a hostname or IP that will never be confused as something else.
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.
0.0.0.0 was never allowed before. We changed it in 3.7 to mean "the local address". It has to be an IP because of DNS. We can't change the value that means autodetect because 3.7 clusters are using 0.0.0.0
} | ||
args["cluster-dns"] = getClusterDNS(externalKubeClient, args["cluster-dns"]) | ||
|
||
return args, nil | ||
} | ||
|
||
func KubeletArgsMapToArgs(argsMap map[string][]string) []string { |
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.
any need for this to still be a separate method or can we tidy it up?
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.
No, can collapse it.
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.
Actually used in two places, but I'm going to move it to the call site
0.0.0.0 meaning: "choose a default for me" rubs me the wrong way. |
Ship sailed in 3.7 on that. Also, dnsmasq uses roughly that, so it's a DNS-ism |
We weren't actually failing kubelet start, so waiting made no sense. Instead, we always start. Also, if the last rotated cert has expired, fallback to the bootstrap certificate info.
27ae459
to
9d90184
Compare
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: smarterclayton 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 |
pkg/cmd/server/start/start_node.go
Outdated
// WriteKubeletFlags writes the correct set of flags to start a Kubelet from the provided node config to | ||
// stdout, instead of launching anything. | ||
func WriteKubeletFlags(nodeConfig configapi.NodeConfig) error { | ||
kubeletFlagsAsMap, err := nodeoptions.ComputeKubeletFlagsAsMap(nodeConfig.KubeletArguments, nodeConfig) |
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 meant: couldn't this just return the string slice of args? It's the first thing you do at both call sites
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.
Oh.
one nit. lgtm |
This acts like --write-config, but instead outputs the flags that the specified --config file would pass to the Kubelet. This prepares us to stop calling openshift start node and instead direct invoke the Kubelet. Remove the unsupported kubelet binary code because we are no longer calling ourself. Also move a small chunk of flag specialization code into a more appropriate place.
9d90184
to
049d247
Compare
Fixed. Labelling |
/retest
|
2 similar comments
/retest |
/retest |
shakes fist at networking flake /retest |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest |
1 similar comment
/retest |
Automatic merge from submit-queue. |
@@ -141,7 +141,6 @@ type manager struct { | |||
certStore Store | |||
certAccessLock sync.RWMutex | |||
cert *tls.Certificate | |||
rotationDeadline time.Time |
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.
@smarterclayton The changes in certificate_manager.go
/certificate_manager_test.go
look unrelated to introducing a new option. Are they really have to be a part of that PR or it was unintentionally?
Related. The rotation change was needed to allow starting a kubelet from flags without blocking in some conditions. You only need some of a config. |
@deads2k Oh, I see now that it was mentioned in the PR description. My bad, sorry. |
Instead of having openshift start node bootstrap, prepare to move to directly invoking the kubelet by having a flag on
openshift start node
called--write-flags
that generates the arguments to invoke the kubelet for a given--config
. Instead of callingopenshift start node
to do bootstrapping, we'd instead invoke the --write-flags path and call the kubelet directly. The generated node-config on the system would have the correct bootstrap settings.Would require us to move to dynamic config in the kubelet or to add a secondary loop to pull down the latest kube-config. That's probably acceptable.
Also contains a set of changes that allow certificate rotation to happen completely in the background, rather than blocking the kubelet startup. This allows us to keep bootstrapping the node from the master, but to still launch static pods in the bacgkround (right now we can't launch static pods while bootstrapping because bootstrapping is happening before the kubelet pod sync loop runs). In this model, master containers as static pods will not require any node changes to make work (so master nodes wouldn't be different from other nodes). I'm going to clean this up and propose upstream.
Note that this path would not require --runonce mode, which is very good because it's effectively unsupported.
@deads2k we're block on static pod for kubelet until we sort out the path forward. I don't want to have two separate types of node config, and I think this is probably the best position in the long run (all nodes bootstrap and have static pod config, nodes background loop waiting for bootstrapping and reject requests that require client/server connections until bootstrapping completes).