From d53f43f44c5e144e105eca7d89b117bdd2ecb2fa Mon Sep 17 00:00:00 2001 From: Marco Ebert Date: Thu, 19 Sep 2024 16:10:30 +0200 Subject: [PATCH] Chart: Support multiple service account issuers. (#339) Co-authored-by: Andreas Sommer --- CHANGELOG.md | 5 + helm/cluster/README.md | 3 +- helm/cluster/ci/ci-values.yaml | 5 +- ...server1serviceaccountissuers+json.yaml.tpl | 8 ++ ...helpers_clusterconfiguration_apiserver.tpl | 17 +-- .../controlplane/_helpers_files.tpl | 8 ++ helm/cluster/values.schema.json | 116 +++++++++--------- 7 files changed, 93 insertions(+), 69 deletions(-) create mode 100644 helm/cluster/files/etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml.tpl diff --git a/CHANGELOG.md b/CHANGELOG.md index 92fb5aac..5f1b0105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Chart: Allow to enable `auditd` service through `global.components.auditd.enabled`. - Chart: Allow configuring `node-cidr-mask-size` flag on `kube-controller-manager`. +### Changed + +- Chart: Support multiple service account issuers.\ + Change `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer` to plural `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers` and render them in the specified order as `--service-account-issuer` parameters for the API server. + ## [1.0.0] - 2024-07-24 ### Changed diff --git a/helm/cluster/README.md b/helm/cluster/README.md index 49eb3641..6e8f035e 100644 --- a/helm/cluster/README.md +++ b/helm/cluster/README.md @@ -594,7 +594,8 @@ Provider-specific properties that can be set by cluster-$provider chart in order | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.featureGates[*]` | **Feature gate** - A feature gate to enable or disable.|**Type:** `object`
| | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.featureGates[*].enabled` | **Enabled** - Whether to enable or disable the feature gate.|**Type:** `boolean`
| | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.featureGates[*].name` | **Name** - Name of the feature gate.|**Type:** `string`
| -| `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer` | **Service account issuer** - Configuration of the identifier of the service account token issuer. You must specify either URL or clusterDomainPrefix (only one, not both).|| +| `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers` | **Service account issuers** - Configuration of the identifier of the service account token issuer. For each issuer, you must specify either `url`, `clusterDomainPrefix` or `templateName`. The first issuer is used by Kubernetes to issue tokens, while the second and further issuers, if any, are trusted regarding tokens. Specifying multiple issuers can make sense for migrations.|**Type:** `array`
| +| `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers[*]` |**None**|| | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.controllerManager` | **Controller manager** - Configuration of controller manager|**Type:** `object`
| | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.controllerManager.externalCloudVolumePlugin` | **External cloud volume plugin** - The plugin to use if the controller-manager cloud provider is set to external. Most in-tree providers are deprecated and this should only be set if you really need it.|**Type:** `string`
| | `providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.controllerManager.featureGates` | **Feature gates** - A list of feature gates to enable or disable.|**Type:** `array`
| diff --git a/helm/cluster/ci/ci-values.yaml b/helm/cluster/ci/ci-values.yaml index fa05f202..7841650d 100644 --- a/helm/cluster/ci/ci-values.yaml +++ b/helm/cluster/ci/ci-values.yaml @@ -365,8 +365,9 @@ providerIntegration: featureGates: - name: DownwardAPIHugePages enabled: false - serviceAccountIssuer: - clusterDomainPrefix: irsa + serviceAccountIssuers: + - clusterDomainPrefix: irsa + - url: http://secondary.issuer.example.org files: - path: /etc/aws/control-plane/node/file.yaml permissions: "0644" diff --git a/helm/cluster/files/etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml.tpl b/helm/cluster/files/etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml.tpl new file mode 100644 index 00000000..9f2d87a7 --- /dev/null +++ b/helm/cluster/files/etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml.tpl @@ -0,0 +1,8 @@ +{{- range $serviceAccountIssuerIndex, $serviceAccountIssuer := .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers -}} +{{- /* First `--service-account-issuer` parameter is set in template `cluster.internal.controlPlane.kubeadm.clusterConfiguration.apiServer` (see note there; avoids Kubernetes adding a default parameter) */ -}} +{{- if gt $serviceAccountIssuerIndex 0 -}} +- op: add + path: /spec/containers/0/command/- + value: {{ printf "--service-account-issuer=%s" (include "cluster.internal.controlPlane.kubeadm.clusterConfiguration.apiServer.serviceAccountIssuer" (dict "Values" $.Values "Release" $.Release "serviceAccountIssuer" $serviceAccountIssuer)) | quote }} +{{ end -}} +{{ end -}} diff --git a/helm/cluster/templates/clusterapi/controlplane/_helpers_clusterconfiguration_apiserver.tpl b/helm/cluster/templates/clusterapi/controlplane/_helpers_clusterconfiguration_apiserver.tpl index 387c13b7..a39cfafa 100644 --- a/helm/cluster/templates/clusterapi/controlplane/_helpers_clusterconfiguration_apiserver.tpl +++ b/helm/cluster/templates/clusterapi/controlplane/_helpers_clusterconfiguration_apiserver.tpl @@ -52,8 +52,9 @@ extraArgs: {{- end }} profiling: "false" runtime-config: api/all=true - {{- if .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer }} - service-account-issuer: "{{ include "cluster.internal.controlPlane.kubeadm.clusterConfiguration.apiServer.serviceAccountIssuer" $ }}" + {{- /* Additional `--service-account-issuer` values are applied via patch file (see `kube-apiserver1serviceaccountissuers+json.yaml.tpl`) if there are multiple such parameters. Since Kubernetes defaults to the parameter `--service-account-issuer=https://kubernetes.default.svc.cluster.local` (not desired), we must set the *first* issuer *here*. This becomes easier with the switch to v1beta4 kubeadm config which supports multiple parameters (array instead of map). */}} + {{- if .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers }} + service-account-issuer: {{ (include "cluster.internal.controlPlane.kubeadm.clusterConfiguration.apiServer.serviceAccountIssuer" (dict "Values" $.Values "Release" $.Release "serviceAccountIssuer" (.Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers | first))) | quote }} {{- end }} service-account-lookup: "true" service-cluster-ip-range: {{ .Values.global.connectivity.network.services.cidrBlocks | first }} @@ -76,7 +77,7 @@ extraVolumes: {{- end }} {{- if $.Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.cloudConfig }} - name: cloud-config - hostPath: {{ $.Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.cloudConfig }} + hostPath: {{ $.Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.cloudConfig }} mountPath: {{ $.Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.cloudConfig }} readOnly: true {{- end }} @@ -118,12 +119,12 @@ extraVolumes: {{- end }} {{- define "cluster.internal.controlPlane.kubeadm.clusterConfiguration.apiServer.serviceAccountIssuer" }} -{{- if .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer.clusterDomainPrefix -}} -https://{{ .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer.clusterDomainPrefix }}.{{ include "cluster.resource.name" $ }}.{{ required "The baseDomain value is required" $.Values.global.connectivity.baseDomain }} -{{- else if .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer.templateName -}} -{{- include .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer.templateName $ -}} +{{- if .serviceAccountIssuer.clusterDomainPrefix -}} +https://{{ .serviceAccountIssuer.clusterDomainPrefix }}.{{ include "cluster.resource.name" $ }}.{{ required "The baseDomain value is required" $.Values.global.connectivity.baseDomain }} +{{- else if .serviceAccountIssuer.templateName -}} +{{- include .serviceAccountIssuer.templateName $ -}} {{- else -}} -{{ .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuer.url }} +{{ .serviceAccountIssuer.url }} {{- end }} {{- end }} diff --git a/helm/cluster/templates/clusterapi/controlplane/_helpers_files.tpl b/helm/cluster/templates/clusterapi/controlplane/_helpers_files.tpl index 80385949..d3ec74fd 100644 --- a/helm/cluster/templates/clusterapi/controlplane/_helpers_files.tpl +++ b/helm/cluster/templates/clusterapi/controlplane/_helpers_files.tpl @@ -79,6 +79,14 @@ encoding: base64 content: {{ tpl ($.Files.Get "files/etc/ssl/certs/oidc.pem") . | b64enc }} {{- end }} +{{- if .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers }} +{{- if gt (len .Values.providerIntegration.controlPlane.kubeadmConfig.clusterConfiguration.apiServer.serviceAccountIssuers) 1 }} +- path: /etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml + permissions: "0644" + encoding: base64 + content: {{ tpl ($.Files.Get "files/etc/kubernetes/patches/kube-apiserver1serviceaccountissuers+json.yaml.tpl") . | b64enc }} +{{- end }} +{{- end }} {{- end }} {{/* Provider-specific files for control plane nodes */}} diff --git a/helm/cluster/values.schema.json b/helm/cluster/values.schema.json index fdcbd4d6..d61befbb 100644 --- a/helm/cluster/values.schema.json +++ b/helm/cluster/values.schema.json @@ -2370,70 +2370,70 @@ "featureGates": { "$ref": "#/$defs/featureGates" }, - "serviceAccountIssuer": { - "title": "Service account issuer", - "description": "Configuration of the identifier of the service account token issuer. You must specify either URL or clusterDomainPrefix (only one, not both).", - "oneOf": [ - { - "type": "null" - }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "clusterDomainPrefix": { - "type": "string", - "title": "Cluster domain prefix", - "description": "Prefix that is prepended to the cluster domain name, so that resulting URL is used as the identifier of the service account token issuer." - }, - "templateName": { - "type": "string", - "title": "Template name", - "description": "The name of the Helm template which renders the 'url' value" - }, - "url": { - "type": "string", - "title": "URL", - "description": "This URL is used as the identifier of the service account token issuer." - } - }, - "oneOf": [ - { - "required": [ - "url" - ], - "not": { - "required": [ - "clusterDomainPrefix", - "templateName" - ] + "serviceAccountIssuers": { + "type": "array", + "title": "Service account issuers", + "description": "Configuration of the identifier of the service account token issuer. For each issuer, you must specify either `url`, `clusterDomainPrefix` or `templateName`. The first issuer is used by Kubernetes to issue tokens, while the second and further issuers, if any, are trusted regarding tokens. Specifying multiple issuers can make sense for migrations.", + "items": { + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "clusterDomainPrefix": { + "type": "string", + "title": "Cluster domain prefix", + "description": "Prefix that is prepended to the cluster domain name, so that resulting URL is used as the identifier of the service account token issuer." + }, + "templateName": { + "type": "string", + "title": "Template name", + "description": "The name of the Helm template which renders the 'url' value" + }, + "url": { + "type": "string", + "title": "URL", + "description": "This URL is used as the identifier of the service account token issuer." } }, - { - "required": [ - "clusterDomainPrefix" - ], - "not": { + "oneOf": [ + { "required": [ - "url", - "templateName" - ] - } - }, - { - "required": [ - "templateName" - ], - "not": { + "url" + ], + "not": { + "required": [ + "clusterDomainPrefix", + "templateName" + ] + } + }, + { "required": [ - "url", "clusterDomainPrefix" - ] + ], + "not": { + "required": [ + "url", + "templateName" + ] + } + }, + { + "required": [ + "templateName" + ], + "not": { + "required": [ + "url", + "clusterDomainPrefix" + ] + } } - } - ] - } - ] + ] + } + ] + } } }, "default": {}