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 (
|
||||
DefaultServiceDNSDomain = "cluster.local"
|
||||
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
|
||||
DefaultKubernetesFallbackVersion = "v1.5.2"
|
||||
DefaultKubernetesFallbackVersion = "v1.6.0-alpha.1"
|
||||
DefaultAPIBindPort = 6443
|
||||
DefaultDiscoveryBindPort = 9898
|
||||
// TODO: Default this to RBAC when DefaultKubernetesFallbackVersion is v1.6-something
|
||||
DefaultAuthorizationMode = "AlwaysAllow"
|
||||
DefaultAuthorizationMode = "RBAC"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
|
|
|
@ -23,14 +23,14 @@ import (
|
|||
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
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"
|
||||
|
||||
"github.com/blang/semver"
|
||||
)
|
||||
|
||||
var (
|
||||
// Maximum version when using AllowAll as the default authz mode. Everything above this will use RBAC by default.
|
||||
allowAllMaxVersion = semver.MustParse("1.6.0-alpha.0")
|
||||
minK8sVersion = semver.MustParse(kubeadmconstants.MinimumControlPlaneVersion)
|
||||
)
|
||||
|
||||
func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
||||
|
@ -53,16 +53,18 @@ func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
|||
}
|
||||
}
|
||||
cfg.KubernetesVersion = ver
|
||||
fmt.Println("[init] Using Kubernetes version:", ver)
|
||||
|
||||
// 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:])
|
||||
if k8sVersion.GT(allowAllMaxVersion) {
|
||||
cfg.AuthorizationMode = "RBAC"
|
||||
if err != nil {
|
||||
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.
|
||||
if cfg.CloudProvider != "" {
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
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/cmd/flags"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
|
||||
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
|
||||
|
@ -219,7 +220,7 @@ func (i *Init) Run(out io.Writer) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if i.cfg.AuthorizationMode == "RBAC" {
|
||||
if i.cfg.AuthorizationMode == kubeadmconstants.AuthzModeRBAC {
|
||||
err = apiconfig.CreateBootstrapRBACClusterRole(client)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -28,4 +28,15 @@ const (
|
|||
APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client"
|
||||
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
|
||||
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/kubectl/cmd/util: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/resource",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
|
|
|
@ -32,8 +32,6 @@ import (
|
|||
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
||||
api "k8s.io/kubernetes/pkg/api/v1"
|
||||
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.
|
||||
|
@ -54,14 +52,6 @@ const (
|
|||
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
|
||||
// where kubelet will pick and schedule them.
|
||||
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),
|
||||
"--allow-privileged",
|
||||
"--storage-backend=etcd3",
|
||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||
)
|
||||
|
||||
if cfg.AuthorizationMode != "" {
|
||||
command = append(command, "--authorization-mode="+cfg.AuthorizationMode)
|
||||
switch cfg.AuthorizationMode {
|
||||
case "ABAC":
|
||||
case kubeadmconstants.AuthzModeABAC:
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
if len(cfg.Etcd.Endpoints) > 0 {
|
||||
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),
|
||||
"--allow-privileged",
|
||||
"--storage-backend=etcd3",
|
||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||
"--etcd-servers=http://127.0.0.1:2379",
|
||||
},
|
||||
},
|
||||
|
@ -405,6 +406,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
"--storage-backend=etcd3",
|
||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||
"--advertise-address=foo",
|
||||
"--etcd-servers=http://127.0.0.1:2379",
|
||||
},
|
||||
|
@ -430,39 +432,12 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
fmt.Sprintf("--secure-port=%d", 123),
|
||||
"--allow-privileged",
|
||||
"--storage-backend=etcd3",
|
||||
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
|
||||
"--etcd-servers=http://127.0.0.1:2379",
|
||||
"--etcd-certfile=fiz",
|
||||
"--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 {
|
||||
|
|
Loading…
Reference in New Issue