Skip to content

Commit

Permalink
add yurtadm join node in specified nodepool
Browse files Browse the repository at this point in the history
  • Loading branch information
JameKeal committed Apr 21, 2023
1 parent 4356d43 commit 19b7c4e
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 1 deletion.
3 changes: 3 additions & 0 deletions charts/openyurt/templates/yurthub-staticpod.yaml
Expand Up @@ -48,6 +48,9 @@ spec:
{{`{{if .organizations }}`}}
- --hub-cert-organizations={{`{{.organizations}}`}}
{{`{{end}}`}}
{{`{{if .nodePoolName }}`}}
- --nodepool-name={{`{{.nodePoolName}}`}}
{{`{{end}}`}}
livenessProbe:
httpGet:
host: {{ .Values.yurtHub.yurthubServerAddr | quote }}
Expand Down
17 changes: 17 additions & 0 deletions pkg/util/kubeconfig/kubeconfig.go
Expand Up @@ -24,6 +24,8 @@ import (
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

yurtclientset "github.com/openyurtio/yurt-app-manager-api/pkg/yurtappmanager/client/clientset/versioned"
)

// CreateBasic creates a basic, general KubeConfig object that then can be extended
Expand Down Expand Up @@ -125,3 +127,18 @@ func GetAuthInfoFromKubeConfig(config *clientcmdapi.Config) *clientcmdapi.AuthIn
}
return nil
}

// ToYurtClientSet converts a KubeConfig object to a yurtClient
func ToYurtClientSet(config *clientcmdapi.Config) (yurtclientset.Interface, error) {
overrides := clientcmd.ConfigOverrides{Timeout: "10s"}
clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &overrides).ClientConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to create yurt client configuration from kubeconfig")
}

Check warning on line 137 in pkg/util/kubeconfig/kubeconfig.go

View check run for this annotation

Codecov / codecov/patch

pkg/util/kubeconfig/kubeconfig.go#L132-L137

Added lines #L132 - L137 were not covered by tests

client, err := yurtclientset.NewForConfig(clientConfig)
if err != nil {
return nil, errors.Wrap(err, "failed to create yurt client")
}
return client, nil

Check warning on line 143 in pkg/util/kubeconfig/kubeconfig.go

View check run for this annotation

Codecov / codecov/patch

pkg/util/kubeconfig/kubeconfig.go#L139-L143

Added lines #L139 - L143 were not covered by tests
}
48 changes: 48 additions & 0 deletions pkg/util/kubernetes/kubeadm/app/util/apiclient/idempotency.go
Expand Up @@ -29,6 +29,8 @@ import (
clientsetretry "k8s.io/client-go/util/retry"

"github.com/openyurtio/openyurt/pkg/util/kubernetes/kubeadm/app/constants"
nodepoolv1alpha1 "github.com/openyurtio/yurt-app-manager-api/pkg/yurtappmanager/apis/apps/v1alpha1"
yurtclientset "github.com/openyurtio/yurt-app-manager-api/pkg/yurtappmanager/client/clientset/versioned"
)

// ConfigMapMutator is a function that mutates the given ConfigMap and optionally returns an error
Expand Down Expand Up @@ -131,3 +133,49 @@ func GetConfigMapWithRetry(client clientset.Interface, namespace, name string) (
}
return nil, lastError
}

func GetNodePoolInfoWithRetry(client yurtclientset.Interface, name string) (*nodepoolv1alpha1.NodePool, error) {
var np *nodepoolv1alpha1.NodePool
var lastError error
err := wait.ExponentialBackoff(clientsetretry.DefaultBackoff, func() (bool, error) {
var err error
np, err = client.AppsV1alpha1().NodePools().Get(context.TODO(), name, metav1.GetOptions{})
if err == nil {
return true, nil
}
if apierrors.IsNotFound(err) {
return true, nil
}
lastError = err
return false, nil
})
if err == nil {
return np, nil
}
return nil, lastError
}

