mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
kubeadm: add means to create Node objects via the API client
This commit is contained in:
parent
02469a023f
commit
2dedfddf81
@ -121,7 +121,7 @@ func TestGetKubeConfigSpecs(t *testing.T) {
|
||||
organizations: []string{kubeadmconstants.SystemPrivilegedGroup},
|
||||
},
|
||||
{
|
||||
kubeConfigFile: kubeadmconstants.KubeletKubeConfigFileName,
|
||||
kubeConfigFile: kubeadmconstants.KubeletBootstrapKubeConfigFileName,
|
||||
clientName: fmt.Sprintf("%s%s", kubeadmconstants.NodesUserPrefix, cfg.NodeRegistration.Name),
|
||||
organizations: []string{kubeadmconstants.NodesGroup},
|
||||
},
|
||||
@ -557,8 +557,8 @@ func TestValidateKubeconfigsForExternalCA(t *testing.T) {
|
||||
},
|
||||
"some files don't exist": {
|
||||
filesToWrite: map[string]*clientcmdapi.Config{
|
||||
kubeadmconstants.AdminKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletKubeConfigFileName: config,
|
||||
kubeadmconstants.AdminKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletBootstrapKubeConfigFileName: config,
|
||||
},
|
||||
initConfig: initConfig,
|
||||
expectedError: true,
|
||||
@ -566,7 +566,7 @@ func TestValidateKubeconfigsForExternalCA(t *testing.T) {
|
||||
"some files have invalid CA": {
|
||||
filesToWrite: map[string]*clientcmdapi.Config{
|
||||
kubeadmconstants.AdminKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletBootstrapKubeConfigFileName: config,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: configWithAnotherClusterCa,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: config,
|
||||
},
|
||||
@ -576,7 +576,7 @@ func TestValidateKubeconfigsForExternalCA(t *testing.T) {
|
||||
"some files have invalid Server Url": {
|
||||
filesToWrite: map[string]*clientcmdapi.Config{
|
||||
kubeadmconstants.AdminKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletBootstrapKubeConfigFileName: config,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: config,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: configWithAnotherServerURL,
|
||||
},
|
||||
@ -586,7 +586,7 @@ func TestValidateKubeconfigsForExternalCA(t *testing.T) {
|
||||
"all files are valid": {
|
||||
filesToWrite: map[string]*clientcmdapi.Config{
|
||||
kubeadmconstants.AdminKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletKubeConfigFileName: config,
|
||||
kubeadmconstants.KubeletBootstrapKubeConfigFileName: config,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: config,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: config,
|
||||
},
|
||||
|
@ -29,6 +29,7 @@ go_library(
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -19,14 +19,20 @@ package markcontrolplane
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
)
|
||||
|
||||
// MarkControlPlane taints the control-plane and sets the control-plane label
|
||||
func MarkControlPlane(client clientset.Interface, controlPlaneName string, taints []v1.Taint) error {
|
||||
klog.V(1).Infof("[patchnode] Creating the Node API object %q if missing", controlPlaneName)
|
||||
// See the comments for this function
|
||||
if err := apiclient.EnsureNodeObject(client, controlPlaneName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("[mark-control-plane] Marking the node %s as control-plane by adding the label \"%s=''\"\n", controlPlaneName, constants.LabelNodeRoleMaster)
|
||||
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@ -138,14 +138,9 @@ func TestMarkControlPlane(t *testing.T) {
|
||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if req.URL.Path != "/api/v1/nodes/"+hostname {
|
||||
t.Errorf("MarkControlPlane(%s): request for unexpected HTTP resource: %v", tc.name, req.URL.Path)
|
||||
http.Error(w, "", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
switch req.Method {
|
||||
case "GET":
|
||||
case "POST":
|
||||
case "PATCH":
|
||||
patchRequest = toString(req.Body)
|
||||
default:
|
||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||
package patchnode
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
@ -26,9 +26,12 @@ import (
|
||||
|
||||
// AnnotateCRISocket annotates the node with the given crisocket
|
||||
func AnnotateCRISocket(client clientset.Interface, nodeName string, criSocket string) error {
|
||||
|
||||
klog.V(1).Infof("[patchnode] Uploading the CRI Socket information %q to the Node API object %q as an annotation\n", criSocket, nodeName)
|
||||
|
||||
klog.V(1).Infof("[patchnode] Creating the Node API object %q if missing", nodeName)
|
||||
// See the comments for this function
|
||||
if err := apiclient.EnsureNodeObject(client, nodeName); err != nil {
|
||||
return err
|
||||
}
|
||||
klog.V(1).Infof("[patchnode] Uploading the CRI Socket information %q to the Node API object %q as an annotation", criSocket, nodeName)
|
||||
return apiclient.PatchNode(client, nodeName, func(n *v1.Node) {
|
||||
annotateNodeWithCRISocket(n, criSocket)
|
||||
})
|
||||
|
@ -285,6 +285,29 @@ func PatchNodeOnce(client clientset.Interface, nodeName string, patchFn func(*v1
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureNodeObject creates a Node with the given name if the Node doesn't exist.
|
||||
// Adding a placeholder v1.LabelHostname label makes the object suitable for patching using PatchNodeOnce.
|
||||
//
|
||||
// Currently this function is used to make sure a Node object exists before patching it
|
||||
// during the "kubeadm init" phases. The creation of the Node object is delayed due to TLS boostrap
|
||||
// and instead of waiting for the object, we create it as a placeholder and patch it right away.
|
||||
// Later the same Node object is populated with dynamic values by the kubelet.
|
||||
func EnsureNodeObject(client clientset.Interface, nodeName string) error {
|
||||
node := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: nodeName,
|
||||
Labels: map[string]string{v1.LabelHostname: ""},
|
||||
},
|
||||
}
|
||||
if _, err := client.CoreV1().Nodes().Create(node); err != nil {
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "error creating Node %q", nodeName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PatchNode tries to patch a node using patchFn for the actual mutating logic.
|
||||
// Retries are provided by the wait package.
|
||||
func PatchNode(client clientset.Interface, nodeName string, patchFn func(*v1.Node)) error {
|
||||
|
Loading…
Reference in New Issue
Block a user