Skip to content

Commit faaed40

Browse files
Add --bootstrap-config-name|namespace to kubelet
This allows the kubelet to be configured to load default configuration out of a known namespace. By default it is openshift-node/node-config. Correct an error in bootstrapping where errors weren't logged, and properly ignore forbidden errors when trying to load the config map. Add a better description of bootstrapping to openshift start node.
1 parent bee1281 commit faaed40

File tree

5 files changed

+79
-32
lines changed

5 files changed

+79
-32
lines changed

contrib/completions/bash/openshift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33725,6 +33725,10 @@ _openshift_start_node()
3372533725

3372633726
flags+=("--bootstrap")
3372733727
local_nonpersistent_flags+=("--bootstrap")
33728+
flags+=("--bootstrap-config-name=")
33729+
local_nonpersistent_flags+=("--bootstrap-config-name=")
33730+
flags+=("--bootstrap-config-namespace=")
33731+
local_nonpersistent_flags+=("--bootstrap-config-namespace=")
3372833732
flags+=("--config=")
3372933733
flags_with_completion+=("--config")
3373033734
flags_completion+=("__handle_filename_extension_flag yaml|yml")

contrib/completions/zsh/openshift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33874,6 +33874,10 @@ _openshift_start_node()
3387433874

3387533875
flags+=("--bootstrap")
3387633876
local_nonpersistent_flags+=("--bootstrap")
33877+
flags+=("--bootstrap-config-name=")
33878+
local_nonpersistent_flags+=("--bootstrap-config-name=")
33879+
flags+=("--bootstrap-config-namespace=")
33880+
local_nonpersistent_flags+=("--bootstrap-config-namespace=")
3387733881
flags+=("--config=")
3387833882
flags_with_completion+=("--config")
3387933883
flags_completion+=("__handle_filename_extension_flag yaml|yml")

pkg/cmd/server/start/bootstrap_node.go

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,20 @@ func (o NodeOptions) loadBootstrap(hostnames []string, nodeConfigDir string) err
212212

