This topic describes how to deploy a Keycloak Service in a Container Service for Kubernetes (ACK) cluster and use Keycloak as a Kubernetes OpenID Connect (OIDC) authentication server to verify identities.
Prerequisites
An ACK managed cluster is created and the cluster runs Kubernetes 1.22 or later.
The kubeconfig file of the cluster is obtained and used to connect to the cluster through kubectl.
jwt-cli is installed. jwt-cli is used to parse JSON Web Tokens (JWT). This step is optional.
Set up the environment
Prepare a domain name for the Keycloak Service.
Certificates
To ensure the security of Keycloak in a production environment, run the following command to generate a root certificate and a server certificate. The Subject Alternate Name (SAN) of the server certificate must contain the domain name that you prepared for the Keycloak Service.
openssl genrsa -out rootCA.key 2048 #Generate a Certificate Authority (CA) key. openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt #Generate a CA certificate. openssl genrsa -out server.key 2048 #Generate a server key. openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extensions v3_req -extfile <(echo '[v3_req]'; echo 'subjectAltName = DNS:${Service domain name}')Databases
By default, Keycloak data is persisted to local files. In a production environment, you need to persist the data to a database. The following table describes the database engines and versions supported by Keycloak.
Database engine
Option value
Version
MariaDB Server
mariadb
10.11
Microsoft SQL Server
mssql
2022
MySQL
mysql
8.0
Oracle Database
oracle
19.3
PostgreSQL
postgres
15
In this example, ApsaraDB RDS for MySQL is used to persist Keycloak data. A database named Keycloak is created. For more information about how to create and use ApsaraDB RDS for MySQL instances, see Create an ApsaraDB RDS for MySQL instance.
Step 1: Deploy Keycloak in an ACK managed cluster
Deploy a Keycloak Service in an ACK managed cluster.
Create a file named keycloak.yaml and add the following content to the file:
apiVersion: v1 kind: Service metadata: labels: app: keycloak name: keycloak namespace: default spec: ports: - name: http port: 80 protocol: TCP targetPort: 8080 selector: app: keycloak type: ClusterIPRun the following command to deploy a Keycloak Service in an ACK managed cluster and expose the Service to internal access:
kubectl apply -f keycloak.yaml
Deploy relevant configurations.
Create a file named keycloak-secret.yaml and add the following content to the file.
The following database configuration is used to connect to the database named Keycloak. The administrator configuration is used to log on to Keycloak for the first time.
apiVersion: v1 data: db_passwd: ${Database password encoded by Base64} db_username: ${Database username encoded by Base64} db_url: ${Database URL or host encoded by Base64} keycloak_admin: ${Keycloak administrator username encoded by Base64} keycloak_admin_password: ${Keycloak administrator password encoded by Base64} kind: Secret metadata: name: keycloak-secret namespace: default type: OpaqueRun the following command to deploy the configurations:
kubectl apply -f keycloak-secret.yamlCreate a file named keylock-pki.yaml and add the following content to the file:
apiVersion: v1 data: tls.crt: ${Server certificate encoded by Base64} tls.key: ${Server key encoded by Base64} kind: Secret metadata: name: keycloak-pki namespace: default type: IngressTLSRun the following command to deploy the server certificate:
kubectl apply -f keycloak-pki.yaml
Create an Ingress.
Create a file named keycloak-ingress.yaml and add the following content to the file.
Replace the Service domain name in the following code block with the domain name that you prepared for the Keycloak Service:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: ingress-controller: nginx name: keycloak namespace: default spec: ingressClassName: nginx rules: - host: ${Service domain name} http: paths: - backend: service: name: keycloak port: number: 80 path: / pathType: ImplementationSpecific tls: - hosts: - ${Service domain name} secretName: keycloak-pkiRun the following command to deploy the Ingress:
kubectl apply -f keycloak-ingress.yamlAfter the Ingress is deployed, a publicly accessible IP address is generated. The Service domain name is resolved to the IP address.
Deploy the Keycloak Deployment.
Create a file named keycloak-deploy.yaml and add the following content to the file:
Run the following command to deploy a Keycloak Deployment:
kubectl apply -f keycloak-deploy.yaml
Enter
https://${Keycloak Service domain name}into the address bar of the web browser to access the Keycloak Service. If the following page appears, the Service is successfully deployed.
Step 2: Deploy Keycloak
User settings
On the Keycloak Service page, click Administration Console and enter the username and password to log on to the Admin console.
You need to enter the administrator username and password specified in the keycloak-secret.yaml file in Step 2.a.
In the upper-left part of the page, select master from the drop-down list and click Create Realm.
On the Create realm page, set Realm name to myrealm and click Create to create a realm named myrealm. You can manage Keycloak tenants in the realm.
In the upper-left part of the page, select myrealm from the drop-down list. In the left-side navigation pane, click Users and then click Add user on the page that appears.
On the Create user page, set Username to myuser and click Create to create a user named myuser. Other parameters are optional.
On the myuser page, click Attributes to add an attribute for the myuser user. Set Key to name and Value to ack and then click Save. The attribute can be injected into an ID token.
On the myuser page, click Credentials and then click Set Password.
Set Temporary to On and click Save. You need to change the password during the first time you log on to Keycloak.
The address of Keycloak is
https://${Keycloak Service domain name}/realms/${Your realm}/account.
Client settings
Keycloak needs to verify the identities of clients. Configure the following client settings.
In the left-side navigation pane of the myrealm page, click Clients. On the Clients page, click Create client.
On the Create client page, configure General Settings, Capability config, and Login settings.
On the General Settings page, specify Client ID and Name and click Next. In this example, both parameters are set to ack.
On the Capability config page, set the access type of clients to confidential by setting Client authentication to on, use the default settings for other parameters, and then click Next.
On the Login settings page, set Valid redirect URIs to http://*. This parameter specifies the redirect URI that is used after you are successfully logged on. In this example, http://* specifies all HTTP redirect URIs. Click Save.
Client scope settings
Client scopes can be used to share common protocol and role mappings between multiple clients within a realm.
In the left-side navigation pane of the myrealm page, click Client scopes. On the Client scopes page, click Create client scope.
On the Create client scope page, set Name to ack-kubernetes, keep the default settings for other parameters, and then click Save.
On the ack-kubernetes page, click Mappers and then click Configure a new mapper.
On the Configure a new mapper page, create a user attribute to inject the attribute added in Step 6 into the ID token. In this example, the attribute whose key and value are name and ack is injected.
On the Add mapper page, set Name to name, User Attribute to name (the name: ack attribute added in the preceding step), and Token Claim Name to name (the name of the attribute in the ID token). Keep the default settings for other parameters. Click Save.
In the left-side navigation pane, click Clients to return to the Clients page and select the client named ack.
On the client page of the ack client, click Client scopes and then click Add client scope. In the dialog box that appears, select the client scope to add and click Add.

