Skip to content

Commit da1711d

Browse files
Merge pull request #18508 from deads2k/controller-04-satoken
Automatic merge from submit-queue (batch tested with PRs 18591, 18508). use the upstream SA token controller This patches in our service serving cert CA initialization in the upstream SA token controller when requested. This makes it easier to run the upstream controllers in 3.10 and doing it in 3.9 makes for a smooth transition on the leases.
2 parents 4a908e0 + cedcafd commit da1711d

File tree

8 files changed

+116
-143
lines changed

8 files changed

+116
-143
lines changed

pkg/cmd/server/origin/controller/config.go

-60
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
package controller
22

33
import (
4-
"fmt"
5-
"io/ioutil"
64
"path"
75
"time"
86

97
"k8s.io/apimachinery/pkg/runtime/schema"
10-
"k8s.io/client-go/util/cert"
118
"k8s.io/kubernetes/pkg/api/legacyscheme"
129
kapi "k8s.io/kubernetes/pkg/apis/core"
13-
kcontroller "k8s.io/kubernetes/pkg/controller"
1410
serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
1511

1612
configapi "github.com/openshift/origin/pkg/cmd/server/apis/config"
17-
"github.com/openshift/origin/pkg/cmd/server/crypto"
1813
"github.com/openshift/origin/pkg/cmd/util/variable"
1914
)
2015

