Kubernetes lets you configure the kube-apiserver authenticators with a structured
AuthenticationConfiguration file, passed to the API server with the --authentication-config
flag. Compared to the legacy --oidc-* flags, the structured configuration supports:
/healthz, /readyz and /livez)KubeOne exposes this through the authenticationConfiguration feature.
KubeOne supports the structured authentication configuration as of v1.15. It supports the following operations:
AuthenticationConfiguration file to all control plane nodeskubeone applyThe authenticationConfiguration feature can’t be used together with the [openidConnect feature][oidc-tutorial]. The
openidConnect feature configures a single OIDC issuer with the legacy --oidc-* flags. Use
authenticationConfiguration if you need anything beyond a single issuer.
The authentication configuration is a standalone manifest of kind AuthenticationConfiguration from the
apiserver.config.k8s.io API group. KubeOne doesn’t generate this file. You write it and KubeOne distributes it as-is.
See the Kubernetes documentation for all available fields.
The following example configures two JWT issuers and allows anonymous access only to the health check endpoints:
# authentication-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://dex.example.com
audiences:
- kubernetes
claimMappings:
username:
claim: email
prefix: "oidc:"
groups:
claim: groups
prefix: "oidc:"
claimValidationRules:
- expression: "claims.email_verified == true"
message: "email must be verified"
- issuer:
url: https://keycloak.example.com/realms/platform
audiences:
- kubernetes
- platform-cli
audienceMatchPolicy: MatchAny
claimMappings:
username:
expression: '"keycloak:" + claims.preferred_username'
groups:
expression: 'claims.groups.map(g, "keycloak:" + g)'
userValidationRules:
- expression: "!user.username.startsWith('system:')"
message: "username cannot use the reserved system: prefix"
anonymous:
enabled: true
conditions:
- path: /livez
- path: /readyz
- path: /healthz
To enable the feature, add the following section to the KubeOne configuration manifest:
apiVersion: kubeone.k8c.io/v1beta2
kind: KubeOneCluster
name: example
versions:
kubernetes: "1.34.1"
features:
authenticationConfiguration:
enable: true
# Path to the AuthenticationConfiguration manifest. Relative paths are
# resolved relative to the KubeOne configuration manifest.
configFilePath: ./authentication-config.yaml
You can also generate an example manifest with the feature section included:
kubeone config print --full --enable-authentication-configuration
The configFilePath field is required when the feature is enabled.
For a new cluster, run kubeone apply as usual. The kube-apiserver uses the structured authentication configuration
from the start:
kubeone apply --manifest kubeone.yaml -t tf.json
Enabling the feature on an existing cluster changes the kube-apiserver flags, so you have to run kubeone apply with
the --force-upgrade flag. This reconfigures the control plane nodes one by one:
kubeone apply --manifest kubeone.yaml -t tf.json --force-upgrade
openidConnect FeatureYou can’t enable both features at the same time, so migrate in a single step:
Translate the features.openidConnect.config values into a jwt entry in the AuthenticationConfiguration file.
For example:
openidConnect.config | AuthenticationConfiguration |
|---|---|
issuerUrl | jwt[].issuer.url |
clientId | jwt[].issuer.audiences |
usernameClaim | jwt[].claimMappings.username.claim |
usernamePrefix | jwt[].claimMappings.username.prefix |
groupsClaim | jwt[].claimMappings.groups.claim |
groupsPrefix | jwt[].claimMappings.groups.prefix |
requiredClaim | jwt[].claimValidationRules |
caFile | jwt[].issuer.certificateAuthority (PEM content, not a path) |
Set features.openidConnect.enable to false (or remove the section) and add the
features.authenticationConfiguration section.
Run kubeone apply --force-upgrade.
Once the feature is enabled, edit the AuthenticationConfiguration file and run kubeone apply:
kubeone apply --manifest kubeone.yaml -t tf.json
KubeOne compares the SHA256 checksum of your local file with the file on each control plane node. If they differ,
KubeOne uploads the new file to all control plane nodes. The kube-apiserver watches the file and reloads it
automatically, so updates don’t need --force-upgrade and don’t restart the API server.
If the reloaded configuration is invalid, the kube-apiserver keeps using the last valid configuration. KubeOne validates the file before uploading it (see Validation), which catches most errors early.
To disable the feature, set features.authenticationConfiguration.enable to
false (or remove the section) and run:
kubeone apply --manifest kubeone.yaml -t tf.json --force-upgrade
KubeOne validates the configuration before making any changes to the cluster. It fails if:
configFilePath is empty or the file can’t be readAuthenticationConfiguration manifest. KubeOne decodes it strictly, so unknown fields are
rejectedhttps://kubernetes.default.svc.<serviceDomainName>, or the values of the service-account-issuer flag if you set it
in controlPlaneComponents.apiServer.flagsauthenticationConfiguration and openidConnect are enabledcontrolPlaneComponents.apiServer.flags sets authentication-config or any oidc-* flaganonymous section and controlPlaneComponents.apiServer.flags also sets anonymous-auth. The
kube-apiserver refuses to start when anonymous authentication is configured both waysWhen the feature is enabled, KubeOne:
/etc/kubernetes/authentication/config.yaml on every control plane node, owned by root:root
with mode 0600./etc/kubernetes/authentication read-only into the kube-apiserver static pod.--authentication-config=/etc/kubernetes/authentication/config.yaml.