Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions charts/gardener/operator/files/crd-gardens.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1881,6 +1881,11 @@ spec:
- configMapName
- kubeconfigs
type: object
tlsMinVersion:
description: |-
TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.
Supported values: VersionTLS12, VersionTLS13.
type: string
watchCacheSizes:
description: |-
WatchCacheSizes contains configuration of the API server's watch cache sizes.
Expand Down
12 changes: 12 additions & 0 deletions docs/api-reference/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -5572,6 +5572,18 @@ integer
<p>Autoscaling contains auto-scaling configuration options for the kube-apiserver.</p>
</td>
</tr>
<tr>
<td>
<code>tlsMinVersion</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.<br />Supported values: VersionTLS12, VersionTLS13.</p>
</td>
</tr>

</tbody>
</table>
Expand Down
1 change: 1 addition & 0 deletions example/90-shoot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ spec:
# minAllowed:
# cpu: "1"
# memory: 3Gi
# tlsMinVersion: VersionTLS12 # Minimum TLS version accepted by the kube-apiserver. Supported values: VersionTLS12, VersionTLS13.
# kubeControllerManager:
# nodeCIDRMaskSize: 24
# nodeCIDRMaskSizeIPv6: 80
Expand Down
5 changes: 5 additions & 0 deletions example/operator/10-crd-operator.gardener.cloud_gardens.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1881,6 +1881,11 @@ spec:
- configMapName
- kubeconfigs
type: object
tlsMinVersion:
description: |-
TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.
Supported values: VersionTLS12, VersionTLS13.
type: string
watchCacheSizes:
description: |-
WatchCacheSizes contains configuration of the API server's watch cache sizes.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/coreos/go-systemd/v22 v22.7.0
github.com/distribution/distribution/v3 v3.1.1
github.com/distribution/reference v0.6.0
github.com/docker/cli v29.7.1+incompatible
github.com/docker/cli v29.7.2+incompatible
github.com/docker/docker v28.5.2+incompatible
github.com/docker/go-connections v0.8.0
github.com/elliotchance/orderedmap/v3 v3.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/cli v29.7.1+incompatible h1:ILZpP6B7fedIr6ANy824QkDp1WMJuouIq0O2SrBkB2w=
github.com/docker/cli v29.7.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v29.7.2+incompatible h1:dlkwallR8XqfeVnA2ELEhdwvb4lsSwuB4IgsG8Q9cLY=
github.com/docker/cli v29.7.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/core/validation/shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -1888,6 +1888,13 @@ func ValidateKubeAPIServer(kubeAPIServer *core.KubeAPIServerConfig, kubernetesVe
}
}

if kubeAPIServer.TLSMinVersion != nil {
validTLSVersions := sets.New("VersionTLS12", "VersionTLS13")
if !validTLSVersions.Has(*kubeAPIServer.TLSMinVersion) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("tlsMinVersion"), *kubeAPIServer.TLSMinVersion, sets.List(validTLSVersions)))
}
}

allErrs = append(allErrs, ValidateControlPlaneAutoscaling(
kubeAPIServer.Autoscaling,
corev1.ResourceList{
Expand Down
28 changes: 28 additions & 0 deletions pkg/api/core/validation/shoot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3729,6 +3729,34 @@ var _ = Describe("Shoot Validation Tests", func() {
}))))
})

DescribeTable("should not allow unsupported or invalid TLS min versions",
func(version string) {
shoot.Spec.Kubernetes.KubeAPIServer.TLSMinVersion = &version

errorList := ValidateShoot(shoot)

Expect(errorList).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeNotSupported),
"Field": Equal("spec.kubernetes.kubeAPIServer.tlsMinVersion"),
}))))
},
Entry("VersionTLS10", "VersionTLS10"),
Entry("VersionTLS11", "VersionTLS11"),
Entry("VersionTLS00", "VersionTLS00"),
)

DescribeTable("should allow all valid TLS min versions",
func(version string) {
shoot.Spec.Kubernetes.KubeAPIServer.TLSMinVersion = &version

errorList := ValidateShoot(shoot)

Expect(errorList).To(BeEmpty())
},
Entry("VersionTLS12", "VersionTLS12"),
Entry("VersionTLS13", "VersionTLS13"),
)