func JoinNodeInSpecifiedNodePool(client clientset.Interface, nodeName, nodePoolName string) error {
var node *v1.Node
var lastError error
err := wait.ExponentialBackoff(clientsetretry.DefaultBackoff, func() (bool, error) {
var err error
node, err = client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
if err != nil {
lastError = err
return false, nil
}

node.Labels[nodepoolv1alpha1.LabelDesiredNodePool] = nodePoolName
_, err = client.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{})
if err != nil {
lastError = err
return false, nil
}
return true, nil
})
if err == nil {
return nil
}
return lastError
}
22 changes: 22 additions & 0 deletions pkg/yurtadm/cmd/join/join.go
Expand Up @@ -31,6 +31,7 @@ import (
"k8s.io/klog/v2"

kubeconfigutil "github.com/openyurtio/openyurt/pkg/util/kubeconfig"
"github.com/openyurtio/openyurt/pkg/util/kubernetes/kubeadm/app/util/apiclient"
"github.com/openyurtio/openyurt/pkg/yurtadm/cmd/join/joindata"
yurtphases "github.com/openyurtio/openyurt/pkg/yurtadm/cmd/join/phases"
yurtconstants "github.com/openyurtio/openyurt/pkg/yurtadm/constants"
Expand All @@ -42,6 +43,7 @@ type joinOptions struct {
token string
nodeType string
nodeName string
nodePoolName string
criSocket string
organizations string
pauseImage string
Expand Down Expand Up @@ -124,6 +126,10 @@ func addJoinConfigFlags(flagSet *flag.FlagSet, joinOptions *joinOptions) {
&joinOptions.namespace, yurtconstants.Namespace, joinOptions.namespace,
`Specify the namespace of the yurthub staticpod configmap, if not specified, the namespace will be default.`,
)
flagSet.StringVar(
&joinOptions.nodePoolName, yurtconstants.NodePoolName, joinOptions.nodePoolName,
`Specify the nodePool name. if specified, that will add node into specified nodePool.`,
)
flagSet.StringVar(
&joinOptions.criSocket, yurtconstants.NodeCRISocket, joinOptions.criSocket,
"Path to the CRI socket to connect",
Expand Down Expand Up @@ -273,6 +279,7 @@ func newJoinData(args []string, opt *joinOptions) (*joinData, error) {
nodeLabels: make(map[string]string),
joinNodeData: &joindata.NodeRegistration{
Name: name,
NodePoolName: opt.nodePoolName,

Check warning on line 282 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L282

Added line #L282 was not covered by tests
WorkingMode: opt.nodeType,
CRISocket: opt.criSocket,
Organizations: opt.organizations,
Expand Down Expand Up @@ -316,6 +323,21 @@ func newJoinData(args []string, opt *joinOptions) (*joinData, error) {
return nil, err
}
data.kubernetesVersion = k8sVersion

// check whether specified nodePool exists
if len(opt.nodePoolName) != 0 {
yurtClient, err := kubeconfigutil.ToYurtClientSet(cfg)
if err != nil {
klog.Errorf("failed to create yurt client, %v", err)
return nil, err
}

Check warning on line 333 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L326-L333

Added lines #L326 - L333 were not covered by tests

np, err := apiclient.GetNodePoolInfoWithRetry(yurtClient, opt.nodePoolName)
if err != nil || np == nil {
// the specified nodePool not exist, return
return nil, errors.Errorf("when --nodepool-name is specified, the specified nodePool should be exist.")
}

Check warning on line 339 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L335-L339

Added lines #L335 - L339 were not covered by tests
}
klog.Infof("node join data info: %#+v", *data)

// get the yurthub template from the staticpod cr
Expand Down
1 change: 1 addition & 0 deletions pkg/yurtadm/cmd/join/joindata/data.go
Expand Up @@ -24,6 +24,7 @@ import (

type NodeRegistration struct {
Name string
NodePoolName string
CRISocket string
WorkingMode string
Organizations string
Expand Down
13 changes: 12 additions & 1 deletion pkg/yurtadm/cmd/join/phases/postcheck.go
Expand Up @@ -19,12 +19,14 @@ package phases
import (
"k8s.io/klog/v2"

"github.com/openyurtio/openyurt/pkg/util/kubernetes/kubeadm/app/util/apiclient"
"github.com/openyurtio/openyurt/pkg/yurtadm/cmd/join/joindata"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/kubernetes"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/yurthub"
)

// RunPostCheck executes the node health check and clean process.
// RunPostCheck executes the node health check and clean process,
// if specified nodePool, it will join node in specified nodePool.
func RunPostCheck(data joindata.YurtJoinData) error {
klog.V(1).Infof("check kubelet status.")
if err := kubernetes.CheckKubeletStatus(); err != nil {
Expand All @@ -38,6 +40,15 @@ func RunPostCheck(data joindata.YurtJoinData) error {
}
klog.V(1).Infof("hub agent is ready")

if len(data.NodeRegistration().NodePoolName) != 0 {
klog.V(1).Infof("starting join node in specified nodePool.")
if err := apiclient.JoinNodeInSpecifiedNodePool(data.BootstrapClient(),
data.NodeRegistration().Name, data.NodeRegistration().NodePoolName); err != nil {
return err
}
klog.V(1).Infof("join node in specified nodePool successful.")
}

if err := yurthub.CleanHubBootstrapConfig(); err != nil {
return err
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/yurtadm/constants/constants.go
Expand Up @@ -83,6 +83,8 @@ const (
NodeLabels = "node-labels"
// NodeName flag sets the node name.
NodeName = "node-name"
// NodePoolName flag sets the nodePool name.
NodePoolName = "nodepool-name"
// NodeType flag sets the type of worker node to edge or cloud.
NodeType = "node-type"
// Organizations flag sets the extra organizations of hub agent client certificate.
Expand Down Expand Up @@ -237,6 +239,9 @@ spec:
{{if .organizations }}
- --hub-cert-organizations={{.organizations}}
{{end}}
{{if .nodePoolName }}
- --nodepool-name={{.nodePoolName}}
{{end}}
livenessProbe:
httpGet:
host: {{.yurthubServerAddr}}
Expand Down
3 changes: 3 additions & 0 deletions pkg/yurtadm/util/yurthub/yurthub.go
Expand Up @@ -64,6 +64,9 @@ func AddYurthubStaticYaml(data joindata.YurtJoinData, podManifestPath string) er
"workingMode": data.NodeRegistration().WorkingMode,
"organizations": data.NodeRegistration().Organizations,
}
if len(data.NodeRegistration().NodePoolName) != 0 {
ctx["nodePoolName"] = data.NodeRegistration().NodePoolName
}

yurthubTemplate, err := templates.SubsituteTemplate(data.YurtHubTemplate(), ctx)
if err != nil {
Expand Down

0 comments on commit 19b7c4e

Please sign in to comment.