mirror of https://github.com/k3s-io/k3s
Merge pull request #40698 from luxas/kubeadm_fix_authz_default
Automatic merge from submit-queue (batch tested with PRs 40707, 40698) kubeadm: Default to control plane v1.6.0-alpha.1 and using RBAC Also use constants for authz modes **What this PR does / why we need it**: Defaults to v1.6.0-alpha.1 (will be cut later today) because the certificates API group has been upgraded to beta, so `kubeadm join` at HEAD doesn't work on a `v1.5` cluster anyway. By defaulting to v1.6.0-alpha.1, we can focus totally on v1.6 for kubeadm at HEAD, we don't support other versions in the upcoming v1.6 kubeadm release because of the alpha -> beta upgrades. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: **Release note**: ```release-note NONE ``` @mikedanese @pirespull/6/head
commit
8ffada6699
|
@ -21,13 +21,12 @@ import "k8s.io/apimachinery/pkg/runtime"
|
||||||
const (
|
const (
|
||||||
DefaultServiceDNSDomain = "cluster.local"
|
DefaultServiceDNSDomain = "cluster.local"
|
||||||
DefaultServicesSubnet = "10.96.0.0/12"
|
DefaultServicesSubnet = "10.96.0.0/12"
|
||||||
DefaultKubernetesVersion = "stable"
|
DefaultKubernetesVersion = "latest"
|
||||||
// This is only for clusters without internet, were the latest stable version can't be determined
|
// This is only for clusters without internet, were the latest stable version can't be determined
|
||||||
DefaultKubernetesFallbackVersion = "v1.5.2"
|
DefaultKubernetesFallbackVersion = "v1.6.0-alpha.1"
|
||||||
DefaultAPIBindPort = 6443
|
DefaultAPIBindPort = 6443
|
||||||
DefaultDiscoveryBindPort = 9898
|
DefaultDiscoveryBindPort = 9898
|
||||||
// TODO: Default this to RBAC when DefaultKubernetesFallbackVersion is v1.6-something
|
DefaultAuthorizationMode = "RBAC"
|
||||||
DefaultAuthorizationMode = "AlwaysAllow"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||||
|
|
|
@ -23,14 +23,14 @@ import (
|
||||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Maximum version when using AllowAll as the default authz mode. Everything above this will use RBAC by default.
|
minK8sVersion = semver.MustParse(kubeadmconstants.MinimumControlPlaneVersion)
|
||||||
allowAllMaxVersion = semver.MustParse("1.6.0-alpha.0")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
|
@ -53,16 +53,18 @@ func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg.KubernetesVersion = ver
|
cfg.KubernetesVersion = ver
|
||||||
fmt.Println("[init] Using Kubernetes version:", ver)
|
|
||||||
|
|
||||||
// Omit the "v" in the beginning, otherwise semver will fail
|
// Omit the "v" in the beginning, otherwise semver will fail
|
||||||
// If the version is newer than the specified version, RBAC v1beta1 support is enabled in the apiserver so we can default to RBAC
|
|
||||||
k8sVersion, err := semver.Parse(cfg.KubernetesVersion[1:])
|
k8sVersion, err := semver.Parse(cfg.KubernetesVersion[1:])
|
||||||
if k8sVersion.GT(allowAllMaxVersion) {
|
if err != nil {
|
||||||
cfg.AuthorizationMode = "RBAC"
|
return fmt.Errorf("couldn't parse kubernetes version %q: %v", cfg.KubernetesVersion, err)
|
||||||
|
}
|
||||||
|
if k8sVersion.LT(minK8sVersion) {
|
||||||
|
return fmt.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= v1.6.0-alpha.1. Current version: %s", cfg.KubernetesVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[init] Using Authorization mode:", cfg.AuthorizationMode)
|
fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
|
||||||
|
fmt.Printf("[init] Using Authorization mode: %s\n", 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 != "" {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import (
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/flags"
|
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/flags"
|
||||||
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"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"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
|
||||||
|
@ -219,7 +220,7 @@ func (i *Init) Run(out io.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if i.cfg.AuthorizationMode == "RBAC" {
|
if i.cfg.AuthorizationMode == kubeadmconstants.AuthzModeRBAC {
|
||||||
err = apiconfig.CreateBootstrapRBACClusterRole(client)
|
err = apiconfig.CreateBootstrapRBACClusterRole(client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -28,4 +28,15 @@ const (
|
||||||
APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client"
|
APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client"
|
||||||
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
|
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
|
||||||
APIServerKubeletClientKeyName = "apiserver-kubelet-client.key"
|
APIServerKubeletClientKeyName = "apiserver-kubelet-client.key"
|
||||||
|
|
||||||
|
// TODO: These constants should actually come from pkg/kubeapiserver/authorizer, but we can't vendor that package in now
|
||||||
|
// because of all the other sub-packages that would get vendored. To fix this, a pkg/kubeapiserver/authorizer/modes package
|
||||||
|
// or similar should exist that only has these constants; then we can vendor it.
|
||||||
|
AuthzModeAlwaysAllow = "AlwaysAllow"
|
||||||
|
AuthzModeABAC = "ABAC"
|
||||||
|
AuthzModeRBAC = "RBAC"
|
||||||
|
AuthzModeWebhook = "Webhook"
|
||||||
|
|
||||||
|
// Important: a "v"-prefix shouldn't exist here; semver doesn't allow that
|
||||||
|
MinimumControlPlaneVersion = "1.6.0-alpha.1"
|
||||||
)
|
)
|
||||||
|
|
|
@ -31,7 +31,6 @@ go_library(
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset: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",
|
||||||
"//vendor:github.com/blang/semver",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
|
|
@ -32,8 +32,6 @@ import (
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
||||||
api "k8s.io/kubernetes/pkg/api/v1"
|
api "k8s.io/kubernetes/pkg/api/v1"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
|
||||||
"github.com/blang/semver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Static pod definitions in golang form are included below so that `kubeadm init` can get going.
|
// Static pod definitions in golang form are included below so that `kubeadm init` can get going.
|
||||||
|
@ -54,14 +52,6 @@ const (
|
||||||
authorizationWebhookConfigFile = "webhook_authz.conf"
|
authorizationWebhookConfigFile = "webhook_authz.conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// Minimum version of kube-apiserver that supports --kubelet-preferred-address-types
|
|
||||||
preferredAddressAPIServerMinVersion = semver.MustParse("1.5.0")
|
|
||||||
|
|
||||||
// Minimum version of kube-apiserver that has to have --anonymous-auth=false set
|
|
||||||
anonAuthDisableAPIServerMinVersion = semver.MustParse("1.5.0")
|
|
||||||
)
|
|
||||||
|
|
||||||
// WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk
|
// WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk
|
||||||
// where kubelet will pick and schedule them.
|
// where kubelet will pick and schedule them.
|
||||||
func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
|
func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
|
@ -328,14 +318,15 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [
|
||||||
fmt.Sprintf("--secure-port=%d", cfg.API.Port),
|
fmt.Sprintf("--secure-port=%d", cfg.API.Port),
|
||||||
"--allow-privileged",
|
"--allow-privileged",
|
||||||
"--storage-backend=etcd3",
|
"--storage-backend=etcd3",
|
||||||
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
)
|
)
|
||||||
|
|
||||||
if cfg.AuthorizationMode != "" {
|
if cfg.AuthorizationMode != "" {
|
||||||
command = append(command, "--authorization-mode="+cfg.AuthorizationMode)
|
command = append(command, "--authorization-mode="+cfg.AuthorizationMode)
|
||||||
switch cfg.AuthorizationMode {
|
switch cfg.AuthorizationMode {
|
||||||
case "ABAC":
|
case kubeadmconstants.AuthzModeABAC:
|
||||||
command = append(command, "--authorization-policy-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationPolicyFile))
|
command = append(command, "--authorization-policy-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationPolicyFile))
|
||||||
case "Webhook":
|
case kubeadmconstants.AuthzModeWebhook:
|
||||||
command = append(command, "--authorization-webhook-config-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationWebhookConfigFile))
|
command = append(command, "--authorization-webhook-config-file="+path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, authorizationWebhookConfigFile))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,23 +340,6 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.KubernetesVersion) != 0 {
|
|
||||||
// If the k8s version is v1.5-something, this argument is set and makes `kubectl logs` and `kubectl exec`
|
|
||||||
// work on bare-metal where hostnames aren't usually resolvable
|
|
||||||
// Omit the "v" in the beginning, otherwise semver will fail
|
|
||||||
k8sVersion, err := semver.Parse(cfg.KubernetesVersion[1:])
|
|
||||||
|
|
||||||
// If the k8s version is greater than this version, it supports telling it which way it should contact kubelets
|
|
||||||
if err == nil && k8sVersion.GTE(preferredAddressAPIServerMinVersion) {
|
|
||||||
command = append(command, "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname")
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a critical "bugfix". Any version above this is vulnerable unless a RBAC/ABAC-authorizer is provided (which kubeadm doesn't for the time being)
|
|
||||||
if err == nil && k8sVersion.GTE(anonAuthDisableAPIServerMinVersion) {
|
|
||||||
command = append(command, "--anonymous-auth=false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user decided to use an external etcd cluster
|
// Check if the user decided to use an external etcd cluster
|
||||||
if len(cfg.Etcd.Endpoints) > 0 {
|
if len(cfg.Etcd.Endpoints) > 0 {
|
||||||
command = append(command, fmt.Sprintf("--etcd-servers=%s", strings.Join(cfg.Etcd.Endpoints, ",")))
|
command = append(command, fmt.Sprintf("--etcd-servers=%s", strings.Join(cfg.Etcd.Endpoints, ",")))
|
||||||
|
|
|
@ -382,6 +382,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
fmt.Sprintf("--secure-port=%d", 123),
|
||||||
"--allow-privileged",
|
"--allow-privileged",
|
||||||
"--storage-backend=etcd3",
|
"--storage-backend=etcd3",
|
||||||
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--etcd-servers=http://127.0.0.1:2379",
|
"--etcd-servers=http://127.0.0.1:2379",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -405,6 +406,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
fmt.Sprintf("--secure-port=%d", 123),
|
||||||
"--allow-privileged",
|
"--allow-privileged",
|
||||||
"--storage-backend=etcd3",
|
"--storage-backend=etcd3",
|
||||||
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--advertise-address=foo",
|
"--advertise-address=foo",
|
||||||
"--etcd-servers=http://127.0.0.1:2379",
|
"--etcd-servers=http://127.0.0.1:2379",
|
||||||
},
|
},
|
||||||
|
@ -430,39 +432,12 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
fmt.Sprintf("--secure-port=%d", 123),
|
||||||
"--allow-privileged",
|
"--allow-privileged",
|
||||||
"--storage-backend=etcd3",
|
"--storage-backend=etcd3",
|
||||||
|
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||||
"--etcd-servers=http://127.0.0.1:2379",
|
"--etcd-servers=http://127.0.0.1:2379",
|
||||||
"--etcd-certfile=fiz",
|
"--etcd-certfile=fiz",
|
||||||
"--etcd-keyfile=faz",
|
"--etcd-keyfile=faz",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Make sure --kubelet-preferred-address-types
|
|
||||||
{
|
|
||||||
cfg: &kubeadmapi.MasterConfiguration{
|
|
||||||
API: kubeadm.API{Port: 123, AdvertiseAddresses: []string{"foo"}},
|
|
||||||
Networking: kubeadm.Networking{ServiceSubnet: "bar"},
|
|
||||||
KubernetesVersion: "v1.5.3",
|
|
||||||
},
|
|
||||||
expected: []string{
|
|
||||||
"kube-apiserver",
|
|
||||||
"--insecure-bind-address=127.0.0.1",
|
|
||||||
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
|
|
||||||
"--service-cluster-ip-range=bar",
|
|
||||||
"--service-account-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
|
||||||
"--client-ca-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/ca.crt",
|
|
||||||
"--tls-cert-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.crt",
|
|
||||||
"--tls-private-key-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver.key",
|
|
||||||
"--kubelet-client-certificate=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.crt",
|
|
||||||
"--kubelet-client-key=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/apiserver-kubelet-client.key",
|
|
||||||
"--token-auth-file=" + kubeadmapi.GlobalEnvParams.HostPKIPath + "/tokens.csv",
|
|
||||||
fmt.Sprintf("--secure-port=%d", 123),
|
|
||||||
"--allow-privileged",
|
|
||||||
"--storage-backend=etcd3",
|
|
||||||
"--advertise-address=foo",
|
|
||||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
|
||||||
"--anonymous-auth=false",
|
|
||||||
"--etcd-servers=http://127.0.0.1:2379",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
|
|
Loading…
Reference in New Issue