Merge pull request #39846 from andrewrynhard/add_authorization_mode

Automatic merge from submit-queue

Add authorization mode to kubeadm

This PR adds an option in `kubeadm` to allow a user to specify an [authorization plugin](https://kubernetes.io/docs/admin/authorization/). It defaults to RBAC.
This commit is contained in:
Kubernetes Submit Queue 2017-01-18 22:49:58 -08:00 committed by GitHub
commit f90bb1772b
28 changed files with 322 additions and 71 deletions

View File

@ -36,6 +36,7 @@ filegroup(
"//cmd/kubeadm/app/images:all-srcs", "//cmd/kubeadm/app/images:all-srcs",
"//cmd/kubeadm/app/master:all-srcs", "//cmd/kubeadm/app/master:all-srcs",
"//cmd/kubeadm/app/node:all-srcs", "//cmd/kubeadm/app/node:all-srcs",
"//cmd/kubeadm/app/phases/apiconfig:all-srcs",
"//cmd/kubeadm/app/phases/certs:all-srcs", "//cmd/kubeadm/app/phases/certs:all-srcs",
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs", "//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
"//cmd/kubeadm/app/preflight:all-srcs", "//cmd/kubeadm/app/preflight:all-srcs",

View File

@ -39,6 +39,7 @@ type MasterConfiguration struct {
Networking Networking Networking Networking
KubernetesVersion string KubernetesVersion string
CloudProvider string CloudProvider string
AuthorizationMode string
} }
type API struct { type API struct {

View File

@ -19,6 +19,7 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api/v1:go_default_library", "//pkg/api/v1:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/schema",

View File

@ -18,6 +18,7 @@ package v1alpha1
import ( import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
) )
const ( const (
@ -27,6 +28,7 @@ const (
DefaultKubernetesFallbackVersion = "v1.5.0" DefaultKubernetesFallbackVersion = "v1.5.0"
DefaultAPIBindPort = 6443 DefaultAPIBindPort = 6443
DefaultDiscoveryBindPort = 9898 DefaultDiscoveryBindPort = 9898
DefaultAuthorizationMode = authorizer.ModeRBAC
) )
func addDefaultingFuncs(scheme *runtime.Scheme) error { func addDefaultingFuncs(scheme *runtime.Scheme) error {
@ -56,4 +58,8 @@ func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
if obj.Discovery.Token == nil && obj.Discovery.File == nil && obj.Discovery.HTTPS == nil { if obj.Discovery.Token == nil && obj.Discovery.File == nil && obj.Discovery.HTTPS == nil {
obj.Discovery.Token = &TokenDiscovery{} obj.Discovery.Token = &TokenDiscovery{}
} }
if obj.AuthorizationMode == "" {
obj.AuthorizationMode = DefaultAuthorizationMode
}
} }

View File

@ -29,6 +29,7 @@ type MasterConfiguration struct {
Networking Networking `json:"networking"` Networking Networking `json:"networking"`
KubernetesVersion string `json:"kubernetesVersion"` KubernetesVersion string `json:"kubernetesVersion"`
CloudProvider string `json:"cloudProvider"` CloudProvider string `json:"cloudProvider"`
AuthorizationMode string `json:"authorizationMode"`
} }
type API struct { type API struct {

View File

@ -27,6 +27,7 @@ go_library(
"//cmd/kubeadm/app/discovery:go_default_library", "//cmd/kubeadm/app/discovery:go_default_library",
"//cmd/kubeadm/app/master:go_default_library", "//cmd/kubeadm/app/master:go_default_library",
"//cmd/kubeadm/app/node:go_default_library", "//cmd/kubeadm/app/node:go_default_library",
"//cmd/kubeadm/app/phases/apiconfig:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library", "//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/preflight:go_default_library",
@ -34,6 +35,7 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library", "//pkg/api/v1:go_default_library",
"//pkg/fields:go_default_library", "//pkg/fields:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
"//pkg/kubectl:go_default_library", "//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/util/flag:go_default_library", "//pkg/util/flag:go_default_library",
@ -54,7 +56,10 @@ go_test(
], ],
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = ["//cmd/kubeadm/app/preflight:go_default_library"], deps = [
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
],
) )
filegroup( filegroup(

View File

@ -32,6 +32,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/flags" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/flags"
"k8s.io/kubernetes/cmd/kubeadm/app/discovery" "k8s.io/kubernetes/cmd/kubeadm/app/discovery"
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master" kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
certphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" certphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
@ -41,6 +42,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/preflight" "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
) )
var ( var (
@ -183,6 +185,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight
} }
cfg.KubernetesVersion = ver cfg.KubernetesVersion = ver
fmt.Println("[init] Using Kubernetes version:", ver) fmt.Println("[init] Using Kubernetes version:", ver)
fmt.Println("[init] Using Authorization mode:", cfg.AuthorizationMode)
// Warn about the limitations with the current cloudprovider solution. // Warn about the limitations with the current cloudprovider solution.
if cfg.CloudProvider != "" { if cfg.CloudProvider != "" {
@ -255,6 +258,24 @@ func (i *Init) Run(out io.Writer) error {
return err return err
} }
if i.cfg.AuthorizationMode == authorizer.ModeRBAC {
err = apiconfig.CreateBootstrapRBACClusterRole(client)
if err != nil {
return err
}
err = apiconfig.CreateKubeDNSRBACClusterRole(client)
if err != nil {
return err
}
// TODO: remove this when https://github.com/kubernetes/kubeadm/issues/114 is fixed
err = apiconfig.CreateKubeProxyClusterRoleBinding(client)
if err != nil {
return err
}
}
if err := kubemaster.UpdateMasterRoleLabelsAndTaints(client, false); err != nil { if err := kubemaster.UpdateMasterRoleLabelsAndTaints(client, false); err != nil {
return err return err
} }

View File

@ -27,6 +27,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight" "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/util/initsystem" "k8s.io/kubernetes/pkg/util/initsystem"
@ -150,7 +151,7 @@ func drainAndRemoveNode(removeNode bool) error {
hostname = strings.ToLower(hostname) hostname = strings.ToLower(hostname)
// TODO: Use the "native" k8s client for this once we're confident the versioned is working // TODO: Use the "native" k8s client for this once we're confident the versioned is working
kubeConfigPath := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf") kubeConfigPath := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)
getNodesCmd := fmt.Sprintf("kubectl --kubeconfig %s get nodes | grep %s", kubeConfigPath, hostname) getNodesCmd := fmt.Sprintf("kubectl --kubeconfig %s get nodes | grep %s", kubeConfigPath, hostname)
output, err := exec.Command("sh", "-c", getNodesCmd).Output() output, err := exec.Command("sh", "-c", getNodesCmd).Output()
@ -219,8 +220,8 @@ func resetConfigDir(configPathDir, pkiPathDir string) {
} }
filesToClean := []string{ filesToClean := []string{
path.Join(configPathDir, "admin.conf"), path.Join(configPathDir, kubeconfig.AdminKubeConfigFileName),
path.Join(configPathDir, "kubelet.conf"), path.Join(configPathDir, kubeconfig.KubeletKubeConfigFileName),
} }
fmt.Printf("[reset] Deleting files: %v\n", filesToClean) fmt.Printf("[reset] Deleting files: %v\n", filesToClean)
for _, path := range filesToClean { for _, path := range filesToClean {

View File

@ -22,6 +22,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight" "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
) )
@ -63,8 +64,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.json", "manifests/etcd.json",
"manifests/kube-apiserver.json", "manifests/kube-apiserver.json",
"pki/ca.pem", "pki/ca.pem",
"admin.conf", kubeconfig.AdminKubeConfigFileName,
"kubelet.conf", kubeconfig.KubeletKubeConfigFileName,
}, },
verifyExists: []string{ verifyExists: []string{
"manifests", "manifests",
@ -77,7 +78,7 @@ func TestConfigDirCleaner(t *testing.T) {
}, },
setupFiles: []string{ setupFiles: []string{
"pki/ca.pem", "pki/ca.pem",
"kubelet.conf", kubeconfig.KubeletKubeConfigFileName,
}, },
verifyExists: []string{ verifyExists: []string{
"pki", "pki",
@ -95,8 +96,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.json", "manifests/etcd.json",
"manifests/kube-apiserver.json", "manifests/kube-apiserver.json",
"pki/ca.pem", "pki/ca.pem",
"admin.conf", kubeconfig.AdminKubeConfigFileName,
"kubelet.conf", kubeconfig.KubeletKubeConfigFileName,
"cloud-config", "cloud-config",
}, },
verifyExists: []string{ verifyExists: []string{
@ -115,8 +116,8 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/etcd.json", "manifests/etcd.json",
"manifests/kube-apiserver.json", "manifests/kube-apiserver.json",
"pki/ca.pem", "pki/ca.pem",
"admin.conf", kubeconfig.AdminKubeConfigFileName,
"kubelet.conf", kubeconfig.KubeletKubeConfigFileName,
".cloud-config", ".cloud-config",
".mydir/.myfile", ".mydir/.myfile",
}, },
@ -166,8 +167,8 @@ func TestConfigDirCleaner(t *testing.T) {
// Verify the files we cleanup implicitly in every test: // Verify the files we cleanup implicitly in every test:
assertExists(t, tmpDir) assertExists(t, tmpDir)
assertNotExists(t, filepath.Join(tmpDir, "admin.conf")) assertNotExists(t, filepath.Join(tmpDir, kubeconfig.AdminKubeConfigFileName))
assertNotExists(t, filepath.Join(tmpDir, "kubelet.conf")) assertNotExists(t, filepath.Join(tmpDir, kubeconfig.KubeletKubeConfigFileName))
assertDirEmpty(t, filepath.Join(tmpDir, "manifests")) assertDirEmpty(t, filepath.Join(tmpDir, "manifests"))
assertDirEmpty(t, filepath.Join(tmpDir, "pki")) assertDirEmpty(t, filepath.Join(tmpDir, "pki"))

View File

@ -29,6 +29,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master" kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
@ -123,7 +124,7 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
// RunCreateToken generates a new bootstrap token and stores it as a secret on the server. // RunCreateToken generates a new bootstrap token and stores it as a secret on the server.
func RunCreateToken(out io.Writer, cmd *cobra.Command, tokenDuration time.Duration, token string) error { func RunCreateToken(out io.Writer, cmd *cobra.Command, tokenDuration time.Duration, token string) error {
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")) client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
if err != nil { if err != nil {
return err return err
} }
@ -156,7 +157,7 @@ func RunGenerateToken(out io.Writer) error {
// RunListTokens lists details on all existing bootstrap tokens on the server. // RunListTokens lists details on all existing bootstrap tokens on the server.
func RunListTokens(out io.Writer, errW io.Writer, cmd *cobra.Command) error { func RunListTokens(out io.Writer, errW io.Writer, cmd *cobra.Command) error {
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")) client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
if err != nil { if err != nil {
return err return err
} }
@ -215,7 +216,7 @@ func RunDeleteToken(out io.Writer, cmd *cobra.Command, tokenId string) error {
return err return err
} }
client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")) client, err := kubemaster.CreateClientFromFile(path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName))
if err != nil { if err != nil {
return err return err
} }

View File

@ -22,6 +22,7 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/images:go_default_library", "//cmd/kubeadm/app/images:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/resource:go_default_library", "//pkg/api/resource:go_default_library",
@ -30,6 +31,7 @@ go_library(
"//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/client/unversioned/clientcmd/api:go_default_library", "//pkg/client/unversioned/clientcmd/api:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library",
"//pkg/util/cert:go_default_library", "//pkg/util/cert:go_default_library",

View File

@ -23,6 +23,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/cmd/kubeadm/app/images"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
@ -31,6 +32,8 @@ import (
"k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/intstr"
) )
const KubeDNS = "kube-dns"
func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec { func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
privilegedTrue := true privilegedTrue := true
return v1.PodSpec{ return v1.PodSpec{
@ -68,7 +71,7 @@ func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
{ {
Name: "kubeconfig", Name: "kubeconfig",
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")}, HostPath: &v1.HostPathVolumeSource{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)},
}, },
}, },
{ {
@ -86,6 +89,7 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) v1.PodSpec {
dnsmasqPort := int32(53) dnsmasqPort := int32(53)
return v1.PodSpec{ return v1.PodSpec{
ServiceAccountName: KubeDNS,
Containers: []v1.Container{ Containers: []v1.Container{
// DNS server // DNS server
{ {
@ -250,7 +254,7 @@ func createKubeDNSServiceSpec(cfg *kubeadmapi.MasterConfiguration) (*v1.ServiceS
} }
return &v1.ServiceSpec{ return &v1.ServiceSpec{
Selector: map[string]string{"name": "kube-dns"}, Selector: map[string]string{"name": KubeDNS},
Ports: []v1.ServicePort{ Ports: []v1.ServicePort{
{Name: "dns", Port: 53, Protocol: v1.ProtocolUDP}, {Name: "dns", Port: 53, Protocol: v1.ProtocolUDP},
{Name: "dns-tcp", Port: 53, Protocol: v1.ProtocolTCP}, {Name: "dns-tcp", Port: 53, Protocol: v1.ProtocolTCP},
@ -270,10 +274,14 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse
fmt.Println("[addons] Created essential addon: kube-proxy") fmt.Println("[addons] Created essential addon: kube-proxy")
kubeDNSDeployment := NewDeployment("kube-dns", 1, createKubeDNSPodSpec(cfg)) kubeDNSDeployment := NewDeployment(KubeDNS, 1, createKubeDNSPodSpec(cfg))
SetMasterTaintTolerations(&kubeDNSDeployment.Spec.Template.ObjectMeta) SetMasterTaintTolerations(&kubeDNSDeployment.Spec.Template.ObjectMeta)
SetNodeAffinity(&kubeDNSDeployment.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity()) SetNodeAffinity(&kubeDNSDeployment.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity())
kubeDNSServiceAccount := &v1.ServiceAccount{}
kubeDNSServiceAccount.ObjectMeta.Name = KubeDNS
if _, err := client.ServiceAccounts(api.NamespaceSystem).Create(kubeDNSServiceAccount); err != nil {
return fmt.Errorf("failed creating kube-dns service account [%v]", err)
}
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kubeDNSDeployment); err != nil { if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kubeDNSDeployment); err != nil {
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err) return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)
} }
@ -283,7 +291,7 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err) return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)
} }
kubeDNSService := NewService("kube-dns", *kubeDNSServiceSpec) kubeDNSService := NewService(KubeDNS, *kubeDNSServiceSpec)
kubeDNSService.ObjectMeta.Labels["kubernetes.io/name"] = "KubeDNS" kubeDNSService.ObjectMeta.Labels["kubernetes.io/name"] = "KubeDNS"
if _, err := client.Services(api.NamespaceSystem).Create(kubeDNSService); err != nil { if _, err := client.Services(api.NamespaceSystem).Create(kubeDNSService); err != nil {
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err) return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)

View File

@ -69,10 +69,15 @@ func CreateClientAndWaitForAPI(file string) (*clientset.Clientset, error) {
start := time.Now() start := time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) { wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
// TODO: use /healthz API instead of this
cs, err := client.ComponentStatuses().List(v1.ListOptions{}) cs, err := client.ComponentStatuses().List(v1.ListOptions{})
if err != nil { if err != nil {
if apierrs.IsForbidden(err) {
fmt.Print("\r[apiclient] Waiting for the API server to create RBAC policies")
}
return false, nil return false, nil
} }
fmt.Println("\n[apiclient] RBAC policies created")
// TODO(phase2) must revisit this when we implement HA // TODO(phase2) must revisit this when we implement HA
if len(cs.Items) < 3 { if len(cs.Items) < 3 {
fmt.Println("[apiclient] Not all control plane components are ready yet") fmt.Println("[apiclient] Not all control plane components are ready yet")

View File

@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/cmd/kubeadm/app/images"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
api "k8s.io/kubernetes/pkg/api/v1" api "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/intstr"
@ -40,15 +41,17 @@ const (
DefaultClusterName = "kubernetes" DefaultClusterName = "kubernetes"
DefaultCloudConfigPath = "/etc/kubernetes/cloud-config" DefaultCloudConfigPath = "/etc/kubernetes/cloud-config"
etcd = "etcd" etcd = "etcd"
apiServer = "apiserver" apiServer = "apiserver"
controllerManager = "controller-manager" controllerManager = "controller-manager"
scheduler = "scheduler" scheduler = "scheduler"
proxy = "proxy" proxy = "proxy"
kubeAPIServer = "kube-apiserver" kubeAPIServer = "kube-apiserver"
kubeControllerManager = "kube-controller-manager" kubeControllerManager = "kube-controller-manager"
kubeScheduler = "kube-scheduler" kubeScheduler = "kube-scheduler"
kubeProxy = "kube-proxy" kubeProxy = "kube-proxy"
authorizationPolicyFile = "abac_policy.json"
authorizationWebhookConfigFile = "webhook_authz.conf"
) )
var ( var (
@ -296,6 +299,16 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) []string {
"--allow-privileged", "--allow-privileged",
) )
if cfg.AuthorizationMode != "" {
command = append(command, "--authorization-mode="+cfg.AuthorizationMode)
switch cfg.AuthorizationMode {
case authorizer.ModeABAC:
command = append(command, "--authorization-policy-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationPolicyFile))
case authorizer.ModeWebhook:
command = append(command, "--authorization-webhook-config-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationWebhookConfigFile))
}
}
// Use first address we are given // Use first address we are given
if len(cfg.API.AdvertiseAddresses) > 0 { if len(cfg.API.AdvertiseAddresses) > 0 {
command = append(command, fmt.Sprintf("--advertise-address=%s", cfg.API.AdvertiseAddresses[0])) command = append(command, fmt.Sprintf("--advertise-address=%s", cfg.API.AdvertiseAddresses[0]))
@ -357,7 +370,7 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) []string {
"--service-account-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem", "--service-account-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem",
"--cluster-signing-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem", "--cluster-signing-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem",
"--cluster-signing-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca-key.pem", "--cluster-signing-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
) )
if cfg.CloudProvider != "" { if cfg.CloudProvider != "" {

View File

@ -484,7 +484,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
}, },
}, },
{ {
@ -499,7 +499,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
"--cloud-provider=foo", "--cloud-provider=foo",
}, },
}, },
@ -515,7 +515,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem", "--service-account-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-key.pem",
"--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem", "--cluster-signing-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.pem",
"--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem", "--cluster-signing-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=kubeadm:kubelet-bootstrap",
"--allocate-node-cidrs=true", "--allocate-node-cidrs=true",
"--cluster-cidr=bar", "--cluster-cidr=bar",
}, },

View File

@ -32,7 +32,7 @@ func CreateTokenAuthFile(bt string) error {
if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.HostPKIPath, 0700); err != nil { if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.HostPKIPath, 0700); err != nil {
return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err) return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err)
} }
serialized := []byte(fmt.Sprintf("%s,kubeadm-node-csr,%s,system:kubelet-bootstrap\n", bt, uuid.NewUUID())) serialized := []byte(fmt.Sprintf("%s,kubeadm-node-csr,%s,kubeadm:kubelet-bootstrap\n", bt, uuid.NewUUID()))
// DumpReaderToFile create a file with mode 0600 // DumpReaderToFile create a file with mode 0600
if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), tokenAuthFilePath); err != nil { if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), tokenAuthFilePath); err != nil {
return fmt.Errorf("failed to save token auth file (%q) [%v]", tokenAuthFilePath, err) return fmt.Errorf("failed to save token auth file (%q) [%v]", tokenAuthFilePath, err)

View File

@ -20,7 +20,6 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library", "//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/certificates:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/client/unversioned/clientcmd:go_default_library",
@ -28,6 +27,8 @@ go_library(
"//pkg/kubelet/util/csr:go_default_library", "//pkg/kubelet/util/csr:go_default_library",
"//pkg/util/cert:go_default_library", "//pkg/util/cert:go_default_library",
"//vendor:github.com/square/go-jose", "//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/types", "//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/apimachinery/pkg/util/wait",
], ],

View File

@ -22,12 +22,13 @@ import (
"sync" "sync"
"time" "time"
apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -128,14 +129,9 @@ func checkForNodeNameDuplicates(clientSet *clientset.Clientset) error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to get node hostname [%v]", err) return fmt.Errorf("Failed to get node hostname [%v]", err)
} }
nodeList, err := clientSet.Nodes().List(v1.ListOptions{}) _, err = clientSet.Nodes().Get(hostName, metav1.GetOptions{})
if err != nil { if err != nil && !apierrs.IsNotFound(err) {
return fmt.Errorf("Failed to list the nodes in the cluster: [%v]\n", err) return err
}
for _, node := range nodeList.Items {
if hostName == node.Name {
return fmt.Errorf("Node with name [%q] already exists.", node.Name)
}
} }
return nil return nil
} }

