-
Notifications
You must be signed in to change notification settings - Fork 405
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
refactor: the node convert/revert feature #206
Conversation
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.
Thanks for submitting the PR! It looks good except for some minor issues. If these changes are applied, do we need to change the way of running yurtctl convert/revert? If so, would you also update the tutorial? Thanks!
@@ -1,4 +1 @@ | |||
FROM alpine:3.8 |
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.
why use ubuntu instead of alpine?
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.
When the pod Yurtctl-servant-convert runs the command nsenter -t 1 -m -u -n -i /bin/yurtctl convert edgenode --yurthub-image {{.yurthub_image}} --join-token {{.joinToken}} --pod-manifest-path {{.pod_manifest_path}}
, command nsenter
in alpine will parse --yurthub-image
into the parameters of nsenter. It will not have this problem with ubuntu.
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.
Thanks for the explanation. Would you try nsenter -t 1 -m -u -n -i -- /bin/yurtctl convert edgenode --yurthub-image {{.yurthub_image}} --join-token {{.joinToken}} --pod-manifest-path {{.pod_manifest_path}}
in alpine? Let's use '--' to tell nsenter to stop option parsing. As the size of the alpine is smaller than the ubuntu, using it can help us reduce the network throughput when setting up a large cluster.
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.
Thanks!I test it and it works!
openyurtDir string | ||
} | ||
|
||
func NewConvertEdgeNodeOptions() *ConvertEdgeNodeOptions { |
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.
Could you add GoDoc comment for the function and other exposed functions?
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.
👌
pkg/yurtctl/cmd/convert/edgenode.go
Outdated
}, | ||
} | ||
|
||
cmd.Flags().String("join-token", "", "the join token.") |
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 token used by yurthub for joining the cluster.
@@ -0,0 +1,276 @@ | |||
package convert |
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.
Please add the license.
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.
How to add the license? Make verify?
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 OpenSource License : )
/*
Copyright 2021 The OpenYurt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
@@ -0,0 +1,182 @@ | |||
package revert |
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.
Please add the license.
pkg/yurtctl/util/edgenode/exec.go
Outdated
@@ -0,0 +1,76 @@ | |||
package edgenode |
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.
Please add the license.
pkg/yurtctl/util/edgenode/exec.go
Outdated
|
||
// Exec run command and exit formatted error, callers can print err directly | ||
// Any running error or non-zero exitcode is consider as error | ||
func (cmd *Command) Exec() error { |
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.
why not use os/exec
package?
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 struct Command
contains all the information about cmd running and can be used in other places. If wants to be simpler, os/exec can be uses here.
@@ -0,0 +1,105 @@ | |||
package edgenode |
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.
Please add the license.
pkg/yurtctl/util/edgenode/util.go
Outdated
} | ||
if contents == nil { | ||
return "", fmt.Errorf("no matching string %s in file %s", regularExpression, filename) | ||
} else if len(contents) > 1 { |
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.
else if len(contents) > 1 {}
=> if len(contents) > 1 {}
pkg/yurtctl/util/kubernetes/util.go
Outdated
var wg sync.WaitGroup | ||
var servantJobTemplate 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.
servantJobTemplate := constants.ConvertServantJobTemplate
if !convert {
servantJobTemplate = constants.RevertServantJobTemplate
}
pkg/yurtctl/cmd/revert/edgenode.go
Outdated
return err | ||
} | ||
klog.Infof("found backup file %s, will use it to revert the node", kubeletSvcBk) | ||
err = os.Rename(kubeletSvcBk, r.kubeletSvcPath) |
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.
maybe we need delete the converted kubeletSvcPath file before rename the backup file?
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 effect of os.Rename() is similar to mv, it will overwrite original file. So the converted kubeletSvcPath file will be deleted at the same 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.
ok, i got it
pkg/yurtctl/constants/constants.go
Outdated
- name: NODE_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: spec.nodeName | ||
` |
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.
env STATIC_POD_PATH is missed
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.
yurtctl convert
provides the value of STATIC_POD_PATH:
if err = kubeutil.RunServantJobs(co.clientSet, map[string]string{
"provider": string(co.Provider),
"action": "convert",
"yurtctl_servant_image": co.YurctlServantImage,
"yurthub_image": co.YurhubImage,
"joinToken": joinToken,
"pod_manifest_path": co.PodMainfestPath,
}, edgeNodeNames, true);
however, yurtctl revert
not provides it:
if err = kubeutil.RunServantJobs(ro.clientSet,
map[string]string{
"action": "revert",
"yurtctl_servant_image": ro.YurtctlServantImage,
},
edgeNodeNames, false);
so I delete the env STATIC_POD_PATH in RevertServantJobTemplate
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, must had missed STATIC_POD_PATH var for yurtctl revert
command, how ablout add STATIC_POD_PATH for yurtctl revert
cmd?
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.
return content | ||
} | ||
|
||
func GetNodeName() (string, error) { |
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.
how about use env NODE_NAME in convert and revert command instead of new GetNodeName() function?
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.
Does NODE_NAME refer to the env HOSTNAME?
If so, kubelet startup parameters --hostname-override
can be used to configure the host name of the node displayed in the cluster, so the node name in cluster can be different from env HOSTNAME. And it need to get the node name in cluster accurately, because we need to get node resources through node name later.
So maybe it's better to use GetNodeName() function?
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.
using NODE_NAME means we can add the following setting to the pod spec
...
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
...
But yes, I think we should try to get the correct nodename from the service configuration directly, if --hostname-override
can be used to overwrite the nodename.
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.
@Peeknut as @charleszheng44 had said, env NODE_NAME is set in ServantJobTemplate by spec.nodeName
field, so in spite of --hostname-override
is set or not, we can get the node name accurately by env NODE_NAME .
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.
That's right. For yurtctl convert/revert
, we can directly use NODE_NAME. However, for directly calling yurtctl convert/revert edgenode
, NODE_NAME may not be set, we need to read the configuration file to get it. Both approaches may be required. Maybe I should add steps to read env NODE_NAME in GetNodeName() function?
isEdgeNode, ok := node.Labels[projectinfo.GetEdgeWorkerLabelKey()] | ||
if ok && isEdgeNode == "true" { | ||
// 2.1. check the state of worker nodes | ||
_, condition := nodeutil.GetNodeCondition(&node.Status, v1.NodeReady) |
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.
maybe we need add node ready status check at the begin of edgenode convert and revert command.
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.
yurtctl revert
has node ready status check at the beginning of the command.
yurctl revert edgenode
also has node status check. Before node status check, checking the server version and getting node resource are necessary. Does the check time need to be changed?
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 check the node status before conversion/reversion, but the node can still fail when the conversion/reversion is ongoing. To eliminate this, we need to add a CRD/Controller to manage the OpenYurt cluster state, but that can be another new feature. I think we can keep the concurrent implementation just for now.
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.
+1 keep the current implementation
@Peeknut Please merge all commits in this pr(now has 3 commits) into one commit. |
OK! |
pkg/yurtctl/cmd/convert/edgenode.go
Outdated
} | ||
c.PodMainfestPath = podMainfestPath | ||
|
||
c.clientSet, err = kubeutil.GenClientSet(flags) |
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.
if there is no kubeconfig in all flag
, KUBECONFIG
, ~/.kube/config
, it will return err.
@rambohe-ch , how about use /etc/kubernetes/kubelet.conf
if err occurs? kubelet.conf
has enougth authority to set label for current edge node.
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.
+1 for using /etc/kubernetes/kubelet.conf
as the default.
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.
@GsssC how about use InClusterConfig
at the edge node? plus add a serviceaccount and rabc for servant pod.
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.
yurtctl convert/revert edgenode
could be used directly on the single node. In this case, we can't use InClusterConfig
at the edge node because it is not running in a pod environment. Maybe using /etc/kubernetes/kubelet.conf
as the default is better?
@@ -0,0 +1,276 @@ | |||
package convert |
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 OpenSource License : )
/*
Copyright 2021 The OpenYurt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pkg/yurtctl/cmd/convert/edgenode.go
Outdated
} | ||
c.PodMainfestPath = podMainfestPath | ||
|
||
c.clientSet, err = kubeutil.GenClientSet(flags) |
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.
+1 for using /etc/kubernetes/kubelet.conf
as the default.
isEdgeNode, ok := node.Labels[projectinfo.GetEdgeWorkerLabelKey()] | ||
if ok && isEdgeNode == "true" { | ||
// 2.1. check the state of worker nodes | ||
_, condition := nodeutil.GetNodeCondition(&node.Status, v1.NodeReady) |
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 check the node status before conversion/reversion, but the node can still fail when the conversion/reversion is ongoing. To eliminate this, we need to add a CRD/Controller to manage the OpenYurt cluster state, but that can be another new feature. I think we can keep the concurrent implementation just for now.
return content | ||
} | ||
|
||
func GetNodeName() (string, error) { |
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.
using NODE_NAME means we can add the following setting to the pod spec
...
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
...
But yes, I think we should try to get the correct nodename from the service configuration directly, if --hostname-override
can be used to overwrite the nodename.
func NewConvertEdgeNodeCmd() *cobra.Command { | ||
c := NewConvertEdgeNodeOptions() | ||
cmd := &cobra.Command{ | ||
Use: "edgenode", |
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 should specify node name for this subcommand, like yurtctl convert/revert edgenode node-name --xxx=xxx
, so this subcommand can be worked at everywhere with kubeconfig.
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.
And this subcommand can work only on the edge node that user want to convert or revert in current design, I think it's not user-friendly.
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 sub command can need run servant pod to exec convert or revert command.
pkg/yurtctl/cmd/convert/edgenode.go
Outdated
} | ||
} | ||
|
||
// 2.2. check the state of worker nodes |
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.
not check worker nodes here, so how about check the state of EdgeNodes
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.
+1 for EdgeNodes
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.
LGTM
pkg/yurtctl/cmd/convert/edgenode.go
Outdated
} | ||
} | ||
|
||
// 2.2. check the state of worker nodes |
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.
+1 for EdgeNodes
LGTM |
refactor: the node convert/revert feature
Ⅰ. Describe what this PR does
1.Refactor the node convert/revert feature by golang.
2.Add subcommand
yurtctl convert edgenode
andyurtctl revert edgenode
, so that single node could convert/revert Kubernetes edgenode to an Openyurt edgenode.Ⅱ. Does this pull request fix one issue?
fixes #190
Ⅲ. List the added test cases (unit test/integration test) if any, please explain if no tests are needed.
Ⅳ. Describe how to verify it
make test
make build
cp _output/bin/yurtctl /bin/
yurtctl convert
yurtctl revert
yurtctl convert edgenode
yurtctl revert edgenode
Ⅴ. Special notes for reviews