Skip to content

Commit

Permalink
Merge pull request #36101 from jbeda/bootstrap-signer
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue (batch tested with PRs 38252, 41122, 36101, 41017, 41264)

BootstrapSigner and TokenCleaner controllers

This is part of kubernetes/enhancements#130 and is an implementation of kubernetes/community#189.

Work that needs to be done yet in this PR:
* [ ] ~~e2e tests~~ Will come in new PR.
* [x] flag to disable this by default

```release-note
Native support for token based bootstrap flow.  This includes signing a well known ConfigMap in the `kube-public` namespace and cleaning out expired tokens.
```

@kubernetes/sig-cluster-lifecycle @dgoodwin @roberthbailey @mikedanese
  • Loading branch information
Kubernetes Submit Queue committed Feb 10, 2017
2 parents d7ae416 + 415e208 commit 866aa73
Show file tree
Hide file tree
Showing 30 changed files with 1,321 additions and 18 deletions.
2 changes: 2 additions & 0 deletions cmd/kube-controller-manager/app/BUILD
Expand Up @@ -14,6 +14,7 @@ go_library(
"apps.go",
"autoscaling.go",
"batch.go",
"bootstrap.go",
"certificates.go",
"controllermanager.go",
"core.go",
Expand Down Expand Up @@ -42,6 +43,7 @@ go_library(
"//pkg/cloudprovider/providers/photon:go_default_library",
"//pkg/cloudprovider/providers/vsphere:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller/bootstrap:go_default_library",
"//pkg/controller/certificates:go_default_library",
"//pkg/controller/cronjob:go_default_library",
"//pkg/controller/daemon:go_default_library",
Expand Down
35 changes: 35 additions & 0 deletions cmd/kube-controller-manager/app/bootstrap.go
@@ -0,0 +1,35 @@
/*
Copyright 2016 The Kubernetes 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.
*/

package app

import "k8s.io/kubernetes/pkg/controller/bootstrap"

func startBootstrapSignerController(ctx ControllerContext) (bool, error) {
go bootstrap.NewBootstrapSigner(
ctx.ClientBuilder.ClientGoClientOrDie("bootstrap-signer"),
bootstrap.DefaultBootstrapSignerOptions(),
).Run(ctx.Stop)
return true, nil
}

func startTokenCleanerController(ctx ControllerContext) (bool, error) {
go bootstrap.NewTokenCleaner(
ctx.ClientBuilder.ClientGoClientOrDie("token-cleaner"),
bootstrap.DefaultTokenCleanerOptions(),
).Run(ctx.Stop)
return true, nil
}
7 changes: 6 additions & 1 deletion cmd/kube-controller-manager/app/controllermanager.go
Expand Up @@ -270,7 +270,10 @@ func KnownControllers() []string {
return sets.StringKeySet(newControllerInitializers()).List()
}

var ControllersDisabledByDefault = sets.NewString()
var ControllersDisabledByDefault = sets.NewString(
"bootstrapsigner",
"tokencleaner",
)

func newControllerInitializers() map[string]InitFunc {
controllers := map[string]InitFunc{}
Expand All @@ -291,6 +294,8 @@ func newControllerInitializers() map[string]InitFunc {
controllers["cronjob"] = startCronJobController
controllers["certificatesigningrequests"] = startCSRController
controllers["ttl"] = startTTLController
controllers["bootstrapsigner"] = startBootstrapSignerController
controllers["tokencleaner"] = startTokenCleanerController

return controllers
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/kubeadm/app/cmd/BUILD
Expand Up @@ -36,6 +36,7 @@ go_library(
"//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//pkg/api:go_default_library",
"//pkg/bootstrap/api:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/util/initsystem:go_default_library",
Expand All @@ -48,6 +49,7 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/net",
"//vendor:k8s.io/apiserver/pkg/util/flag",
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/util/cert",
],
)
Expand Down
5 changes: 3 additions & 2 deletions cmd/kubeadm/app/cmd/token.go
Expand Up @@ -29,11 +29,12 @@ import (

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/pkg/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/api"
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
"k8s.io/kubernetes/pkg/kubectl"
)

Expand Down Expand Up @@ -164,7 +165,7 @@ func RunListTokens(out io.Writer, errW io.Writer, cmd *cobra.Command) error {

tokenSelector := fields.SelectorFromSet(
map[string]string{
api.SecretTypeField: string(api.SecretTypeBootstrapToken),
api.SecretTypeField: string(bootstrapapi.SecretTypeBootstrapToken),
},
)
listOptions := metav1.ListOptions{
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/util/BUILD
Expand Up @@ -21,8 +21,8 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/bootstrap/api:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
Expand Down
6 changes: 4 additions & 2 deletions cmd/kubeadm/app/util/tokens.go
Expand Up @@ -29,8 +29,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
"k8s.io/kubernetes/pkg/api"
v1 "k8s.io/kubernetes/pkg/api/v1"
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
)

Expand Down Expand Up @@ -154,7 +154,9 @@ func UpdateOrCreateToken(client *clientset.Clientset, d *kubeadmapi.TokenDiscove
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
},
Type: api.SecretTypeBootstrapToken,
// TODO(jbeda): convert kubeadm to client-go
// https://github.com/kubernetes/kubeadm/issues/52
Type: v1.SecretType(bootstrapapi.SecretTypeBootstrapToken),
Data: encodeTokenSecretData(d, tokenDuration),
}
if _, err := client.Secrets(metav1.NamespaceSystem).Create(secret); err == nil {
Expand Down
1 change: 1 addition & 0 deletions hack/.linted_packages
Expand Up @@ -87,6 +87,7 @@ pkg/apis/rbac/install
pkg/apis/rbac/v1alpha1
pkg/apis/storage/install
pkg/apis/storage/validation
pkg/bootstrap/api
pkg/client/conditions
pkg/client/informers/informers_generated/apps
pkg/client/informers/informers_generated/apps/internalversion
Expand Down
1 change: 1 addition & 0 deletions pkg/BUILD
Expand Up @@ -31,6 +31,7 @@ filegroup(
"//pkg/apis/storage:all-srcs",
"//pkg/auth/authorizer/abac:all-srcs",
"//pkg/auth/user:all-srcs",
"//pkg/bootstrap/api:all-srcs",
"//pkg/capabilities:all-srcs",
"//pkg/client/chaosclient:all-srcs",
"//pkg/client/clientset_generated/clientset:all-srcs",
Expand Down
5 changes: 2 additions & 3 deletions pkg/api/types.go
Expand Up @@ -189,6 +189,8 @@ const (
NamespaceNone string = ""
// NamespaceSystem is the system namespace where we place system components.
NamespaceSystem string = "kube-system"
// NamespacePublic is the namespace where we place public info (ConfigMaps)
NamespacePublic string = "kube-public"
// TerminationMessagePathDefault means the default path to capture the application termination message running in a container
TerminationMessagePathDefault string = "/dev/termination-log"
)
Expand Down Expand Up @@ -3344,9 +3346,6 @@ const (
// - Secret.Data["token"] - a token that identifies the service account to the API
SecretTypeServiceAccountToken SecretType = "kubernetes.io/service-account-token"

// SecretTypeBootstrapToken is the key for tokens used by kubeadm to validate cluster info during discovery.
SecretTypeBootstrapToken = "bootstrap.kubernetes.io/token"

// ServiceAccountNameKey is the key of the required annotation for SecretTypeServiceAccountToken secrets
ServiceAccountNameKey = "kubernetes.io/service-account.name"
// ServiceAccountUIDKey is the key of the required annotation for SecretTypeServiceAccountToken secrets
Expand Down
31 changes: 31 additions & 0 deletions pkg/bootstrap/api/BUILD
@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])

licenses(["notice"])

load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)

go_library(
name = "go_default_library",
srcs = [
"doc.go",
"types.go",
],
tags = ["automanaged"],
deps = ["//vendor:k8s.io/client-go/pkg/api/v1"],
)

filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)

filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
20 changes: 20 additions & 0 deletions pkg/bootstrap/api/doc.go
@@ -0,0 +1,20 @@
/*
Copyright 2017 The Kubernetes 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.
*/

// Package api (pkg/bootstrap/api) contains constants and types needed for
// bootstrap tokens as maintained by the BootstrapSigner and TokenCleaner
// controllers (in pkg/controller/bootstrap)
package api // import "k8s.io/kubernetes/pkg/bootstrap/api"
48 changes: 48 additions & 0 deletions pkg/bootstrap/api/types.go
@@ -0,0 +1,48 @@
/*
Copyright 2017 The Kubernetes 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.
*/

package api

import (
"k8s.io/client-go/pkg/api/v1"
)

const (
// SecretTypeBootstrapToken is used during the automated bootstrap process (first
// implemented by kubeadm). It stores tokens that are used to sign well known
// ConfigMaps. They may also eventually be used for authentication.
SecretTypeBootstrapToken v1.SecretType = "bootstrap.kubernetes.io/token"

// BootstrapTokenIDKey is the id of this token. This can be transmitted in the
// clear and encoded in the name of the secret. It should be a random 6
// character string. Required
BootstrapTokenIDKey = "token-id"

// BootstrapTokenSecretKey is the actual secret. Typically this is a random 16
// character string. Required.
BootstrapTokenSecretKey = "token-secret"

// BootstrapTokenExpirationKey is when this token should be expired and no
// longer used. A controller will delete this resource after this time. This
// is an absolute UTC time using RFC3339. If this cannot be parsed, the token
// should be considered invalid. Optional.
BootstrapTokenExpirationKey = "expiration"

// BootstrapTokenUsageSigningKey signals that this token should be used to
// sign configs as part of the bootstrap process. Value must be "true". Any
// other value is assumed to be false. Optional.
BootstrapTokenUsageSigningKey = "usage-bootstrap-signing"
)
1 change: 1 addition & 0 deletions pkg/controller/BUILD
Expand Up @@ -84,6 +84,7 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/controller/bootstrap:all-srcs",
"//pkg/controller/certificates:all-srcs",
"//pkg/controller/cloud:all-srcs",
"//pkg/controller/cronjob:all-srcs",
Expand Down
75 changes: 75 additions & 0 deletions pkg/controller/bootstrap/BUILD
@@ -0,0 +1,75 @@
package(default_visibility = ["//visibility:public"])

licenses(["notice"])

load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)

go_test(
name = "go_default_test",
srcs = [
"bootstrapsigner_test.go",
"common_test.go",
"jws_test.go",
"tokencleaner_test.go",
"util_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/bootstrap/api:go_default_library",
"//vendor:github.com/davecgh/go-spew/spew",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/client-go/kubernetes/fake",
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/testing",
],
)

go_library(
name = "go_default_library",
srcs = [
"bootstrapsigner.go",
"doc.go",
"jws.go",
"tokencleaner.go",
"util.go",
],
tags = ["automanaged"],
deps = [
"//pkg/bootstrap/api:go_default_library",
"//pkg/util/metrics:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/square/go-jose",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/fields",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/client-go/kubernetes",
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/util/workqueue",
],
)

filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)

filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

0 comments on commit 866aa73

Please sign in to comment.