213213
// try to refresh the latest node-config.yaml
214214
o.ConfigFile = filepath.Join(nodeConfigDir, "node-config.yaml")
215-
config, err := c.Core().ConfigMaps("kube-system").Get("node-config", metav1.GetOptions{})
215+
config, err := c.Core().ConfigMaps(o.NodeArgs.BootstrapConfigNamespace).Get(o.NodeArgs.BootstrapConfigName, metav1.GetOptions{})
216216
if err == nil {
217+
glog.V(2).Infof("Loading node configuration from %s/%s (rv=%s, uid=%s)", config.Namespace, config.Name, config.ResourceVersion, config.UID)
217218
// skip all the config we generated ourselves
218-
skipConfig := map[string]struct{}{"server.crt": {}, "server.key": {}, "master-client.crt": {}, "master-client.key": {}, "node.kubeconfig": {}}
219+
skipConfig := map[string]struct{}{
220+
"server.crt": {},
221+
"server.key": {},
222+
"master-client.crt": {},
223+
"master-client.key": {},
224+
"node.kubeconfig": {},
225+
}
219226
for k, v := range config.Data {
220227
if _, ok := skipConfig[k]; ok {
228+
glog.V(2).Infof("Skipping key %q from config map", k)
221229
continue
222230
}
223231
b := []byte(v)
@@ -233,10 +241,10 @@ func (o NodeOptions) loadBootstrap(hostnames []string, nodeConfigDir string) err
233241
if err := o.NodeArgs.MergeSerializeableNodeConfig(nodeConfig); err != nil {
234242
return err
235243
}
236-
nodeConfig.ServingInfo.ServerCert.CertFile = filepath.Join(nodeConfigDir, "server.crt")
237-
nodeConfig.ServingInfo.ServerCert.KeyFile = filepath.Join(nodeConfigDir, "server.key")
238-
nodeConfig.ServingInfo.ClientCA = nodeClientCAPath
239-
nodeConfig.MasterKubeConfig = filepath.Join(nodeConfigDir, "node.kubeconfig")
244+
nodeConfig.ServingInfo.ServerCert.CertFile = "server.crt"
245+
nodeConfig.ServingInfo.ServerCert.KeyFile = "server.key"
246+
nodeConfig.ServingInfo.ClientCA = "node-client-ca.crt"
247+
nodeConfig.MasterKubeConfig = "node.kubeconfig"
240248
b, err = configapilatest.WriteYAML(nodeConfig)
241249
if err != nil {
242250
return err
@@ -252,35 +260,42 @@ func (o NodeOptions) loadBootstrap(hostnames []string, nodeConfigDir string) err
252260

253261
// if we had a previous node-config.yaml, continue using it
254262
if _, err2 := os.Stat(o.ConfigFile); err2 == nil {
255-
if err == nil {
256-
glog.V(2).Infof("Unable to load node configuration from the server: %v", err)
263+
if err != nil {
264+
glog.Warningf("Unable to load node configuration from the server: %v", err)
257265
}
258266
return nil
259267
}
260268

261-
// if there is no node-config.yaml and no server config map, generate one
262-
if kerrors.IsNotFound(err) {
263-
glog.V(2).Infof("Generating a local configuration since no server config available")
264-
nodeConfig, err := o.NodeArgs.BuildSerializeableNodeConfig()
265-
if err != nil {
266-
return err
267-
}
268-
if err := o.NodeArgs.MergeSerializeableNodeConfig(nodeConfig); err != nil {
269-
return err
270-
}
271-
nodeConfig.ServingInfo.ServerCert.CertFile = "server.crt"
272-
nodeConfig.ServingInfo.ServerCert.KeyFile = "server.key"
273-
nodeConfig.ServingInfo.ClientCA = "node-client-ca.crt"
274-
nodeConfig.MasterKubeConfig = "node.kubeconfig"
275-
b, err := configapilatest.WriteYAML(nodeConfig)
276-
if err != nil {
277-
return err
278-
}
279-
if err := ioutil.WriteFile(o.ConfigFile, b, 0600); err != nil {
280-
return err
281-
}
282-
return nil
269+
switch {
270+
case kerrors.IsNotFound(err):
271+
err = nil
272+
case kerrors.IsForbidden(err):
273+
glog.Warningf("Node is not authorized to access config, continuing without config: %v", err)
274+
err = nil
275+
}
276+
if err != nil {
277+
return err
283278
}
284279

285-
return err
280+
// if there is no node-config.yaml and no server config map, generate one
281+
glog.V(2).Infof("Generating a local configuration since no server config available")
282+
nodeConfig, err := o.NodeArgs.BuildSerializeableNodeConfig()
283+
if err != nil {
284+
return err
285+
}
286+
if err := o.NodeArgs.MergeSerializeableNodeConfig(nodeConfig); err != nil {
287+
return err
288+
}
289+
nodeConfig.ServingInfo.ServerCert.CertFile = "server.crt"
290+
nodeConfig.ServingInfo.ServerCert.KeyFile = "server.key"
291+
nodeConfig.ServingInfo.ClientCA = "node-client-ca.crt"
292+
nodeConfig.MasterKubeConfig = "node.kubeconfig"
293+
b, err := configapilatest.WriteYAML(nodeConfig)
294+
if err != nil {
295+
return err
296+
}
297+
if err := ioutil.WriteFile(o.ConfigFile, b, 0600); err != nil {
298+
return err
299+
}
300+
return nil
286301
}

pkg/cmd/server/start/node_args.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type NodeArgs struct {
5858

5959
// Bootstrap is true if the node should rely on the server to set initial configuration.
6060
Bootstrap bool
61+
// BootstrapConfigName is the name of a config map to read node-config.yaml from.
62+
BootstrapConfigName string
63+
// BootstrapConfigNamespace is the namespace the config map for bootstrap config is expected to load from.
64+
BootstrapConfigNamespace string
6165

6266
MasterCertDir string
6367
ConfigDir flag.StringFlag
@@ -129,6 +133,9 @@ func NewDefaultNodeArgs() *NodeArgs {
129133

130134
NodeName: hostname,
131135

136+
BootstrapConfigName: "node-config",
137+
BootstrapConfigNamespace: "openshift-node",
138+
132139
MasterCertDir: "openshift.local.config/master",
133140

134141
ClusterDomain: cmdutil.Env("OPENSHIFT_DNS_DOMAIN", "cluster.local"),
@@ -152,6 +159,14 @@ func (args NodeArgs) Validate() error {
152159
if addr, _ := args.KubeConnectionArgs.GetKubernetesAddress(args.DefaultKubernetesURL); addr == nil {
153160
return errors.New("--kubeconfig must be set to provide API server connection information")
154161
}
162+
if args.Bootstrap {
163+
if len(args.BootstrapConfigName) == 0 {
164+
return errors.New("--bootstrap-config-name must be specified")
165+
}
166+
if len(args.BootstrapConfigNamespace) == 0 {
167+
return errors.New("--bootstrap-config-namespace must be specified")
168+
}
169+
}
155170
return nil
156171
}
157172

pkg/cmd/server/start/start_node.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ var nodeLong = templates.LongDesc(`
5252
%[1]s start node --config=<node-config>
5353
5454
will start a node with given configuration file. The node will run in the
55-
foreground until you terminate the process.`)
55+
foreground until you terminate the process.
56+
57+
The --bootstrap flag instructs the node to use the provided kubeconfig
58+
file to contact the master and request a client cert (its identity) and
59+
a serving cert, and then downloads node-config.yaml from a config map on
60+
the server. If no config map exists, it will use the default settings.
61+
In this mode --config will be location of the downloaded config.
62+
`)
5663

5764
// NewCommandStartNode provides a CLI handler for 'start node' command
5865
func NewCommandStartNode(basename string, out, errout io.Writer) (*cobra.Command, *NodeOptions) {
@@ -82,6 +89,8 @@ func NewCommandStartNode(basename string, out, errout io.Writer) (*cobra.Command
8289
BindKubeConnectionArgs(options.NodeArgs.KubeConnectionArgs, flags, "")
8390

8491
flags.BoolVar(&options.NodeArgs.Bootstrap, "bootstrap", false, "Use the provided .kubeconfig file to perform initial node setup (experimental).")
92+
flags.StringVar(&options.NodeArgs.BootstrapConfigName, "bootstrap-config-name", options.NodeArgs.BootstrapConfigName, "The name of a config map to load node-config.yaml from (experimental).")
93+
flags.StringVar(&options.NodeArgs.BootstrapConfigNamespace, "bootstrap-config-namespace", options.NodeArgs.BootstrapConfigNamespace, "The namespace containing a config map to load node-config.yaml from (experimental).")
8594

8695
// autocompletion hints
8796
cmd.MarkFlagFilename("config", "yaml", "yml")

0 commit comments

Comments
 (0)