mirror of https://github.com/k3s-io/k3s
add ca to token controller and all service accounts
parent
befe545033
commit
56bde3342a
|
@ -28,7 +28,13 @@
|
|||
{% endif -%}
|
||||
{% endif -%}
|
||||
|
||||
{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + cloud_provider + " " + cloud_config + service_account_key + pillar['log_level'] -%}
|
||||
{% set root_ca_file = "" -%}
|
||||
|
||||
{% if grains['cloud'] is defined and grains.cloud in [ 'aws', 'gce' ] %}
|
||||
{% set root_ca_file = "--root_ca_file=/srv/kubernetes/ca.crt" -%}
|
||||
{% endif -%}
|
||||
|
||||
{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + cloud_provider + " " + cloud_config + service_account_key + pillar['log_level'] + " " + root_ca_file -%}
|
||||
|
||||
{
|
||||
"apiVersion": "v1beta3",
|
||||
|
|
|
@ -23,6 +23,8 @@ limitations under the License.
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
|
@ -73,6 +75,7 @@ type CMServer struct {
|
|||
DeletingPodsQps float32
|
||||
DeletingPodsBurst int
|
||||
ServiceAccountKeyFile string
|
||||
RootCAFile string
|
||||
|
||||
ClusterName string
|
||||
ClusterCIDR util.IPNet
|
||||
|
@ -156,6 +159,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.")
|
||||
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
|
||||
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
||||
fs.StringVar(&s.RootCAFile, "root-ca-file", s.RootCAFile, "If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle.")
|
||||
}
|
||||
|
||||
// Run runs the CMServer. This should never exit.
|
||||
|
@ -243,6 +247,20 @@ func (s *CMServer) Run(_ []string) error {
|
|||
}
|
||||
pvRecycler.Run()
|
||||
|
||||
var rootCA []byte
|
||||
|
||||
if s.RootCAFile != "" {
|
||||
rootCA, err := ioutil.ReadFile(s.RootCAFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading root-ca-file at %s: %v", s.RootCAFile, err)
|
||||
}
|
||||
if _, err := util.CertsFromPEM(rootCA); err != nil {
|
||||
return fmt.Errorf("error parsing root-ca-file at %s: %v", s.RootCAFile, err)
|
||||
}
|
||||
} else {
|
||||
rootCA = kubeconfig.CAData
|
||||
}
|
||||
|
||||
if len(s.ServiceAccountKeyFile) > 0 {
|
||||
privateKey, err := serviceaccount.ReadPrivateKey(s.ServiceAccountKeyFile)
|
||||
if err != nil {
|
||||
|
@ -250,9 +268,10 @@ func (s *CMServer) Run(_ []string) error {
|
|||
} else {
|
||||
serviceaccount.NewTokensController(
|
||||
kubeClient,
|
||||
serviceaccount.DefaultTokenControllerOptions(
|
||||
serviceaccount.JWTTokenGenerator(privateKey),
|
||||
),
|
||||
serviceaccount.TokensControllerOptions{
|
||||
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
||||
RootCA: rootCA,
|
||||
},
|
||||
).Run()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,9 +157,10 @@ func (s *CMServer) Run(_ []string) error {
|
|||
} else {
|
||||
serviceaccount.NewTokensController(
|
||||
kubeClient,
|
||||
serviceaccount.DefaultTokenControllerOptions(
|
||||
serviceaccount.JWTTokenGenerator(privateKey),
|
||||
),
|
||||
serviceaccount.TokensControllerOptions{
|
||||
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
||||
RootCA: kubeconfig.CAData,
|
||||
},
|
||||
).Run()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1998,6 +1998,8 @@ const (
|
|||
ServiceAccountTokenKey = "token"
|
||||
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
|
||||
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountRootCAKey = "ca.crt"
|
||||
|
||||
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
|
||||
//
|
||||
|
|
|
@ -1894,6 +1894,8 @@ const (
|
|||
ServiceAccountTokenKey = "token"
|
||||
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
|
||||
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountRootCAKey = "ca.crt"
|
||||
|
||||
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
|
||||
//
|
||||
|
|
|
@ -1900,6 +1900,8 @@ const (
|
|||
ServiceAccountTokenKey = "token"
|
||||
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
|
||||
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
|
||||
ServiceAccountRootCAKey = "ca.crt"
|
||||
|
||||
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
|
||||
//
|
||||
|
|
|
@ -44,11 +44,8 @@ type TokensControllerOptions struct {
|
|||
// SecretResync is the time.Duration at which to fully re-list secrets.
|
||||
// If zero, re-list will be delayed as long as possible
|
||||
SecretResync time.Duration
|
||||
}
|
||||
|
||||
// DefaultTokenControllerOptions returns
|
||||
func DefaultTokenControllerOptions(tokenGenerator TokenGenerator) TokensControllerOptions {
|
||||
return TokensControllerOptions{TokenGenerator: tokenGenerator}
|
||||
// This CA will be added in the secretes of service accounts
|
||||
RootCA []byte
|
||||
}
|
||||
|
||||
// NewTokensController returns a new *TokensController.
|
||||
|
@ -56,6 +53,7 @@ func NewTokensController(cl client.Interface, options TokensControllerOptions) *
|
|||
e := &TokensController{
|
||||
client: cl,
|
||||
token: options.TokenGenerator,
|
||||
rootCA: options.RootCA,
|
||||
}
|
||||
|
||||
e.serviceAccounts, e.serviceAccountController = framework.NewIndexerInformer(
|
||||
|
@ -110,6 +108,8 @@ type TokensController struct {
|
|||
client client.Interface
|
||||
token TokenGenerator
|
||||
|
||||
rootCA []byte
|
||||
|
||||
serviceAccounts cache.Indexer
|
||||
secrets cache.Indexer
|
||||
|
||||
|
@ -293,6 +293,9 @@ func (e *TokensController) createSecret(serviceAccount *api.ServiceAccount) erro
|
|||
return err
|
||||
}
|
||||
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
|
||||
if e.rootCA != nil && len(e.rootCA) > 0 {
|
||||
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
|
||||
}
|
||||
|
||||
// Save the secret
|
||||
if _, err := e.client.Secrets(serviceAccount.Namespace).Create(secret); err != nil {
|
||||
|
@ -337,6 +340,9 @@ func (e *TokensController) generateTokenIfNeeded(serviceAccount *api.ServiceAcco
|
|||
if ok && len(tokenData) > 0 {
|
||||
return nil
|
||||
}
|
||||
if e.rootCA != nil && len(e.rootCA) > 0 {
|
||||
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
|
||||
}
|
||||
|
||||
// Generate the token
|
||||
token, err := e.token.GenerateToken(*serviceAccount, *secret)
|
||||
|
|
|
@ -378,7 +378,7 @@ func TestTokenCreation(t *testing.T) {
|
|||
|
||||
client := testclient.NewSimpleFake(tc.ClientObjects...)
|
||||
|
||||
controller := NewTokensController(client, DefaultTokenControllerOptions(generator))
|
||||
controller := NewTokensController(client, TokensControllerOptions{TokenGenerator: generator})
|
||||
|
||||
// Tell the token controller whether its stores have been synced
|
||||
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }
|
||||
|
|
|
@ -123,16 +123,16 @@ func certificatesFromFile(file string) ([]*x509.Certificate, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certs, err := certsFromPEM(pemBlock)
|
||||
certs, err := CertsFromPEM(pemBlock)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %s", file, err)
|
||||
}
|
||||
return certs, nil
|
||||
}
|
||||
|
||||
// certsFromPEM returns the x509.Certificates contained in the given PEM-encoded byte array
|
||||
// CertsFromPEM returns the x509.Certificates contained in the given PEM-encoded byte array
|
||||
// Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
|
||||
func certsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
||||
func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
||||
ok := false
|
||||
certs := []*x509.Certificate{}
|
||||
for len(pemCerts) > 0 {
|
||||
|
|
|
@ -422,7 +422,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
|
|||
})
|
||||
|
||||
// Start the service account and service account token controllers
|
||||
tokenController := serviceaccount.NewTokensController(rootClient, serviceaccount.DefaultTokenControllerOptions(serviceaccount.JWTTokenGenerator(serviceAccountKey)))
|
||||
tokenController := serviceaccount.NewTokensController(rootClient, serviceaccount.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceAccountKey)})
|
||||
tokenController.Run()
|
||||
serviceAccountController := serviceaccount.NewServiceAccountsController(rootClient, serviceaccount.DefaultServiceAccountsControllerOptions())
|
||||
serviceAccountController.Run()
|
||||
|
|
Loading…
Reference in New Issue