mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #108002 from SataQiu/fix-dryrun-20220208
kubeadm: fix the bug that 'kubeadm init --dry-run --upload-certs' command failed with 'secret not found' error
This commit is contained in:
commit
3ba7d48093
@ -25,11 +25,14 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
|
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||||
|
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
@ -162,7 +165,19 @@ func NewDryRunClientWithOpts(opts DryRunClientOptions) clientset.Interface {
|
|||||||
&core.SimpleReactor{
|
&core.SimpleReactor{
|
||||||
Verb: "create",
|
Verb: "create",
|
||||||
Resource: "*",
|
Resource: "*",
|
||||||
Reaction: successfulModificationReactorFunc,
|
Reaction: func(action core.Action) (bool, runtime.Object, error) {
|
||||||
|
objAction, ok := action.(actionWithObject)
|
||||||
|
if obj := objAction.GetObject(); ok && obj != nil {
|
||||||
|
if secret, ok := obj.(*v1.Secret); ok {
|
||||||
|
if secret.Namespace == metav1.NamespaceSystem && strings.HasPrefix(secret.Name, bootstrapapi.BootstrapTokenSecretPrefix) {
|
||||||
|
// bypass bootstrap token secret create event so that it can be persisted to the backing data store
|
||||||
|
// this secret should be readable during the uploadcerts init phase if it has already been created
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return successfulModificationReactorFunc(action)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&core.SimpleReactor{
|
&core.SimpleReactor{
|
||||||
Verb: "update",
|
Verb: "update",
|
||||||
|
@ -17,8 +17,6 @@ limitations under the License.
|
|||||||
package apiclient
|
package apiclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
@ -36,7 +34,6 @@ import (
|
|||||||
// Need to handle these routes in a special manner:
|
// Need to handle these routes in a special manner:
|
||||||
// - GET /default/services/kubernetes -- must return a valid Service
|
// - GET /default/services/kubernetes -- must return a valid Service
|
||||||
// - GET /clusterrolebindings/system:nodes -- can safely return a NotFound error
|
// - GET /clusterrolebindings/system:nodes -- can safely return a NotFound error
|
||||||
// - GET /kube-system/secrets/bootstrap-token-* -- can safely return a NotFound error
|
|
||||||
// - GET /nodes/<node-name> -- must return a valid Node
|
// - GET /nodes/<node-name> -- must return a valid Node
|
||||||
// - ...all other, unknown GETs/LISTs will be logged
|
// - ...all other, unknown GETs/LISTs will be logged
|
||||||
type InitDryRunGetter struct {
|
type InitDryRunGetter struct {
|
||||||
@ -61,7 +58,6 @@ func (idr *InitDryRunGetter) HandleGetAction(action core.GetAction) (bool, runti
|
|||||||
idr.handleKubernetesService,
|
idr.handleKubernetesService,
|
||||||
idr.handleGetNode,
|
idr.handleGetNode,
|
||||||
idr.handleSystemNodesClusterRoleBinding,
|
idr.handleSystemNodesClusterRoleBinding,
|
||||||
idr.handleGetBootstrapToken,
|
|
||||||
}
|
}
|
||||||
for _, f := range funcs {
|
for _, f := range funcs {
|
||||||
handled, obj, err := f(action)
|
handled, obj, err := f(action)
|
||||||
@ -148,14 +144,3 @@ func (idr *InitDryRunGetter) handleSystemNodesClusterRoleBinding(action core.Get
|
|||||||
// This can only happen on an upgrade; and in that case the ClientBackedDryRunGetter impl will be used
|
// This can only happen on an upgrade; and in that case the ClientBackedDryRunGetter impl will be used
|
||||||
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), "clusterrolebinding not found")
|
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), "clusterrolebinding not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetBootstrapToken handles the case where kubeadm init creates the default token; and the token code GETs the
|
|
||||||
// bootstrap token secret first in order to check if it already exists
|
|
||||||
func (idr *InitDryRunGetter) handleGetBootstrapToken(action core.GetAction) (bool, runtime.Object, error) {
|
|
||||||
if !strings.HasPrefix(action.GetName(), "bootstrap-token-") || action.GetNamespace() != metav1.NamespaceSystem || action.GetResource().Resource != "secrets" {
|
|
||||||
// We can't handle this event
|
|
||||||
return false, nil, nil
|
|
||||||
}
|
|
||||||
// We can safely return a NotFound error here as the code will just proceed normally and create the Bootstrap Token
|
|
||||||
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), "secret not found")
|
|
||||||
}
|
|
||||||
|
@ -59,13 +59,6 @@ func TestHandleGetAction(t *testing.T) {
|
|||||||
expectedObjectJSON: []byte(``),
|
expectedObjectJSON: []byte(``),
|
||||||
expectedErr: true, // we expect a NotFound error here
|
expectedErr: true, // we expect a NotFound error here
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "get kube-system secret bootstrap-token-abcdef",
|
|
||||||
action: core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, "kube-system", "bootstrap-token-abcdef"),
|
|
||||||
expectedHandled: true,
|
|
||||||
expectedObjectJSON: []byte(``),
|
|
||||||
expectedErr: true, // we expect a NotFound error here
|
|
||||||
},
|
|
||||||
{ // an ask for a kubernetes service in the _kube-system_ ns should not be answered
|
{ // an ask for a kubernetes service in the _kube-system_ ns should not be answered
|
||||||
name: "get kube-system services",
|
name: "get kube-system services",
|
||||||
action: core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "services"}, "kube-system", "kubernetes"),
|
action: core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "services"}, "kube-system", "kubernetes"),
|
||||||
@ -87,13 +80,6 @@ func TestHandleGetAction(t *testing.T) {
|
|||||||
expectedObjectJSON: []byte(``),
|
expectedObjectJSON: []byte(``),
|
||||||
expectedErr: false,
|
expectedErr: false,
|
||||||
},
|
},
|
||||||
{ // an ask for a secret in any other ns than kube-system should not be answered
|
|
||||||
name: "get default secret bootstrap-token-abcdef",
|
|
||||||
action: core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, "default", "bootstrap-token-abcdef"),
|
|
||||||
expectedHandled: false,
|
|
||||||
expectedObjectJSON: []byte(``),
|
|
||||||
expectedErr: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user