@@ -56,8 +51,6 @@ func getOpenShiftClientEnvVars(options configapi.MasterConfig) ([]kapi.EnvVar, e
5651
// OpenshiftControllerConfig is the runtime (non-serializable) config object used to
5752
// launch the set of openshift (not kube) controllers.
5853
type OpenshiftControllerConfig struct {
59-
ServiceAccountTokenControllerOptions ServiceAccountTokenControllerOptions
60-
6154
ServiceAccountControllerOptions ServiceAccountControllerOptions
6255

6356
BuildControllerConfig BuildControllerConfig
@@ -115,63 +108,10 @@ func (c *OpenshiftControllerConfig) GetControllerInitializers() (map[string]Init
115108
return ret, nil
116109
}
117110

118-
// NewOpenShiftControllerPreStartInitializers returns list of initializers for controllers
119-
// that needed to be run before any other controller is started.
120-
// Typically this has to done for the serviceaccount-token controller as it provides
121-
// tokens to other controllers.
122-
func (c *OpenshiftControllerConfig) ServiceAccountContentControllerInit() InitFunc {
123-
return c.ServiceAccountTokenControllerOptions.RunController
124-
}
125-
126111
func BuildOpenshiftControllerConfig(options configapi.MasterConfig) (*OpenshiftControllerConfig, error) {
127112
var err error
128113
ret := &OpenshiftControllerConfig{}
129114

130-
_, loopbackClientConfig, err := configapi.GetInternalKubeClient(options.MasterClients.OpenShiftLoopbackKubeConfig, options.MasterClients.OpenShiftLoopbackClientConnectionOverrides)
131-
if err != nil {
132-
return nil, err
133-
}
134-
135-
ret.ServiceAccountTokenControllerOptions = ServiceAccountTokenControllerOptions{
136-
RootClientBuilder: kcontroller.SimpleControllerClientBuilder{
137-
ClientConfig: loopbackClientConfig,
138-
},
139-
}
140-
if len(options.ServiceAccountConfig.PrivateKeyFile) > 0 {
141-
ret.ServiceAccountTokenControllerOptions.PrivateKey, err = cert.PrivateKeyFromFile(options.ServiceAccountConfig.PrivateKeyFile)
142-
if err != nil {
143-
return nil, fmt.Errorf("error reading signing key for Service Account Token Manager: %v", err)
144-
}
145-
}
146-
if len(options.ServiceAccountConfig.MasterCA) > 0 {
147-
ret.ServiceAccountTokenControllerOptions.RootCA, err = ioutil.ReadFile(options.ServiceAccountConfig.MasterCA)
148-
if err != nil {
149-
return nil, fmt.Errorf("error reading master ca file for Service Account Token Manager: %s: %v", options.ServiceAccountConfig.MasterCA, err)
150-
}
151-
if _, err := cert.ParseCertsPEM(ret.ServiceAccountTokenControllerOptions.RootCA); err != nil {
152-
return nil, fmt.Errorf("error parsing master ca file for Service Account Token Manager: %s: %v", options.ServiceAccountConfig.MasterCA, err)
153-
}
154-
}
155-
if options.ControllerConfig.ServiceServingCert.Signer != nil && len(options.ControllerConfig.ServiceServingCert.Signer.CertFile) > 0 {
156-
certFile := options.ControllerConfig.ServiceServingCert.Signer.CertFile
157-
serviceServingCA, err := ioutil.ReadFile(certFile)
158-
if err != nil {
159-
return nil, fmt.Errorf("error reading ca file for Service Serving Certificate Signer: %s: %v", certFile, err)
160-
}
161-
if _, err := crypto.CertsFromPEM(serviceServingCA); err != nil {
162-
return nil, fmt.Errorf("error parsing ca file for Service Serving Certificate Signer: %s: %v", certFile, err)
163-
}
164-
165-
// if we have a rootCA bundle add that too. The rootCA will be used when hitting the default master service, since those are signed
166-
// using a different CA by default. The rootCA's key is more closely guarded than ours and if it is compromised, that power could
167-
// be used to change the trusted signers for every pod anyway, so we're already effectively trusting it.
168-
if len(ret.ServiceAccountTokenControllerOptions.RootCA) > 0 {
169-
ret.ServiceAccountTokenControllerOptions.ServiceServingCA = append(ret.ServiceAccountTokenControllerOptions.ServiceServingCA, ret.ServiceAccountTokenControllerOptions.RootCA...)
170-
ret.ServiceAccountTokenControllerOptions.ServiceServingCA = append(ret.ServiceAccountTokenControllerOptions.ServiceServingCA, []byte("\n")...)
171-
}
172-
ret.ServiceAccountTokenControllerOptions.ServiceServingCA = append(ret.ServiceAccountTokenControllerOptions.ServiceServingCA, serviceServingCA...)
173-
}
174-
175115
ret.ServiceAccountControllerOptions = ServiceAccountControllerOptions{
176116
ManagedNames: options.ServiceAccountConfig.ManagedNames,
177117
}

pkg/cmd/server/origin/controller/serviceaccount.go

-33
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import (
44
"github.com/golang/glog"
55

66
kapiv1 "k8s.io/api/core/v1"
7-
"k8s.io/kubernetes/pkg/controller"
87
sacontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
9-
"k8s.io/kubernetes/pkg/serviceaccount"
108

119
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
1210
serviceaccountcontrollers "github.com/openshift/origin/pkg/serviceaccounts/controllers"
@@ -49,37 +47,6 @@ func (c *ServiceAccountControllerOptions) RunController(ctx ControllerContext) (
4947
return true, nil
5048
}
5149

52-
type ServiceAccountTokenControllerOptions struct {
53-
RootCA []byte
54-
ServiceServingCA []byte
55-
PrivateKey interface{}
56-
57-
RootClientBuilder controller.SimpleControllerClientBuilder
58-
}
59-
60-
func (c *ServiceAccountTokenControllerOptions) RunController(ctx ControllerContext) (bool, error) {
61-
if c.PrivateKey == nil {
62-
glog.Infof("Skipped starting Service Account Token Manager, no private key specified")
63-
return false, nil
64-
}
65-
66-
controller, err := sacontroller.NewTokensController(
67-
ctx.ExternalKubeInformers.Core().V1().ServiceAccounts(),
68-
ctx.ExternalKubeInformers.Core().V1().Secrets(),
69-
c.RootClientBuilder.ClientOrDie(bootstrappolicy.InfraServiceAccountTokensControllerServiceAccountName),
70-
sacontroller.TokensControllerOptions{
71-
TokenGenerator: serviceaccount.JWTTokenGenerator(c.PrivateKey),
72-
RootCA: c.RootCA,
73-
ServiceServingCA: c.ServiceServingCA,
74-
},
75-
)
76-
if err != nil {
77-
return true, nil
78-
}
79-
go controller.Run(int(ctx.OpenshiftControllerOptions.ServiceAccountTokenOptions.ConcurrentSyncs), ctx.Stop)
80-
return true, nil
81-
}
82-
8350
func RunServiceAccountPullSecretsController(ctx ControllerContext) (bool, error) {
8451
kc := ctx.ClientBuilder.ClientOrDie(bootstrappolicy.InfraServiceAccountPullSecretsControllerServiceAccountName)
8552

pkg/cmd/server/start/start_kube_controller_manager.go

-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ func computeKubeControllerManagerArgs(kubeconfigFile, saPrivateKeyFile, saRootCA
2121
"-tokencleaner",
2222
// we have to configure this separately until it is generic
2323
"-horizontalpodautoscaling",
24-
// we carry patches on this. For now....
25-
"-serviceaccount-token",
2624
}
2725
}
2826
if _, ok := cmdLineArgs["service-account-private-key-file"]; !ok {

pkg/cmd/server/start/start_master.go

+23-45
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import (
66
"io"
77
"io/ioutil"
88
"net"
9-
"net/http"
109
"os"
1110
"path"
1211
"path/filepath"
1312
"strings"
14-
"time"
1513

1614
"github.com/coreos/go-systemd/daemon"
1715
"github.com/golang/glog"
@@ -21,7 +19,6 @@ import (
2119

2220
kerrors "k8s.io/apimachinery/pkg/api/errors"
2321
"k8s.io/apimachinery/pkg/util/sets"
24-
"k8s.io/apimachinery/pkg/util/wait"
2522
utilwait "k8s.io/apimachinery/pkg/util/wait"
2623
clientgoclientset "k8s.io/client-go/kubernetes"
2724
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -431,19 +428,34 @@ func (m *Master) Start() error {
431428
go runEmbeddedScheduler(m.config.MasterClients.OpenShiftLoopbackKubeConfig, m.config.KubernetesMasterConfig.SchedulerConfigFile, m.config.KubernetesMasterConfig.SchedulerArguments)
432429

433430
go func() {
434-
kubeControllerConfigBytes, err := configapilatest.WriteYAML(m.config)
431+
kubeControllerConfigShallowCopy := *m.config
432+
// this creates using 0700
433+
kubeControllerConfigDir, err := ioutil.TempDir("", "openshift-kube-controller-manager-config-")
435434
if err != nil {
436435
glog.Fatal(err)
437436
}
438-
// this creates using 0600
439-
kubeControllerConfigFile, err := ioutil.TempFile("", "openshift-kube-controler-manager-config.yaml")
437+
defer func() {
438+
os.RemoveAll(kubeControllerConfigDir)
439+
}()
440+
if m.config.ControllerConfig.ServiceServingCert.Signer != nil && len(m.config.ControllerConfig.ServiceServingCert.Signer.CertFile) > 0 {
441+
caBytes, err := ioutil.ReadFile(m.config.ControllerConfig.ServiceServingCert.Signer.CertFile)
442+
if err != nil {
443+
glog.Fatal(err)
444+
}
445+
serviceServingCertSignerCAFile := path.Join(kubeControllerConfigDir, "service-signer.crt")
446+
if err := ioutil.WriteFile(serviceServingCertSignerCAFile, caBytes, 0644); err != nil {
447+
glog.Fatal(err)
448+
}
449+
450+
// we need to tweak the master config file with a relative ref, but to do that we need to copy it
451+
kubeControllerConfigShallowCopy.ControllerConfig.ServiceServingCert.Signer = &configapi.CertInfo{CertFile: "service-signer.crt"}
452+
}
453+
kubeControllerConfigBytes, err := configapilatest.WriteYAML(&kubeControllerConfigShallowCopy)
440454
if err != nil {
441455
glog.Fatal(err)
442456
}
443-
defer func() {
444-
os.Remove(kubeControllerConfigFile.Name())
445-
}()
446-
if err := ioutil.WriteFile(kubeControllerConfigFile.Name(), kubeControllerConfigBytes, 0644); err != nil {
457+
masterConfigFile := path.Join(kubeControllerConfigDir, "master-config.yaml")
458+
if err := ioutil.WriteFile(masterConfigFile, kubeControllerConfigBytes, 0644); err != nil {
447459
glog.Fatal(err)
448460
}
449461

@@ -452,7 +464,7 @@ func (m *Master) Start() error {
452464
m.config.ServiceAccountConfig.PrivateKeyFile,
453465
m.config.ServiceAccountConfig.MasterCA,
454466
m.config.KubernetesMasterConfig.PodEvictionTimeout,
455-
kubeControllerConfigFile.Name(),
467+
masterConfigFile,
456468
m.config.VolumeConfig.DynamicProvisioningEnabled,
457469
)
458470
}()
@@ -602,40 +614,6 @@ func startControllers(options configapi.MasterConfig, allocationController origi
602614
return err
603615
}
604616

605-
// We need to start the serviceaccount-tokens controller first as it provides token
606-
// generation for other controllers.
607-
startSATokenController := openshiftControllerConfig.ServiceAccountContentControllerInit()
608-
if enabled, err := startSATokenController(controllerContext); err != nil {
609-
return fmt.Errorf("Error starting serviceaccount-token controller: %v", err)
610-
} else if !enabled {
611-
glog.Warningf("Skipping serviceaccount-token controller")
612-
} else {
613-
glog.Infof("Started serviceaccount-token controller")
614-
}
615-
616-
// The service account controllers require informers in order to create service account tokens
617-
// for other controllers, which means we need to start their informers (which use the privileged
618-
// loopback client) before the other controllers will run.
619-
controllerContext.ExternalKubeInformers.Start(controllerContext.Stop)
620-
621-
// right now we have controllers which are relying on the ability to make requests before the bootstrap policy is in place
622-
// In 3.7, we will be fixed by the post start hook that prevents readiness unless policy is in place
623-
// for 3.6, just make sure we don't proceed until the garbage collector can hit discovery
624-
// wait for bootstrap permissions to be established. This check isn't perfect, but it ensures that at least the controllers checking discovery can succeed
625-
gcClientset := controllerContext.ClientBuilder.ClientOrDie("generic-garbage-collector")
626-
err = wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
627-
result := gcClientset.Discovery().RESTClient().Get().AbsPath("/apis").Do()
628-
var statusCode int
629-
result.StatusCode(&statusCode)
630-
if statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices {
631-
return true, nil
632-
}
633-
return false, nil
634-
})
635-
if err != nil {
636-
return err
637-
}
638-
639617
// the service account passed for the recyclable volume plugins needs to exist. We want to do this via the init function, but its a kube init function
640618
// for the rebase, create that service account here
641619
// TODO make this a lot cleaner

test/util/server/server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ func StartConfiguredMasterAPI(masterConfig *configapi.MasterConfig) (string, err
424424
if masterConfig.KubernetesMasterConfig.ControllerArguments == nil {
425425
masterConfig.KubernetesMasterConfig.ControllerArguments = map[string][]string{}
426426
}
427-
masterConfig.KubernetesMasterConfig.ControllerArguments["controllers"] = append(masterConfig.KubernetesMasterConfig.ControllerArguments["controllers"], "clusterrole-aggregation")
427+
masterConfig.KubernetesMasterConfig.ControllerArguments["controllers"] = append(masterConfig.KubernetesMasterConfig.ControllerArguments["controllers"], "serviceaccount-token", "clusterrole-aggregation")
428428

429429
return StartConfiguredMasterWithOptions(masterConfig)
430430
}

vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/patch.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/patch_satoken.go

+83
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)