Step 3: Configure Kube API Server parameters
Kubernetes supports the OIDC protocol and can be interfaced with external identity providers (IdPs) to verify identities. To enable identity verification, you need to configure OIDC parameters related to the Kube API Server component of the ACK managed cluster.
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, find the one you want to manage and click its name. In the left navigation pane, click Add-ons.
On the Add-ons page, find the Kube API Server component on the Core Components tab and click Configuration in the lower-right part of the card.
In the Kube API Server Parameters dialog box, configure the following parameters, keep the default settings for other parameters, and then click OK.
Parameter
Description
oidcIssuerURLOIDC
OIDC provider URL
Access
https://${Keycloak Service domain name}/realms/myrealm/.well-known/openid-configurationand obtain the URL of the OIDC provider. In this example,https://${Keycloak Service domain name}/realms/myrealmis entered.ImportantThe API server of the cluster accesses the addresses specified in the oidcIssuerURL configurations. If you use public endpoints, make sure that the cluster has access to the Internet. For more information, see Enable an existing ACK cluster to access the Internet.
If the API server still cannot access the addresses specified in the oidcIssuerURL configurations after the cluster has Internet access enabled, you can run the
kubectl get endpointscommand to obtain the number of backend IP addresses in Kubernetes.If the number of IP addresses is greater than one, log on to the worker node, try to access the oidcIssuerURL, then check the configurations of the Internet and security group rules.
If there is only one IP address, submit a ticket.
oidcClientIdOIDC Token
Client ID
Enter the client ID specified in Step 2 of the Client settings section. In this example, ack is entered.
oidcUsernameClaim
Username JWT claim
Enter the value of the Token Claim Name parameter specified in Step 5 of the Client scope settings section. In this example, name is entered, which is the identity of the user in the ACK managed cluster.
oidcUsernamePrefix
Username prefix
Enter a hyphen (-), which means that no prefix is specified.
oidcCAContent
The Base64-encoded CA certificate required for sending requests to the URL of the OIDC provider
Enter the Base64-encoded root certificate generated in Certificates in the Set up the environment section.
Step 4: Verify identities
Run the following command to request an ID token. Then, obtain the ID token from the request body.
curl -ks -X POST https://${Keycloak Service domain name}/realms/myrealm/protocol/openid-connect/token \ -d grant_type=password -d client_id=ack \ -d username=myuser -d password=${Password used to log on to Keycloak} -d scope=openid \ -d client_secret=${client credential}You need to replace the following variables:
Variable to replace
Description
Keycloak Service domain name
Replace it with the domain name that you prepared for the Keycloak Service.
password
Replace it with the password specified in Step 2.a.
client_secret
Log on to the Keycloak console. On the Clients page, select the client named ack, click Credentials, and then copy the value of the Client secret parameter.

Optional. Use jwt-cli to parse the token. The parsing result indicates that
issis set to the value of the oidcIssuerURL parameter of the API server andnameis set to the user attribute that you added in Step 5 of the Client scope settings section.Use the following YAML content to create a ClusterRole:
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: keycloak-example rules: - apiGroups: [""] resources: ["namespaces"] verbs: ["get","list"] # Allow the role to read namespace information. --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: ack-crb roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: keycloak-example subjects: - kind: User name: ack apiGroup: rbac.authorization.k8s.ioRun the following command to send a request to the API server:
curl -k https://${API server address}/api/v1/namespaces -H "Authorization: Bearer ${id token}"API server address: Enter an API server address based on the network in which the cluster resides. On the Cluster Information page of the ACK console, find the Network section under the Basic Information tab. Then, view the API server Public Endpoint and API server Internal Endpoint.id token: Specify the ID token obtained in Step 1.
After the request is sent, the following namespace information is returned.
Send another request to request a resource that the current user is unauthorized to access. The output indicates that Kubernetes identifies the ack user and verifies the permissions of the user.