Remove UseServiceAccountIAM feature flag and rename feature to UseServiceAccountExternalPermissions

This commit is contained in:
Ole Markus With 2021-08-05 20:33:54 +02:00
parent 82e4e5ab77
commit 0439bb0d76
30 changed files with 84 additions and 67 deletions

View File

@ -392,14 +392,8 @@ func TestPrivateDns2(t *testing.T) {
runTestTerraformAWS(t)
}
// TestDiscoveryFeatureGate runs a simple configuration, but with UseServiceAccountIAM and the ServiceAccountIssuerDiscovery feature gate enabled
// TestDiscoveryFeatureGate runs a simple configuration, but with UseServiceAccountExternalPermissions and the ServiceAccountIssuerDiscovery feature gate enabled
func TestDiscoveryFeatureGate(t *testing.T) {
featureflag.ParseFlags("+UseServiceAccountIAM")
unsetFeatureFlags := func() {
featureflag.ParseFlags("-UseServiceAccountIAM")
}
defer unsetFeatureFlags()
newIntegrationTest("minimal.example.com", "public-jwks-apiserver").
withServiceAccountRole("dns-controller.kube-system", true).
withOIDCDiscovery().
@ -416,14 +410,8 @@ func TestVFSServiceAccountIssuerDiscovery(t *testing.T) {
}
// TestAWSLBController runs a simple configuration, but with AWS LB controller and UseServiceAccountIAM enabled
// TestAWSLBController runs a simple configuration, but with AWS LB controller and UseServiceAccountExternalPermissions enabled
func TestAWSLBController(t *testing.T) {
featureflag.ParseFlags("+UseServiceAccountIAM")
unsetFeatureFlags := func() {
featureflag.ParseFlags("-UseServiceAccountIAM")
}
defer unsetFeatureFlags()
newIntegrationTest("minimal.example.com", "aws-lb-controller").
withOIDCDiscovery().
withServiceAccountRole("dns-controller.kube-system", true).
@ -446,12 +434,6 @@ func TestManyAddons(t *testing.T) {
}
func TestManyAddonsCCMIRSA(t *testing.T) {
featureflag.ParseFlags("+UseServiceAccountIAM,+EnableExternalCloudController")
unsetFeatureFlags := func() {
featureflag.ParseFlags("-UseServiceAccountIAM,-EnableExternalCloudController")
}
defer unsetFeatureFlags()
newIntegrationTest("minimal.example.com", "many-addons-ccm-irsa").
withOIDCDiscovery().
withServiceAccountRole("dns-controller.kube-system", true).
@ -474,11 +456,6 @@ func TestManyAddonsCCMIRSA(t *testing.T) {
}
func TestCCM(t *testing.T) {
featureflag.ParseFlags("+EnableExternalCloudController")
unsetFeatureFlags := func() {
featureflag.ParseFlags("-EnableExternalCloudController")
}
defer unsetFeatureFlags()
newIntegrationTest("minimal.example.com", "many-addons-ccm").
withAddons(
"aws-ebs-csi-driver.addons.k8s.io-k8s-1.17",

View File

@ -21,6 +21,20 @@ spec:
httpTokens: optional
```
## External ServiceAccountPermissions
Many of kOps addons can now make direct use of external permissions.
This can be enabled by adding the following to the Cluster spec:
```
spec:
iam:
useServiceAcountExternalPermissions: true
```
Currently this is only available using the AWS cloud provider.
## Other significant changes
* New clusters on AWS will no longer provision an SSH public key by default. To provision

View File

@ -1206,6 +1206,12 @@ spec:
- namespace
type: object
type: array
useServiceAccountExternalPermissions:
description: UseServiceAccountExternalPermissions determines if
managed ServiceAccounts will use external permissions directly.
If this is set to false, ServiceAccounts will assume external
permissions from the instances they run on.
type: boolean
required:
- legacy
type: object

View File

@ -304,6 +304,9 @@ type IAMSpec struct {
Legacy bool `json:"legacy"`
AllowContainerRegistry bool `json:"allowContainerRegistry,omitempty"`
PermissionsBoundary *string `json:"permissionsBoundary,omitempty"`
// UseServiceAccountExternalPermissions determines if managed ServiceAccounts will use external permissions directly.
// If this is set to false, ServiceAccounts will assume external permissions from the instances they run on.
UseServiceAccountExternalPermissions *bool `json:"useServiceAccountExternalPermissions,omitempty"`
// ServiceAccountExternalPermissions defines the relatinship between Kubernetes ServiceAccounts and permissions with external resources.
ServiceAccountExternalPermissions []ServiceAccountExternalPermission `json:"serviceAccountExternalPermissions,omitempty"`
}

View File

@ -301,6 +301,9 @@ type IAMSpec struct {
Legacy bool `json:"legacy"`
AllowContainerRegistry bool `json:"allowContainerRegistry,omitempty"`
PermissionsBoundary *string `json:"permissionsBoundary,omitempty"`
// UseServiceAccountExternalPermissions determines if managed ServiceAccounts will use external permissions directly.
// If this is set to false, ServiceAccounts will assume external permissions from the instances they run on.
UseServiceAccountExternalPermissions *bool `json:"useServiceAccountExternalPermissions,omitempty"`
// ServiceAccountExternalPermissions defines the relatinship between Kubernetes ServiceAccounts and permissions with external resources.
ServiceAccountExternalPermissions []ServiceAccountExternalPermission `json:"serviceAccountExternalPermissions,omitempty"`
}

View File

@ -3960,6 +3960,7 @@ func autoConvert_v1alpha2_IAMSpec_To_kops_IAMSpec(in *IAMSpec, out *kops.IAMSpec
out.Legacy = in.Legacy
out.AllowContainerRegistry = in.AllowContainerRegistry
out.PermissionsBoundary = in.PermissionsBoundary
out.UseServiceAccountExternalPermissions = in.UseServiceAccountExternalPermissions
if in.ServiceAccountExternalPermissions != nil {
in, out := &in.ServiceAccountExternalPermissions, &out.ServiceAccountExternalPermissions
*out = make([]kops.ServiceAccountExternalPermission, len(*in))
@ -3983,6 +3984,7 @@ func autoConvert_kops_IAMSpec_To_v1alpha2_IAMSpec(in *kops.IAMSpec, out *IAMSpec
out.Legacy = in.Legacy
out.AllowContainerRegistry = in.AllowContainerRegistry
out.PermissionsBoundary = in.PermissionsBoundary
out.UseServiceAccountExternalPermissions = in.UseServiceAccountExternalPermissions
if in.ServiceAccountExternalPermissions != nil {
in, out := &in.ServiceAccountExternalPermissions, &out.ServiceAccountExternalPermissions
*out = make([]ServiceAccountExternalPermission, len(*in))

View File

@ -2000,6 +2000,11 @@ func (in *IAMSpec) DeepCopyInto(out *IAMSpec) {
*out = new(string)
**out = **in
}
if in.UseServiceAccountExternalPermissions != nil {
in, out := &in.UseServiceAccountExternalPermissions, &out.UseServiceAccountExternalPermissions
*out = new(bool)
**out = **in
}
if in.ServiceAccountExternalPermissions != nil {
in, out := &in.ServiceAccountExternalPermissions, &out.ServiceAccountExternalPermissions
*out = make([]ServiceAccountExternalPermission, len(*in))

View File

@ -2150,6 +2150,11 @@ func (in *IAMSpec) DeepCopyInto(out *IAMSpec) {
*out = new(string)
**out = **in
}
if in.UseServiceAccountExternalPermissions != nil {
in, out := &in.UseServiceAccountExternalPermissions, &out.UseServiceAccountExternalPermissions
*out = new(bool)
**out = **in
}
if in.ServiceAccountExternalPermissions != nil {
in, out := &in.ServiceAccountExternalPermissions, &out.ServiceAccountExternalPermissions
*out = make([]ServiceAccountExternalPermission, len(*in))

View File

@ -87,8 +87,6 @@ var (
TerraformJSON = new("TerraformJSON", Bool(false))
// ClusterAddons activates experimental cluster-addons support
ClusterAddons = new("ClusterAddons", Bool(false))
// UseServiceAccountIAM controls whether we use pod-level IAM permissions for our system pods and kOps addons.
UseServiceAccountIAM = new("UseServiceAccountIAM", Bool(false))
// Azure toggles the Azure support.
Azure = new("Azure", Bool(false))
// KopsControllerStateStore enables fetching the kops state from kops-controller, instead of requiring access to S3/GCS/etc.

1
pkg/model/BUILD.bazel generated
View File

@ -22,7 +22,6 @@ go_library(
"//pkg/apis/kops/registry:go_default_library",
"//pkg/apis/kops/util:go_default_library",
"//pkg/apis/nodeup:go_default_library",
"//pkg/featureflag:go_default_library",
"//pkg/kopscodecs:go_default_library",
"//pkg/model/components:go_default_library",
"//pkg/model/iam:go_default_library",

View File

@ -224,10 +224,10 @@ func (b *IAMModelBuilder) buildIAMRole(role iam.Subject, iamName string, c *fi.M
func (b *IAMModelBuilder) buildIAMRolePolicy(role iam.Subject, iamName string, iamRole *awstasks.IAMRole, c *fi.ModelBuilderContext) error {
iamPolicy := &iam.PolicyResource{
Builder: &iam.PolicyBuilder{
Cluster: b.Cluster,
Role: role,
Region: b.Region,
UseServiceAccountIAM: b.UseServiceAccountIAM(),
Cluster: b.Cluster,
Role: role,
Region: b.Region,
UseServiceAccountExternalPermisssions: b.UseServiceAccountExternalPermissions(),
},
}

View File

@ -8,7 +8,6 @@ go_library(
deps = [
"//channels/pkg/api:go_default_library",
"//pkg/assets:go_default_library",
"//pkg/featureflag:go_default_library",
"//pkg/kubemanifest:go_default_library",
"//pkg/model:go_default_library",
"//pkg/model/components/addonmanifests/awscloudcontrollermanager:go_default_library",

View File

@ -29,7 +29,7 @@ import (
// Remap remaps the dns-controller addon
func Remap(context *model.KopsModelContext, addon *addonsapi.AddonSpec, objects []*kubemanifest.Object) error {
if !context.UseServiceAccountIAM() {
if !context.UseServiceAccountExternalPermissions() {
return nil
}

View File

@ -25,7 +25,6 @@ import (
"k8s.io/klog/v2"
addonsapi "k8s.io/kops/channels/pkg/api"
"k8s.io/kops/pkg/assets"
"k8s.io/kops/pkg/featureflag"
"k8s.io/kops/pkg/kubemanifest"
"k8s.io/kops/pkg/model"
"k8s.io/kops/pkg/model/components/addonmanifests/awscloudcontrollermanager"
@ -83,7 +82,7 @@ func RemapAddonManifest(addon *addonsapi.AddonSpec, context *model.KopsModelCont
}
func addServiceAccountRole(context *model.KopsModelContext, objects kubemanifest.ObjectList) error {
if !featureflag.UseServiceAccountIAM.Enabled() {
if !context.UseServiceAccountExternalPermissions() {
return nil
}

View File

@ -24,7 +24,6 @@ import (
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/model"
"k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/pkg/featureflag"
"k8s.io/kops/pkg/model/components"
"k8s.io/kops/pkg/model/iam"
nodeidentityaws "k8s.io/kops/pkg/nodeidentity/aws"
@ -414,7 +413,9 @@ func (b *KopsModelContext) NodePortRange() (utilnet.PortRange, error) {
return defaultServiceNodePortRange, nil
}
// UseServiceAccountIAM returns true if we are using service-account bound IAM roles.
func (b *KopsModelContext) UseServiceAccountIAM() bool {
return featureflag.UseServiceAccountIAM.Enabled()
// UseServiceAccountExternalPermissions returns true if we are using service-account bound IAM roles.
func (b *KopsModelContext) UseServiceAccountExternalPermissions() bool {
return b.Cluster.Spec.IAM != nil &&
fi.BoolValue(b.Cluster.Spec.IAM.UseServiceAccountExternalPermissions)
}

View File

@ -230,13 +230,13 @@ func (l *Statement) Equal(r *Statement) bool {
// PolicyBuilder struct defines all valid fields to be used when building the
// AWS IAM policy document for a given instance group role.
type PolicyBuilder struct {
Cluster *kops.Cluster
HostedZoneID string
KMSKeys []string
Region string
ResourceARN *string
Role Subject
UseServiceAccountIAM bool
Cluster *kops.Cluster
HostedZoneID string
KMSKeys []string
Region string
ResourceARN *string
Role Subject
UseServiceAccountExternalPermisssions bool
}
// BuildAWSPolicy builds a set of IAM policy statements based on the
@ -325,7 +325,7 @@ func (r *NodeRoleMaster) BuildAWSPolicy(b *PolicyBuilder) (*Policy, error) {
addKMSIAMPolicies(p, stringorslice.Slice(b.KMSKeys))
}
// Protokube needs dns-controller permissions in instance role even if UseServiceAccountIAM.
// Protokube needs dns-controller permissions in instance role even if UseServiceAccountExternalPermissions.
AddDNSControllerPermissions(b, p)
// If cluster does not use external CCM, the master IAM Role needs CCM permissions
@ -334,7 +334,7 @@ func (r *NodeRoleMaster) BuildAWSPolicy(b *PolicyBuilder) (*Policy, error) {
AddLegacyCCMPermissions(p)
}
if !b.UseServiceAccountIAM {
if !b.UseServiceAccountExternalPermisssions {
esc := b.Cluster.Spec.SnapshotController != nil &&
fi.BoolValue(b.Cluster.Spec.SnapshotController.Enabled)
AddAWSEBSCSIDriverPermissions(p, esc)

View File

@ -49,7 +49,6 @@ fi
if [[ ${KOPS_IRSA-} = true ]]; then
OVERRIDES="${OVERRIDES-} --override=cluster.spec.serviceAccountIssuerDiscovery.discoveryStore=${DISCOVERY_STORE}/${CLUSTER_NAME}/discovery"
OVERRIDES="${OVERRIDES} --override=cluster.spec.serviceAccountIssuerDiscovery.enableAWSOIDCProvider=true"
KOPS_FEATURE_FLAGS="UseServiceAccountIAM,${KOPS_FEATURE_FLAGS}"
fi
export GO111MODULE=on

View File

@ -51,6 +51,7 @@ spec:
version: 3.4.13
iam:
legacy: false
useServiceAccountExternalPermissions: true
keyStore: memfs://clusters.example.com/minimal.example.com/pki
kubeAPIServer:
allowPrivileged: true

View File

@ -22,7 +22,8 @@ spec:
- instanceGroup: master-us-test-1a
name: us-test-1a
name: events
iam: {}
iam:
useServiceAccountExternalPermissions: true
kubelet:
anonymousAuth: false
kubernetesVersion: v1.21.0

View File

@ -63,6 +63,7 @@ spec:
version: 3.4.13
iam:
legacy: false
useServiceAccountExternalPermissions: true
keyStore: memfs://clusters.example.com/minimal.example.com/pki
kubeAPIServer:
allowPrivileged: true

View File

@ -29,7 +29,8 @@ spec:
- instanceGroup: master-us-test-1a
name: us-test-1a
name: events
iam: {}
iam:
useServiceAccountExternalPermissions: true
kubelet:
anonymousAuth: false
kubernetesVersion: v1.21.0

View File

@ -56,6 +56,7 @@ spec:
version: 3.4.13
iam:
legacy: false
useServiceAccountExternalPermissions: true
keyStore: memfs://clusters.example.com/minimal.example.com/pki
kubeAPIServer:
allowPrivileged: true

View File

@ -18,7 +18,8 @@ spec:
- instanceGroup: master-us-test-1a
name: us-test-1a
name: events
iam: {}
iam:
useServiceAccountExternalPermissions: true
kubeAPIServer:
featureGates:
ServiceAccountIssuerDiscovery: "true"

View File

@ -415,12 +415,12 @@ spec:
topologyKey: topology.kubernetes.io/zone
nodeSelector:
kubernetes.io/os: linux
{{ if not UseServiceAccountIAM }}
{{ if not UseServiceAccountExternalPermissions }}
node-role.kubernetes.io/master: ""
{{ end }}
serviceAccountName: ebs-csi-controller-sa
priorityClassName: system-cluster-critical
{{ if not UseServiceAccountIAM }}
{{ if not UseServiceAccountExternalPermissions }}
tolerations:
- operator: Exists
{{ end }}

View File

@ -264,7 +264,7 @@ spec:
topologyKey: topology.kubernetes.io/zone
priorityClassName: system-cluster-critical
serviceAccountName: cluster-autoscaler
{{ if not UseServiceAccountIAM }}
{{ if not UseServiceAccountExternalPermissions }}
tolerations:
- operator: "Exists"
key: node-role.kubernetes.io/master

View File

@ -202,7 +202,7 @@ spec:
requests:
cpu: {{ .CPURequest }}
memory: {{ .MemoryRequest }}
{{ if not UseServiceAccountIAM }}
{{ if not UseServiceAccountExternalPermissions }}
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:

View File

@ -442,7 +442,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
}
// Generate dns-controller ServiceAccount IAM permissions
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &dnscontroller.ServiceAccount{})
}
}
@ -502,7 +502,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
}
}
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &clusterautoscaler.ServiceAccount{})
}
@ -562,7 +562,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
})
}
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &nodeterminationhandler.ServiceAccount{})
}
}
@ -604,7 +604,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
}
// Generate aws-load-balancer-controller ServiceAccount IAM permissions
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &awsloadbalancercontroller.ServiceAccount{})
}
}
@ -906,7 +906,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
Id: id,
})
}
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &awscloudcontrollermanager.ServiceAccount{})
}
}
@ -925,7 +925,7 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
}
// Generate aws-load-balancer-controller ServiceAccount IAM permissions
if b.UseServiceAccountIAM() {
if b.UseServiceAccountExternalPermissions() {
serviceAccountRoles = append(serviceAccountRoles, &awsebscsidriver.ServiceAccount{})
}
}

View File

@ -59,9 +59,9 @@ func TestBootstrapChannelBuilder_ServiceAccountIAM(t *testing.T) {
h.SetupMockAWS()
featureflag.ParseFlags("+UseServiceAccountIAM")
featureflag.ParseFlags("+UseServiceAccountExternalPermissions")
unsetFeatureFlag := func() {
featureflag.ParseFlags("-UseServiceAccountIAM")
featureflag.ParseFlags("-UseServiceAccountExternalPermissions")
}
defer unsetFeatureFlag()
runChannelBuilderTest(t, "service-account-iam", []string{"dns-controller.addons.k8s.io-k8s-1.12", "kops-controller.addons.k8s.io-k8s-1.16"})

View File

@ -234,7 +234,7 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap, secretStore fi.SecretS
}
dest["IsIPv6Only"] = tf.IsIPv6Only
dest["UseServiceAccountIAM"] = tf.UseServiceAccountIAM
dest["UseServiceAccountExternalPermissions"] = tf.UseServiceAccountExternalPermissions
if cluster.Spec.NodeTerminationHandler != nil {
dest["DefaultQueueName"] = func() string {

View File

@ -20,7 +20,8 @@ spec:
- instanceGroup: master-us-test-1a
name: master-us-test-1a
name: events
iam: {}
iam:
useServiceAccountExternalPermissions: true
kubernetesVersion: v1.20.6
masterInternalName: api.internal.minimal.example.com
masterPublicName: api.minimal.example.com