mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Merge pull request #53181 from andrewsykim/kubeadm/v1.9
Automatic merge from submit-queue (batch tested with PRs 47039, 53681, 53303, 53181, 53781). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. kubeadm: prepare for v1.9 cycle **What this PR does / why we need it**: Prepares kubeadm for v1.9 cycle which only supports v1.8 and v1.9 (when released). Deletes all v1.7.x support and sets minimum Kubernetes version to v1.8. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes https://github.com/kubernetes/kubeadm/issues/447 https://github.com/kubernetes/kubeadm/issues/448 https://github.com/kubernetes/kubeadm/issues/445 **Special notes for your reviewer**: @luxas these changes seem a bit aggressive but seems reasonable given the compatibility expectations for kubeadm.
This commit is contained in:
commit
49e03d76ba
@ -370,7 +370,7 @@ func (i *Init) Run(out io.Writer) error {
|
|||||||
|
|
||||||
// Create the default node bootstrap token
|
// Create the default node bootstrap token
|
||||||
tokenDescription := "The default bootstrap token generated by 'kubeadm init'."
|
tokenDescription := "The default bootstrap token generated by 'kubeadm init'."
|
||||||
if err := nodebootstraptokenphase.UpdateOrCreateToken(client, i.cfg.Token, false, i.cfg.TokenTTL.Duration, kubeadmconstants.DefaultTokenUsages, []string{kubeadmconstants.V18NodeBootstrapTokenAuthGroup}, tokenDescription); err != nil {
|
if err := nodebootstraptokenphase.UpdateOrCreateToken(client, i.cfg.Token, false, i.cfg.TokenTTL.Duration, kubeadmconstants.DefaultTokenUsages, []string{kubeadmconstants.NodeBootstrapTokenAuthGroup}, tokenDescription); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Create RBAC rules that makes the bootstrap tokens able to post CSRs
|
// Create RBAC rules that makes the bootstrap tokens able to post CSRs
|
||||||
|
@ -120,7 +120,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
|||||||
createCmd.Flags().StringSliceVar(&usages,
|
createCmd.Flags().StringSliceVar(&usages,
|
||||||
"usages", kubeadmconstants.DefaultTokenUsages, "The ways in which this token can be used. Valid options: [signing,authentication].")
|
"usages", kubeadmconstants.DefaultTokenUsages, "The ways in which this token can be used. Valid options: [signing,authentication].")
|
||||||
createCmd.Flags().StringSliceVar(&extraGroups,
|
createCmd.Flags().StringSliceVar(&extraGroups,
|
||||||
"groups", []string{kubeadmconstants.V18NodeBootstrapTokenAuthGroup},
|
"groups", []string{kubeadmconstants.NodeBootstrapTokenAuthGroup},
|
||||||
fmt.Sprintf("Extra groups that this token will authenticate as when used for authentication. Must match %q.", bootstrapapi.BootstrapGroupPattern))
|
fmt.Sprintf("Extra groups that this token will authenticate as when used for authentication. Must match %q.", bootstrapapi.BootstrapGroupPattern))
|
||||||
createCmd.Flags().StringVar(&description,
|
createCmd.Flags().StringVar(&description,
|
||||||
"description", "", "A human friendly description of how this token is used.")
|
"description", "", "A human friendly description of how this token is used.")
|
||||||
|
@ -32,5 +32,4 @@ go_test(
|
|||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["constants_test.go"],
|
srcs = ["constants_test.go"],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
deps = ["//pkg/util/version:go_default_library"],
|
|
||||||
)
|
)
|
||||||
|
@ -170,11 +170,8 @@ const (
|
|||||||
// KubeConfigVolumeName specifies the name for the Volume that is used for injecting the kubeconfig to talk securely to the api server for a control plane component if applicable
|
// KubeConfigVolumeName specifies the name for the Volume that is used for injecting the kubeconfig to talk securely to the api server for a control plane component if applicable
|
||||||
KubeConfigVolumeName = "kubeconfig"
|
KubeConfigVolumeName = "kubeconfig"
|
||||||
|
|
||||||
// V17NodeBootstrapTokenAuthGroup specifies which group a Node Bootstrap Token should be authenticated in, in v1.7
|
// NodeBootstrapTokenAuthGroup specifies which group a Node Bootstrap Token should be authenticated in
|
||||||
V17NodeBootstrapTokenAuthGroup = "system:bootstrappers"
|
NodeBootstrapTokenAuthGroup = "system:bootstrappers:kubeadm:default-node-token"
|
||||||
|
|
||||||
// V18NodeBootstrapTokenAuthGroup specifies which group a Node Bootstrap Token should be authenticated in, in v1.8
|
|
||||||
V18NodeBootstrapTokenAuthGroup = "system:bootstrappers:kubeadm:default-node-token"
|
|
||||||
|
|
||||||
// DefaultCIImageRepository points to image registry where CI uploads images from ci-cross build job
|
// DefaultCIImageRepository points to image registry where CI uploads images from ci-cross build job
|
||||||
DefaultCIImageRepository = "gcr.io/kubernetes-ci-images"
|
DefaultCIImageRepository = "gcr.io/kubernetes-ci-images"
|
||||||
@ -212,10 +209,6 @@ var (
|
|||||||
// TODO: Remove this when the v1.9 cycle starts and we bump the minimum supported version to v1.8.0
|
// TODO: Remove this when the v1.9 cycle starts and we bump the minimum supported version to v1.8.0
|
||||||
MinimumCSRAutoApprovalClusterRolesVersion = version.MustParseSemantic("v1.8.0-alpha.3")
|
MinimumCSRAutoApprovalClusterRolesVersion = version.MustParseSemantic("v1.8.0-alpha.3")
|
||||||
|
|
||||||
// UseEnableBootstrapTokenAuthFlagVersion defines the first version where the API server supports the --enable-bootstrap-token-auth flag instead of the old and deprecated flag.
|
|
||||||
// TODO: Remove this when the v1.9 cycle starts and we bump the minimum supported version to v1.8.0
|
|
||||||
UseEnableBootstrapTokenAuthFlagVersion = version.MustParseSemantic("v1.8.0-beta.0")
|
|
||||||
|
|
||||||
// MinimumKubeletVersion specifies the minimum version of kubelet which kubeadm supports
|
// MinimumKubeletVersion specifies the minimum version of kubelet which kubeadm supports
|
||||||
MinimumKubeletVersion = version.MustParseSemantic("v1.8.0")
|
MinimumKubeletVersion = version.MustParseSemantic("v1.8.0")
|
||||||
)
|
)
|
||||||
@ -253,11 +246,3 @@ func CreateTempDirForKubeadm(dirName string) (string, error) {
|
|||||||
}
|
}
|
||||||
return tempDir, nil
|
return tempDir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNodeBootstrapTokenAuthGroup gets the bootstrap token auth group conditionally based on version
|
|
||||||
func GetNodeBootstrapTokenAuthGroup(k8sVersion *version.Version) string {
|
|
||||||
if k8sVersion.AtLeast(UseEnableBootstrapTokenAuthFlagVersion) {
|
|
||||||
return V18NodeBootstrapTokenAuthGroup
|
|
||||||
}
|
|
||||||
return V17NodeBootstrapTokenAuthGroup
|
|
||||||
}
|
|
||||||
|
@ -18,8 +18,6 @@ package constants
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/util/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetStaticPodDirectory(t *testing.T) {
|
func TestGetStaticPodDirectory(t *testing.T) {
|
||||||
@ -112,48 +110,3 @@ func TestAddSelfHostedPrefix(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNodeBootstrapTokenAuthGroup(t *testing.T) {
|
|
||||||
var tests = []struct {
|
|
||||||
k8sVersion, expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.7.0",
|
|
||||||
expected: "system:bootstrappers",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.7.8",
|
|
||||||
expected: "system:bootstrappers",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.8.0-alpha.3",
|
|
||||||
expected: "system:bootstrappers",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.8.0-beta.0",
|
|
||||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.8.0-rc.1",
|
|
||||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.8.0",
|
|
||||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
k8sVersion: "v1.8.9",
|
|
||||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, rt := range tests {
|
|
||||||
actual := GetNodeBootstrapTokenAuthGroup(version.MustParseSemantic(rt.k8sVersion))
|
|
||||||
if actual != rt.expected {
|
|
||||||
t.Errorf(
|
|
||||||
"failed GetNodeBootstrapTokenAuthGroup:\n\texpected: %s\n\t actual: %s",
|
|
||||||
rt.expected,
|
|
||||||
actual,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -63,7 +63,7 @@ func AllowBootstrapTokensToPostCSRs(client clientset.Interface, k8sVersion *vers
|
|||||||
Subjects: []rbac.Subject{
|
Subjects: []rbac.Subject{
|
||||||
{
|
{
|
||||||
Kind: rbac.GroupKind,
|
Kind: rbac.GroupKind,
|
||||||
Name: constants.GetNodeBootstrapTokenAuthGroup(k8sVersion),
|
Name: constants.NodeBootstrapTokenAuthGroup,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -87,7 +87,7 @@ func AutoApproveNodeBootstrapTokens(client clientset.Interface, k8sVersion *vers
|
|||||||
Subjects: []rbac.Subject{
|
Subjects: []rbac.Subject{
|
||||||
{
|
{
|
||||||
Kind: "Group",
|
Kind: "Group",
|
||||||
Name: constants.GetNodeBootstrapTokenAuthGroup(k8sVersion),
|
Name: constants.NodeBootstrapTokenAuthGroup,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -148,6 +148,7 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, k8sVersion *versio
|
|||||||
"tls-private-key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKeyName),
|
"tls-private-key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKeyName),
|
||||||
"kubelet-client-certificate": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientCertName),
|
"kubelet-client-certificate": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientCertName),
|
||||||
"kubelet-client-key": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientKeyName),
|
"kubelet-client-key": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientKeyName),
|
||||||
|
"enable-bootstrap-token-auth": "true",
|
||||||
"secure-port": fmt.Sprintf("%d", cfg.API.BindPort),
|
"secure-port": fmt.Sprintf("%d", cfg.API.BindPort),
|
||||||
"allow-privileged": "true",
|
"allow-privileged": "true",
|
||||||
"kubelet-preferred-address-types": "InternalIP,ExternalIP,Hostname",
|
"kubelet-preferred-address-types": "InternalIP,ExternalIP,Hostname",
|
||||||
@ -164,13 +165,6 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, k8sVersion *versio
|
|||||||
|
|
||||||
command := []string{"kube-apiserver"}
|
command := []string{"kube-apiserver"}
|
||||||
|
|
||||||
// Note: Mutating defaultArguments dynamically must happen before the BuildArgumentListFromMap call below
|
|
||||||
if k8sVersion.AtLeast(kubeadmconstants.UseEnableBootstrapTokenAuthFlagVersion) {
|
|
||||||
defaultArguments["enable-bootstrap-token-auth"] = "true"
|
|
||||||
} else {
|
|
||||||
defaultArguments["experimental-bootstrap-token-auth"] = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.APIServerExtraArgs)...)
|
command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.APIServerExtraArgs)...)
|
||||||
command = append(command, getAuthzParameters(cfg.AuthorizationModes)...)
|
command = append(command, getAuthzParameters(cfg.AuthorizationModes)...)
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func TestGetStaticPodSpecs(t *testing.T) {
|
|||||||
|
|
||||||
// Creates a Master Configuration
|
// Creates a Master Configuration
|
||||||
cfg := &kubeadmapi.MasterConfiguration{
|
cfg := &kubeadmapi.MasterConfiguration{
|
||||||
KubernetesVersion: "v1.7.0",
|
KubernetesVersion: "v1.8.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executes GetStaticPodSpecs
|
// Executes GetStaticPodSpecs
|
||||||
@ -113,7 +113,7 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) {
|
|||||||
|
|
||||||
// Creates a Master Configuration
|
// Creates a Master Configuration
|
||||||
cfg := &kubeadmapi.MasterConfiguration{
|
cfg := &kubeadmapi.MasterConfiguration{
|
||||||
KubernetesVersion: "v1.7.0",
|
KubernetesVersion: "v1.8.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute createStaticPodFunction
|
// Execute createStaticPodFunction
|
||||||
@ -143,7 +143,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
CertificatesDir: testCertsDir,
|
CertificatesDir: testCertsDir,
|
||||||
KubernetesVersion: "v1.7.0",
|
KubernetesVersion: "v1.8.0",
|
||||||
},
|
},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
@ -156,10 +156,10 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
||||||
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
||||||
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
||||||
|
"--enable-bootstrap-token-auth=true",
|
||||||
"--secure-port=123",
|
"--secure-port=123",
|
||||||
"--allow-privileged=true",
|
"--allow-privileged=true",
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--experimental-bootstrap-token-auth=true",
|
|
||||||
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
||||||
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
||||||
"--requestheader-username-headers=X-Remote-User",
|
"--requestheader-username-headers=X-Remote-User",
|
||||||
@ -211,7 +211,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "4.3.2.1"},
|
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "4.3.2.1"},
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
CertificatesDir: testCertsDir,
|
CertificatesDir: testCertsDir,
|
||||||
KubernetesVersion: "v1.7.1",
|
KubernetesVersion: "v1.8.1",
|
||||||
},
|
},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
@ -224,10 +224,10 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
||||||
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
||||||
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
||||||
|
"--enable-bootstrap-token-auth=true",
|
||||||
"--secure-port=123",
|
"--secure-port=123",
|
||||||
"--allow-privileged=true",
|
"--allow-privileged=true",
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--experimental-bootstrap-token-auth=true",
|
|
||||||
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
||||||
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
||||||
"--requestheader-username-headers=X-Remote-User",
|
"--requestheader-username-headers=X-Remote-User",
|
||||||
@ -246,7 +246,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
||||||
CertificatesDir: testCertsDir,
|
CertificatesDir: testCertsDir,
|
||||||
KubernetesVersion: "v1.7.2",
|
KubernetesVersion: "v1.8.0",
|
||||||
},
|
},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
@ -259,10 +259,10 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
||||||
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
||||||
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
||||||
|
"--enable-bootstrap-token-auth=true",
|
||||||
"--secure-port=123",
|
"--secure-port=123",
|
||||||
"--allow-privileged=true",
|
"--allow-privileged=true",
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--experimental-bootstrap-token-auth=true",
|
|
||||||
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
||||||
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
||||||
"--requestheader-username-headers=X-Remote-User",
|
"--requestheader-username-headers=X-Remote-User",
|
||||||
@ -283,7 +283,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
||||||
CertificatesDir: testCertsDir,
|
CertificatesDir: testCertsDir,
|
||||||
KubernetesVersion: "v1.7.3",
|
KubernetesVersion: "v1.8.3",
|
||||||
},
|
},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
@ -296,10 +296,10 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
||||||
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
||||||
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
||||||
|
"--enable-bootstrap-token-auth=true",
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
fmt.Sprintf("--secure-port=%d", 123),
|
||||||
"--allow-privileged=true",
|
"--allow-privileged=true",
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--experimental-bootstrap-token-auth=true",
|
|
||||||
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
||||||
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
||||||
"--requestheader-username-headers=X-Remote-User",
|
"--requestheader-username-headers=X-Remote-User",
|
||||||
@ -320,7 +320,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
Etcd: kubeadmapi.Etcd{CertFile: "fiz", KeyFile: "faz"},
|
||||||
CertificatesDir: testCertsDir,
|
CertificatesDir: testCertsDir,
|
||||||
KubernetesVersion: "v1.7.0",
|
KubernetesVersion: "v1.8.0",
|
||||||
},
|
},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
@ -333,10 +333,10 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||||||
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
"--tls-private-key-file=" + testCertsDir + "/apiserver.key",
|
||||||
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
"--kubelet-client-certificate=" + testCertsDir + "/apiserver-kubelet-client.crt",
|
||||||
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
"--kubelet-client-key=" + testCertsDir + "/apiserver-kubelet-client.key",
|
||||||
|
"--enable-bootstrap-token-auth=true",
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
fmt.Sprintf("--secure-port=%d", 123),
|
||||||
"--allow-privileged=true",
|
"--allow-privileged=true",
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--experimental-bootstrap-token-auth=true",
|
|
||||||
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
"--proxy-client-cert-file=/var/lib/certs/front-proxy-client.crt",
|
||||||
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
"--proxy-client-key-file=/var/lib/certs/front-proxy-client.key",
|
||||||
"--requestheader-username-headers=X-Remote-User",
|
"--requestheader-username-headers=X-Remote-User",
|
||||||
|
@ -8,7 +8,6 @@ go_library(
|
|||||||
"health.go",
|
"health.go",
|
||||||
"policy.go",
|
"policy.go",
|
||||||
"postupgrade.go",
|
"postupgrade.go",
|
||||||
"postupgrade_v17_v18.go",
|
|
||||||
"prepull.go",
|
"prepull.go",
|
||||||
"selfhosted.go",
|
"selfhosted.go",
|
||||||
"staticpods.go",
|
"staticpods.go",
|
||||||
@ -32,14 +31,12 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/bootstrap/api:go_default_library",
|
|
||||||
"//pkg/util/version:go_default_library",
|
"//pkg/util/version:go_default_library",
|
||||||
"//pkg/version:go_default_library",
|
"//pkg/version:go_default_library",
|
||||||
"//vendor/k8s.io/api/apps/v1beta2:go_default_library",
|
"//vendor/k8s.io/api/apps/v1beta2:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
|
@ -64,7 +64,7 @@ func TestEnforceVersionPolicies(t *testing.T) {
|
|||||||
newK8sVersion: "v1.8.3",
|
newK8sVersion: "v1.8.3",
|
||||||
expectedSkippableErrs: 1,
|
expectedSkippableErrs: 1,
|
||||||
},
|
},
|
||||||
{ // new version must be higher than v1.7.0
|
{ // new version must be higher than v1.8.0
|
||||||
vg: &fakeVersionGetter{
|
vg: &fakeVersionGetter{
|
||||||
clusterVersion: "v1.8.3",
|
clusterVersion: "v1.8.3",
|
||||||
kubeletVersion: "v1.8.3",
|
kubeletVersion: "v1.8.3",
|
||||||
|
@ -40,22 +40,6 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.MasterC
|
|||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Bootstrap Tokens graduating to from alpha to beta in the v1.7 -> v1.8 upgrade
|
|
||||||
// That transition requires two minor changes
|
|
||||||
|
|
||||||
// Remove the old ClusterRoleBinding for approving if it already exists due to the reasons outlined in the comment below
|
|
||||||
if err := deleteOldApprovalClusterRoleBindingIfExists(client, k8sVersion); err != nil {
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
// Upgrade the Bootstrap Tokens' authentication group
|
|
||||||
if err := upgradeBootstrapTokens(client, k8sVersion); err != nil {
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
// Upgrade the cluster-info RBAC rules
|
|
||||||
if err := deleteWronglyNamedClusterInfoRBACRules(client, k8sVersion); err != nil {
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create/update RBAC rules that makes the bootstrap tokens able to post CSRs
|
// Create/update RBAC rules that makes the bootstrap tokens able to post CSRs
|
||||||
if err := nodebootstraptoken.AllowBootstrapTokensToPostCSRs(client, k8sVersion); err != nil {
|
if err := nodebootstraptoken.AllowBootstrapTokensToPostCSRs(client, k8sVersion); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
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 upgrade
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
|
||||||
nodebootstraptoken "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
|
||||||
"k8s.io/kubernetes/pkg/util/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
oldClusterInfoRole = "system:bootstrap-signer-clusterinfo"
|
|
||||||
)
|
|
||||||
|
|
||||||
// deleteOldApprovalClusterRoleBindingIfExists exists because the roleRef of the NodeAutoApproveBootstrapClusterRoleBinding changed between
|
|
||||||
// v1.7 and v1.8, and roleRef updates are not possible. So in order to change that binding's roleRef, we have to delete it if it already exists
|
|
||||||
// TODO: When the v1.9 cycle starts, we can remove this logic, as the kubeadm v1.9 CLI doesn't support upgrading from v1.7
|
|
||||||
func deleteOldApprovalClusterRoleBindingIfExists(client clientset.Interface, k8sVersion *version.Version) error {
|
|
||||||
|
|
||||||
// Gate this upgrade behavior for new clusters above v1.9.0-alpha.3 where this change took place
|
|
||||||
if k8sVersion.AtLeast(constants.MinimumCSRAutoApprovalClusterRolesVersion) {
|
|
||||||
|
|
||||||
err := client.RbacV1().ClusterRoleBindings().Delete(nodebootstraptoken.NodeAutoApproveBootstrapClusterRoleBinding, &metav1.DeleteOptions{})
|
|
||||||
// If the binding was not found, happily continue
|
|
||||||
if apierrors.IsNotFound(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// If an unexpected error occurred, return it
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The binding was successfully deleted
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// deleteWronglyNamedClusterInfoRBACRules exists because the cluster-info Role's name changed from "system:bootstrap-signer-clusterinfo" in v1.7 to
|
|
||||||
// "kubeadm:bootstrap-signer-clusterinfo" in v1.8. It was incorrectly prefixed "system:" in v1.7
|
|
||||||
// The old, incorrectly-named Role should be removed and roleRef updates on the binding are not possible. So in order to change that binding's roleRef,
|
|
||||||
// we have to delete it if it already exists
|
|
||||||
// TODO: When the v1.9 cycle starts, we can remove this logic, as the kubeadm v1.9 CLI doesn't support upgrading from v1.7
|
|
||||||
func deleteWronglyNamedClusterInfoRBACRules(client clientset.Interface, k8sVersion *version.Version) error {
|
|
||||||
// Gate this upgrade behavior for new clusters above v1.8.0-beta.0 where this change took place
|
|
||||||
if k8sVersion.AtLeast(constants.UseEnableBootstrapTokenAuthFlagVersion) {
|
|
||||||
|
|
||||||
if err := removeOldRole(client); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := removeOldRoleBinding(client); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The binding was successfully deleted
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeOldRole(client clientset.Interface) error {
|
|
||||||
err := client.RbacV1().Roles(metav1.NamespacePublic).Delete(oldClusterInfoRole, &metav1.DeleteOptions{})
|
|
||||||
// If the binding was not found, happily continue
|
|
||||||
if apierrors.IsNotFound(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// If an unexpected error occurred, return it
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// The role was successfully deleted
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeOldRoleBinding(client clientset.Interface) error {
|
|
||||||
err := client.RbacV1().RoleBindings(metav1.NamespacePublic).Delete(clusterinfo.BootstrapSignerClusterRoleName, &metav1.DeleteOptions{})
|
|
||||||
// If the binding was not found, happily continue
|
|
||||||
if apierrors.IsNotFound(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// If an unexpected error occurred, return it
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// The binding was successfully removed
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// upgradeBootstrapTokens handles the transition from alpha bootstrap tokens to beta. There isn't much that is changing,
|
|
||||||
// but the group that a Bootstrap Token authenticates as changes from "system:bootstrappers" (alpha) in v1.7 to
|
|
||||||
// "system:bootstrappers:kubeadm:default-node-token" (beta). To handle this transition correctly, the RBAC bindings earlier
|
|
||||||
// bound to "system:bootstrappers" are now bound to "system:bootstrappers:kubeadm:default-node-token". To make v1.7 tokens
|
|
||||||
// still valid in v1.8; this code makes sure that all tokens that were used for authentication in v1.7 have the right group
|
|
||||||
// bound to it in v1.8.
|
|
||||||
// TODO: When the v1.9 cycle starts, we can remove this logic, as the kubeadm v1.9 CLI doesn't support upgrading from v1.7
|
|
||||||
func upgradeBootstrapTokens(client clientset.Interface, k8sVersion *version.Version) error {
|
|
||||||
|
|
||||||
// Gate this upgrade behavior for new clusters above v1.8.0-beta.0; where this BT change took place
|
|
||||||
if k8sVersion.AtLeast(constants.UseEnableBootstrapTokenAuthFlagVersion) {
|
|
||||||
|
|
||||||
tokenSelector := fields.SelectorFromSet(
|
|
||||||
map[string]string{
|
|
||||||
api.SecretTypeField: string(bootstrapapi.SecretTypeBootstrapToken),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
listOptions := metav1.ListOptions{
|
|
||||||
FieldSelector: tokenSelector.String(),
|
|
||||||
}
|
|
||||||
|
|
||||||
secrets, err := client.CoreV1().Secrets(metav1.NamespaceSystem).List(listOptions)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to list bootstrap tokens: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
errs := []error{}
|
|
||||||
for _, secret := range secrets.Items {
|
|
||||||
// If this Bootstrap Token is used for authentication, the permissions it had in v1.7 should be preserved
|
|
||||||
if bytes.Equal(secret.Data[bootstrapapi.BootstrapTokenUsageAuthentication], []byte("true")) {
|
|
||||||
|
|
||||||
secret.Data[bootstrapapi.BootstrapTokenExtraGroupsKey] = []byte(constants.GetNodeBootstrapTokenAuthGroup(k8sVersion))
|
|
||||||
|
|
||||||
// Update the Bootstrap Token Secret
|
|
||||||
if _, err := client.CoreV1().Secrets(metav1.NamespaceSystem).Update(&secret); err != nil {
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors.NewAggregate(errs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user