View File

@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["clusterroles.go"],
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/master:go_default_library",
"//pkg/api:go_default_library",
"//pkg/apis/rbac/v1beta1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,136 @@
/*
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 apiconfig
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/cmd/kubeadm/app/master"
"k8s.io/kubernetes/pkg/api"
rbac "k8s.io/kubernetes/pkg/apis/rbac/v1beta1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
)
// CreateBootstrapRBACClusterRole creates the necessary ClusterRole for bootstrapping
func CreateBootstrapRBACClusterRole(clientset *clientset.Clientset) error {
clusterRole := rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: "kubeadm:kubelet-bootstrap"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get").Groups("").Resources("nodes").RuleOrDie(),
rbac.NewRule("create", "watch").Groups("certificates.k8s.io").Resources("certificatesigningrequests").RuleOrDie(),
},
}
if _, err := clientset.Rbac().ClusterRoles().Create(&clusterRole); err != nil {
return err
}
subject := rbac.Subject{
Kind: "Group",
Name: "kubeadm:kubelet-bootstrap",
}
clusterRoleBinding := rbac.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "kubeadm:kubelet-bootstrap",
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "kubeadm:kubelet-bootstrap",
},
Subjects: []rbac.Subject{subject},
}
if _, err := clientset.Rbac().ClusterRoleBindings().Create(&clusterRoleBinding); err != nil {
return err
}
fmt.Println("[apiconfig] Created kubelet-bootstrap RBAC rules")
return nil
}
// CreateKubeDNSRBACClusterRole creates the necessary ClusterRole for kube-dns
func CreateKubeDNSRBACClusterRole(clientset *clientset.Clientset) error {
clusterRole := rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: "kubeadm:" + master.KubeDNS},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch").Groups("").Resources("endpoints", "services").RuleOrDie(),
// TODO: remove watch rule when https://github.com/kubernetes/kubernetes/pull/38816 gets merged
rbac.NewRule("get", "list", "watch").Groups("").Resources("configmaps").RuleOrDie(),
},
}
if _, err := clientset.Rbac().ClusterRoles().Create(&clusterRole); err != nil {
return err
}
subject := rbac.Subject{
Kind: "ServiceAccount",
Name: master.KubeDNS,
Namespace: api.NamespaceSystem,
}
clusterRoleBinding := rbac.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "kubeadm:" + master.KubeDNS,
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "kubeadm:" + master.KubeDNS,
},
Subjects: []rbac.Subject{subject},
}
if _, err := clientset.Rbac().ClusterRoleBindings().Create(&clusterRoleBinding); err != nil {
return err
}
fmt.Println("[apiconfig] Created kube-dns RBAC rules")
return nil
}
// CreateKubeProxyClusterRoleBinding creates the necessary ClusterRole for kube-dns
func CreateKubeProxyClusterRoleBinding(clientset *clientset.Clientset) error {
systemKubeProxySubject := rbac.Subject{
Kind: "User",
Name: "system:kube-proxy",
Namespace: api.NamespaceSystem,
}
systemNodesSubject := rbac.Subject{
Kind: "Group",
Name: "system:nodes",
Namespace: api.NamespaceSystem,
}
clusterRoleBinding := rbac.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "system:node-proxier",
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "system:node-proxier",
},
Subjects: []rbac.Subject{systemKubeProxySubject, systemNodesSubject},
}
if _, err := clientset.Rbac().ClusterRoleBindings().Update(&clusterRoleBinding); err != nil {
return err
}
fmt.Println("[apiconfig] Created kube-proxy RBAC rules")
return nil
}

View File

@ -34,7 +34,6 @@ func newCertificateAuthority() (*rsa.PrivateKey, *x509.Certificate, error) {
config := certutil.Config{ config := certutil.Config{
CommonName: "kubernetes", CommonName: "kubernetes",
} }
cert, err := certutil.NewSelfSignedCACert(config, key) cert, err := certutil.NewSelfSignedCACert(config, key)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err) return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err)
@ -61,16 +60,13 @@ func newServerKeyAndCert(caCert *x509.Certificate, caKey *rsa.PrivateKey, altNam
return key, cert, nil return key, cert, nil
} }
func NewClientKeyAndCert(caCert *x509.Certificate, caKey *rsa.PrivateKey) (*rsa.PrivateKey, *x509.Certificate, error) { func NewClientKeyAndCert(config *certutil.Config, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*rsa.PrivateKey, *x509.Certificate, error) {
key, err := certutil.NewPrivateKey() key, err := certutil.NewPrivateKey()
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to create private key [%v]", err) return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
} }
config := certutil.Config{ cert, err := certutil.NewSignedCert(*config, key, caCert, caKey)
CommonName: "kubernetes-client",
}
cert, err := certutil.NewSignedCert(config, key, caCert, caKey)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err) return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err)
} }

View File

@ -105,7 +105,11 @@ func TestNewClientKeyAndCert(t *testing.T) {
t.Fatalf("Couldn't create rsa Private Key") t.Fatalf("Couldn't create rsa Private Key")
} }
caCert := &x509.Certificate{} caCert := &x509.Certificate{}
_, _, actual := NewClientKeyAndCert(caCert, caKey) config := &certutil.Config{
CommonName: "test",
Organization: []string{"test"},
}
_, _, actual := NewClientKeyAndCert(config, caCert, caKey)
if (actual == nil) != rt.expected { if (actual == nil) != rt.expected {
t.Errorf( t.Errorf(
"failed NewClientKeyAndCert:\n\texpected: %t\n\t actual: %t", "failed NewClientKeyAndCert:\n\texpected: %t\n\t actual: %t",

View File

@ -31,9 +31,11 @@ import (
) )
const ( const (
KubernetesDirPermissions = 0700 KubernetesDirPermissions = 0700
AdminKubeConfigFileName = "admin.conf" AdminKubeConfigFileName = "admin.conf"
KubeletKubeConfigFileName = "kubelet.conf" AdminKubeConfigClientName = "kubernetes-admin"
KubeletKubeConfigFileName = "kubelet.conf"
KubeletKubeConfigClientName = "kubelet"
) )
// This function is called from the main init and does the work for the default phase behaviour // This function is called from the main init and does the work for the default phase behaviour
@ -68,36 +70,47 @@ func CreateAdminAndKubeletKubeConfig(masterEndpoint, pkiDir, outDir string) erro
} }
// User admin should have full access to the cluster // User admin should have full access to the cluster
if err := createKubeConfigFileForClient(masterEndpoint, "admin", outDir, caCert, caKey); err != nil { adminCertConfig := &certutil.Config{
return fmt.Errorf("couldn't create a kubeconfig file for admin: %v", err) CommonName: AdminKubeConfigClientName,
Organization: []string{"system:masters"},
}
adminKubeConfigFilePath := path.Join(outDir, AdminKubeConfigFileName)
if err := createKubeConfigFileForClient(masterEndpoint, adminKubeConfigFilePath, adminCertConfig, caCert, caKey); err != nil {
return fmt.Errorf("couldn't create config for %s: %v", AdminKubeConfigClientName, err)
} }
// TODO: The kubelet should have limited access to the cluster // The kubelet should have limited access to the cluster
if err := createKubeConfigFileForClient(masterEndpoint, "kubelet", outDir, caCert, caKey); err != nil { kubeletCertConfig := &certutil.Config{
return fmt.Errorf("couldn't create a kubeconfig file for kubelet: %v", err) CommonName: KubeletKubeConfigClientName,
Organization: []string{"system:nodes"},
} }
kubeletKubeConfigFilePath := path.Join(outDir, KubeletKubeConfigFileName)
if err := createKubeConfigFileForClient(masterEndpoint, kubeletKubeConfigFilePath, kubeletCertConfig, caCert, caKey); err != nil {
return fmt.Errorf("couldn't create config for %s: %v", KubeletKubeConfigClientName, err)
}
// TODO make credentials for the controller manager and kube proxy
return nil return nil
} }
func createKubeConfigFileForClient(masterEndpoint, client, outDir string, caCert *x509.Certificate, caKey *rsa.PrivateKey) error { func createKubeConfigFileForClient(masterEndpoint, kubeConfigFilePath string, config *certutil.Config, caCert *x509.Certificate, caKey *rsa.PrivateKey) error {
key, cert, err := certphase.NewClientKeyAndCert(caCert, caKey) key, cert, err := certphase.NewClientKeyAndCert(config, caCert, caKey)
if err != nil { if err != nil {
return fmt.Errorf("failure while creating %s client certificate [%v]", client, err) return fmt.Errorf("failure while creating %s client certificate [%v]", config.CommonName, err)
} }
config := MakeClientConfigWithCerts( kubeConfig := MakeClientConfigWithCerts(
masterEndpoint, masterEndpoint,
"kubernetes", "kubernetes",
client, config.CommonName,
certutil.EncodeCertPEM(caCert), certutil.EncodeCertPEM(caCert),
certutil.EncodePrivateKeyPEM(key), certutil.EncodePrivateKeyPEM(key),
certutil.EncodeCertPEM(cert), certutil.EncodeCertPEM(cert),
) )
// Write it now to a file // Write it now to a file
filepath := path.Join(outDir, fmt.Sprintf("%s.conf", client)) return WriteKubeconfigToDisk(kubeConfigFilePath, kubeConfig)
return WriteKubeconfigToDisk(filepath, config)
} }
func WriteKubeconfigToDisk(filepath string, kubeconfig *clientcmdapi.Config) error { func WriteKubeconfigToDisk(filepath string, kubeconfig *clientcmdapi.Config) error {

View File

@ -14,6 +14,7 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//pkg/api/validation:go_default_library", "//pkg/api/validation:go_default_library",
"//pkg/util/initsystem:go_default_library", "//pkg/util/initsystem:go_default_library",
"//pkg/util/node:go_default_library", "//pkg/util/node:go_default_library",

View File

@ -29,6 +29,7 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/util/initsystem" "k8s.io/kubernetes/pkg/util/initsystem"
"k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/pkg/util/node"
@ -320,8 +321,8 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")}, DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")},
DirAvailableCheck{Path: kubeadmapi.GlobalEnvParams.HostPKIPath}, DirAvailableCheck{Path: kubeadmapi.GlobalEnvParams.HostPKIPath},
DirAvailableCheck{Path: "/var/lib/kubelet"}, DirAvailableCheck{Path: "/var/lib/kubelet"},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")}, FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.AdminKubeConfigFileName)},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")}, FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)},
FileContentCheck{Path: bridgenf, Content: []byte{'1'}}, FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "ip", mandatory: true},
InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true},
@ -355,7 +356,7 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
PortOpenCheck{port: 10250}, PortOpenCheck{port: 10250},
DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")}, DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")},
DirAvailableCheck{Path: "/var/lib/kubelet"}, DirAvailableCheck{Path: "/var/lib/kubelet"},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")}, FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, kubeconfig.KubeletKubeConfigFileName)},
FileContentCheck{Path: bridgenf, Content: []byte{'1'}}, FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "ip", mandatory: true},
InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true},

View File

@ -27,6 +27,7 @@ cmd/kube-proxy
cmd/kubeadm cmd/kubeadm
cmd/kubeadm cmd/kubeadm
cmd/kubeadm/app/apis/kubeadm/install cmd/kubeadm/app/apis/kubeadm/install
cmd/kubeadm/app/phases/apiconfig
cmd/kubectl cmd/kubectl
cmd/kubelet cmd/kubelet
cmd/libs/go2idl/client-gen cmd/libs/go2idl/client-gen

View File

@ -562,6 +562,7 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
obj.API.Port = 20 obj.API.Port = 20
obj.Networking.ServiceSubnet = "foo" obj.Networking.ServiceSubnet = "foo"
obj.Networking.DNSDomain = "foo" obj.Networking.DNSDomain = "foo"
obj.AuthorizationMode = "foo"
obj.Discovery.Token = &kubeadm.TokenDiscovery{} obj.Discovery.Token = &kubeadm.TokenDiscovery{}
}, },
func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) { func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) {

View File

@ -90,7 +90,7 @@ func NewSignedCert(cfg Config, key *rsa.PrivateKey, caCert *x509.Certificate, ca
certTmpl := x509.Certificate{ certTmpl := x509.Certificate{
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: cfg.CommonName, CommonName: cfg.CommonName,
Organization: caCert.Subject.Organization, Organization: cfg.Organization,
}, },
DNSNames: cfg.AltNames.DNSNames, DNSNames: cfg.AltNames.DNSNames,
IPAddresses: cfg.AltNames.IPs, IPAddresses: cfg.AltNames.IPs,