diff --git a/config/core/configmaps/features.yaml b/config/core/configmaps/features.yaml index 80efd818b854..4b4ed451538d 100644 --- a/config/core/configmaps/features.yaml +++ b/config/core/configmaps/features.yaml @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/component: controller app.kubernetes.io/version: devel annotations: - knative.dev/example-checksum: "e1c6e542" + knative.dev/example-checksum: "433d7e74" data: _example: |- ################################ @@ -88,6 +88,18 @@ data: # See: https://knative.dev/docs/serving/feature-flags/#kubernetes-runtime-class kubernetes.podspec-runtimeclassname: "disabled" + # Indicates whether Kubernetes DNSPolicy support is enabled + # + # WARNING: Cannot safely be disabled once enabled. + # See: https://knative.dev/docs/serving/feature-flags/#kubernetes-dnspolicy + kubernetes.podspec-dnspolicy: "disabled" + + # Indicates whether Kubernetes DNSConfig support is enabled + # + # WARNING: Cannot safely be disabled once enabled. + # See: https://knative.dev/docs/serving/feature-flags/#kubernetes-dnsconfig + kubernetes.podspec-dnsconfig: "disabled" + # This feature allows end-users to set a subset of fields on the Pod's SecurityContext # # When set to "enabled" or "allowed" it allows the following diff --git a/pkg/apis/config/features.go b/pkg/apis/config/features.go index f1339bfa0083..47be7b709a9b 100644 --- a/pkg/apis/config/features.go +++ b/pkg/apis/config/features.go @@ -58,6 +58,8 @@ func defaultFeaturesConfig() *Features { PodSpecPersistentVolumeClaim: Disabled, PodSpecPersistentVolumeWrite: Disabled, PodSpecInitContainers: Disabled, + PodSpecDNSPolicy: Disabled, + PodSpecDNSConfig: Disabled, TagHeaderBasedRouting: Disabled, AutoDetectHTTP2: Disabled, } @@ -85,6 +87,8 @@ func NewFeaturesConfigFromMap(data map[string]string) (*Features, error) { asFlag("kubernetes.podspec-init-containers", &nc.PodSpecInitContainers), asFlag("kubernetes.podspec-persistent-volume-claim", &nc.PodSpecPersistentVolumeClaim), asFlag("kubernetes.podspec-persistent-volume-write", &nc.PodSpecPersistentVolumeWrite), + asFlag("kubernetes.podspec-dnspolicy", &nc.PodSpecDNSPolicy), + asFlag("kubernetes.podspec-dnsconfig", &nc.PodSpecDNSConfig), asFlag("tag-header-based-routing", &nc.TagHeaderBasedRouting), asFlag("autodetect-http2", &nc.AutoDetectHTTP2)); err != nil { return nil, err @@ -116,6 +120,8 @@ type Features struct { PodSpecInitContainers Flag PodSpecPersistentVolumeClaim Flag PodSpecPersistentVolumeWrite Flag + PodSpecDNSPolicy Flag + PodSpecDNSConfig Flag TagHeaderBasedRouting Flag AutoDetectHTTP2 Flag } diff --git a/pkg/apis/config/features_test.go b/pkg/apis/config/features_test.go index 10592e92b873..77c1c3305e27 100644 --- a/pkg/apis/config/features_test.go +++ b/pkg/apis/config/features_test.go @@ -70,6 +70,8 @@ func TestFeaturesConfiguration(t *testing.T) { PodSpecTolerations: Enabled, PodSpecPriorityClassName: Enabled, PodSpecSchedulerName: Enabled, + PodSpecDNSPolicy: Enabled, + PodSpecDNSConfig: Enabled, TagHeaderBasedRouting: Enabled, }), data: map[string]string{ @@ -84,6 +86,8 @@ func TestFeaturesConfiguration(t *testing.T) { "kubernetes.podspec-tolerations": "Enabled", "kubernetes.podspec-priorityclassname": "Enabled", "kubernetes.podspec-schedulername": "Enabled", + "kubernetes.podspec-dnspolicy": "Enabled", + "kubernetes.podspec-dnsconfig": "Enabled", "tag-header-based-routing": "Enabled", }, }, { @@ -491,6 +495,60 @@ func TestFeaturesConfiguration(t *testing.T) { data: map[string]string{ "kubernetes.podspec-schedulername": "Disabled", }, + }, { + name: "kubernetes.podspec-dnspolicy Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Allowed", + }, + }, { + name: "kubernetes.podspec-dnspolicy Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Enabled", + }, + }, { + name: "kubernetes.podspec-dnspolicy Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Disabled", + }, + }, { + name: "kubernetes.podspec-dnsconfig Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Allowed", + }, + }, { + name: "kubernetes.podspec-dnsconfig Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Enabled", + }, + }, { + name: "kubernetes.podspec-dnsconfig Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Disabled", + }, }} for _, tt := range configTests { diff --git a/pkg/apis/serving/fieldmask.go b/pkg/apis/serving/fieldmask.go index 5b43269b89e2..acd5462c129c 100644 --- a/pkg/apis/serving/fieldmask.go +++ b/pkg/apis/serving/fieldmask.go @@ -227,13 +227,18 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { if cfg.Features.PodSpecInitContainers != config.Disabled { out.InitContainers = in.InitContainers } + if cfg.Features.PodSpecDNSPolicy != config.Disabled { + out.DNSPolicy = in.DNSPolicy + } + if cfg.Features.PodSpecDNSConfig != config.Disabled { + out.DNSConfig = in.DNSConfig + } // Disallowed fields // This list is unnecessary, but added here for clarity out.RestartPolicy = "" out.TerminationGracePeriodSeconds = nil out.ActiveDeadlineSeconds = nil - out.DNSPolicy = "" out.NodeName = "" out.HostNetwork = false out.HostPID = false @@ -242,7 +247,6 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { out.Hostname = "" out.Subdomain = "" out.Priority = nil - out.DNSConfig = nil out.ReadinessGates = nil return out diff --git a/pkg/apis/serving/k8s_validation_test.go b/pkg/apis/serving/k8s_validation_test.go index dc004931c640..cb0f7255da24 100644 --- a/pkg/apis/serving/k8s_validation_test.go +++ b/pkg/apis/serving/k8s_validation_test.go @@ -155,6 +155,20 @@ func withPodSpecInitContainersEnabled() configOption { cfg.Features.PodSpecInitContainers = config.Enabled return cfg } + +} +func withPodSpecDNSPolicyEnabled() configOption { + return func(cfg *config.Config) *config.Config { + cfg.Features.PodSpecDNSPolicy = config.Enabled + return cfg + } +} + +func withPodSpecDNSConfigEnabled() configOption { + return func(cfg *config.Config) *config.Config { + cfg.Features.PodSpecDNSConfig = config.Enabled + return cfg + } } func TestPodSpecValidation(t *testing.T) { @@ -1062,6 +1076,28 @@ func TestPodSpecFeatureValidation(t *testing.T) { Paths: []string{"topologySpreadConstraints"}, }, cfgOpts: []configOption{withPodSpecTopologySpreadConstraintsEnabled()}, + }, { + name: "DNSPolicy", + featureSpec: corev1.PodSpec{ + DNSPolicy: corev1.DNSDefault, + }, + err: &apis.FieldError{ + Message: "must not set the field(s)", + Paths: []string{"dnsPolicy"}, + }, + cfgOpts: []configOption{withPodSpecDNSPolicyEnabled()}, + }, { + name: "DNSConfig", + featureSpec: corev1.PodSpec{ + DNSConfig: &corev1.PodDNSConfig{ + Nameservers: []string{"1.2.3.4"}, + }, + }, + err: &apis.FieldError{ + Message: "must not set the field(s)", + Paths: []string{"dnsConfig"}, + }, + cfgOpts: []configOption{withPodSpecDNSConfigEnabled()}, }, { name: "HostAliases", featureSpec: corev1.PodSpec{