It("should not allow to specify a negative defaultNotReadyTolerationSeconds", func() {
shoot.Spec.Kubernetes.KubeAPIServer.DefaultNotReadyTolerationSeconds = new(int64(-1))

Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/core/types_shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@ type KubeAPIServerConfig struct {
StructuredAuthorization *StructuredAuthorization
// Autoscaling contains auto-scaling configuration options for the kube-apiserver.
Autoscaling *ControlPlaneAutoscaling
// TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.
// Supported values: VersionTLS12, VersionTLS13.
TLSMinVersion *string
}

// ControlPlaneAutoscaling contains auto-scaling configuration options for control-plane components.
Expand Down
47 changes: 47 additions & 0 deletions pkg/apis/core/v1beta1/generated.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/apis/core/v1beta1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/apis/core/v1beta1/types_shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,10 @@ type KubeAPIServerConfig struct {
// Autoscaling contains auto-scaling configuration options for the kube-apiserver.
// +optional
Autoscaling *ControlPlaneAutoscaling `json:"autoscaling,omitempty" protobuf:"bytes,19,opt,name=autoscaling"`
// TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.
// Supported values: VersionTLS12, VersionTLS13.
// +optional
TLSMinVersion *string `json:"tlsMinVersion,omitempty" protobuf:"bytes,20,opt,name=tlsMinVersion"`
}

// ControlPlaneAutoscaling contains auto-scaling configuration options for control-plane components.
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/core/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/apis/core/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/apis/core/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pkg/apiserver/openapi/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/component/kubernetes/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ type Values struct {
DefaultUnreachableTolerationSeconds *int64
// EventTTL is the amount of time to retain events.
EventTTL *metav1.Duration
// TLSMinVersion is the minimum TLS version accepted by the kube-apiserver.
TLSMinVersion *string
// ExternalHostname is the external hostname which should be exposed by the kube-apiserver.
ExternalHostname string
// Images is a set of container images used for the containers of the kube-apiserver pods.
Expand Down
3 changes: 3 additions & 0 deletions pkg/component/kubernetes/apiserver/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3124,6 +3124,7 @@ kind: AuthorizationConfiguration
},
}
eventTTL = 2 * time.Hour
tlsMinVersion = "VersionTLS13"
externalHostname = "api.foo.bar.com"
images = Images{KubeAPIServer: "some-kapi-image:latest"}
serviceAccountIssuer = "issuer"
Expand All @@ -3144,6 +3145,7 @@ kind: AuthorizationConfiguration
},
Autoscaling: AutoscalingConfig{APIServerResources: apiServerResources},
EventTTL: &metav1.Duration{Duration: eventTTL},
TLSMinVersion: &tlsMinVersion,
ExternalHostname: externalHostname,
Images: images,
IsWorkerless: true,
Expand Down Expand Up @@ -3193,6 +3195,7 @@ kind: AuthorizationConfiguration
"--etcd-servers-overrides=/events#https://etcd-events-client:2379",
"--encryption-provider-config=/etc/kubernetes/etcd-encryption-secret/encryption-configuration.yaml",
"--event-ttl="+eventTTL.String(),
"--tls-min-version="+tlsMinVersion,
"--external-hostname="+externalHostname,
"--livez-grace-period=1m",
"--shutdown-delay-duration=15s",
Expand Down
4 changes: 4 additions & 0 deletions pkg/component/kubernetes/apiserver/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ func (k *kubeAPIServer) computeKubeAPIServerArgs() []string {
out = append(out, fmt.Sprintf("--event-ttl=%s", k.values.EventTTL.Duration))
}

if k.values.TLSMinVersion != nil {
out = append(out, fmt.Sprintf("--tls-min-version=%s", *k.values.TLSMinVersion))
}

out = append(out, fmt.Sprintf("--proxy-client-cert-file=%s/%s", volumeMountPathKubeAggregator, secrets.DataKeyCertificate))
out = append(out, fmt.Sprintf("--proxy-client-key-file=%s/%s", volumeMountPathKubeAggregator, secrets.DataKeyPrivateKey))
out = append(out, fmt.Sprintf("--requestheader-client-ca-file=%s/%s", volumeMountPathCAFrontProxy, secrets.DataKeyCertificateBundle))
Expand Down
31 changes: 29 additions & 2 deletions pkg/component/kubernetes/apiserverexposure/sni.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ type SNIValues struct {
IstioIngressGateway IstioIngressGateway
IstioTLSTermination bool
WildcardConfiguration *WildcardConfiguration
TLSMinVersion *string
}

// APIServerProxy contains values for the APIServer proxy protocol configuration.
Expand Down Expand Up @@ -360,12 +361,23 @@ func (s *sni) Deploy(ctx context.Context) error {

gatewayMutateFn := istio.GatewayWithTLSPassthrough(configuration.gateway, getLabels(), configuration.istioIngressGateway.Labels, allHosts)
if values.IstioTLSTermination {
minProtocolVersion := tlsVersionToIstioProtocolVersion(values.TLSMinVersion)
var serverConfigs []istio.ServerConfig
if len(configuration.hosts) > 0 {
serverConfigs = append(serverConfigs, istio.ServerConfig{Hosts: configuration.hosts, PortName: portNameTLS, TLSSecret: s.namespace + istioTLSSecretSuffix})
serverConfigs = append(serverConfigs, istio.ServerConfig{
Hosts: configuration.hosts,
PortName: portNameTLS,
TLSSecret: s.namespace + istioTLSSecretSuffix,
MinProtocolVersion: minProtocolVersion,
})
}
if configuration.wildcardConfiguration != nil {
serverConfigs = append(serverConfigs, istio.ServerConfig{Hosts: configuration.wildcardConfiguration.Hosts, PortName: portNameWildcardTLS, TLSSecret: s.emptyIstioWildcardTLSSecret().Name})
serverConfigs = append(serverConfigs, istio.ServerConfig{
Hosts: configuration.wildcardConfiguration.Hosts,
PortName: portNameWildcardTLS,
TLSSecret: s.emptyIstioWildcardTLSSecret().Name,
MinProtocolVersion: minProtocolVersion,
})
}
gatewayMutateFn = istio.GatewayWithMutualTLS(configuration.gateway, getLabels(), configuration.istioIngressGateway.Labels, serverConfigs)
}
Expand Down Expand Up @@ -668,3 +680,18 @@ func getExportTo(istioGatewayConfigurations []istioGatewayConfiguration) []strin

return namespaces
}

func tlsVersionToIstioProtocolVersion(v *string) istioapinetworkingv1beta1.ServerTLSSettings_TLSProtocol {
if v == nil {
return istioapinetworkingv1beta1.ServerTLSSettings_TLS_AUTO
}

switch *v {
case "VersionTLS13":
return istioapinetworkingv1beta1.ServerTLSSettings_TLSV1_3
case "VersionTLS12":
return istioapinetworkingv1beta1.ServerTLSSettings_TLSV1_2
default:
return istioapinetworkingv1beta1.ServerTLSSettings_TLS_AUTO
}
}
Loading
Loading