Users¶
MySQL user accounts within the Cluster can be divided into two different groups:
- application-level users: the unprivileged user accounts for applications,
- system-level users: the accounts needed to automate the cluster deployment and management tasks, such as Percona XtraDB Cluster Health checks or ProxySQL integration.
These two groups serve different purposes. Read the following sections to learn more.
Unprivileged users¶
The Operator doesn’t create application-level (unprivileged) user accounts by default.
You can create these unprivileged users in the following ways:
- Automatically via Custom Resource. This ability is available with Operator versions 1.16.0 and newer
- Manually in MySQL
Create users in the Custom Resource¶
Starting from the Operator version 1.16.0, you can create users in Percona XtraDB Cluster via the users subsection in the Custom Resource. This is called declarative user management.
You can change the users section in the deploy/cr.yaml configuration file either at the cluster creation time or adjust it over time.
You can define users in the users section of your Custom Resource. For each user, you can specify:
- The user’s login name
- Hosts the user is allowed to connect from
- Databases the user can access
- MySQL privilege grants
- A reference to a Secret resource containing the user’s password
Here is an example configuration of the Custom Resource:
...
users:
- name: my-user
dbs:
- db1
- db2
hosts:
- localhost
grants:
- SELECT
- DELETE
- INSERT
withGrantOption: true
passwordSecretRef:
name: my-user-pwd
key: my-user-pwd-key
...
For detailed information about all available options, see the Custom Resource reference.
Generate user passwords manually¶
You can create the Secret containing the user password manually. The Secret referenced in users.passwordSecretRef.name should follow this format:
apiVersion: v1
kind: Secret
metadata:
name: my-user-pwd
type: Opaque
stringData:
password: my-user-pwd-key
The Operator tracks password changes in the Secret object and automatically updates the user password in the database when the Secret is modified.
Customize password generation by the Operator¶
By default, the Operator generates user passwords using alphanumeric characters plus a set of special symbols. The password length is randomly chosen in the range of 16 to 20 characters.
To ensure compatibility with tools that may not support certain special symbols or require a different password length, you can customize password generation using the passwordGenerationOptions subsection in the Custom Resource:
passwordGenerationOptions:
symbols: "!#$%&()*+,-.<=>?@[]^_{}~"
maxLength: 20
minLength: 16
Important considerations¶
When creating users via Custom Resource, keep the following behavior in mind:
-
Minimal configuration: The only required field is
users.name. If you omit other fields: -
If no Secret is specified, the Operator generates a password and stores it in a Secret named
<cluster-name>-custom-user-secret -
If
grantsordbsare omitted, MySQL provides default grants -
User deletion: The Operator does not delete users when they are removed from the Custom Resource. This prevents accidental removal of pre-existing users.
- Host changes: When you update the
hostsarray (for example, changinghost1tohost2), the Operator creates a new useruser@host2in addition to the existinguser@host1. If you later change the host back tohost1, theuser@host1account will continue using its original password, which may differ from the password in the Secret. - Grant updates: The Operator updates grants in an additive manner. It adds new grants but does not revoke existing ones that are not specified in the Custom Resource.
- Duplicate users: You cannot define two entries for the same user (for example, with different grants for different databases) in a single Custom Resource. However, you can achieve this by making sequential updates to the Custom Resource.
- Invalid grants: If you specify an invalid grant or set an administrative (global) grant while also specifying
dbs, the Operator logs an error and creates the user with default grants (GRANT USAGE).
Create users manually¶
Instead of using the Custom Resource, you can create unprivileged users directly in MySQL using standard SQL commands. This approach gives you full control over user creation and is useful when you need to create users with specific configurations that may not be easily expressed in the Custom Resource format.
Create a user¶
To create a user manually, use separate statements to create the account and grant privileges:
-
Connect to your cluster. Replace
cluster1with your actual cluster name androot_passwordwith your root password:kubectl run -it --rm percona-client --image=percona/percona-xtradb-cluster:8.4.8-8.1 --restart=Never -- mysql -hcluster1-pxc -uroot -proot_password -
Create the user account:
CREATE USER 'user1'@'%' IDENTIFIED BY 'password1';Note
MySQL password for the user you create should not exceed 32 characters due to the replication-specific limit introduced in MySQL 5.7.5 .
-
Grant privileges to the user:
GRANT ALL PRIVILEGES ON database1.* TO 'user1'@'%';
Verify user creation¶
After creating the user, verify that it was created successfully and can connect to the database. The following example connects to the cluster via HAProxy and executes a simple query:
kubectl run -it --rm percona-client --image=percona/percona-xtradb-cluster:8.4.8-8.1 --restart=Never -- bash -il
percona-client:/$ mysql -h cluster1-haproxy -uuser1 -ppassword1
mysql> SELECT * FROM database1.table1 LIMIT 1;
If the connection succeeds and you can execute queries, the user has been created correctly with the appropriate permissions.
System Users¶
To automate the deployment and management of the cluster components, the Operator requires system-level Percona XtraDB Cluster users.
Credentials for these users are stored as a Kubernetes Secrets object.
The Operator requires Kubernetes Secrets before Percona XtraDB Cluster is
started. It uses an existing Secret, if it already exists. Otherwise, the Operator creates a new Secret with randomly generated passwords. The default Secret name is cluster1-secrets.
The name of the required Secret should be set in the spec.secretsName option of the deploy/cr.yaml
configuration file.
In addition to cluster1-secrets, the Operator will also create an internal Secrets object named internal-cluster1, which exists for technical purposes and should not be edited by end users. Read more about internal Secret usage in Internal Secret and its usage section.
The following table shows system user names and purposes.
Warning
Don’t use system users to run applications.
| User Purpose | Username | Password Secret Key | Description |
|---|---|---|---|
| Admin | root | root | Database administrative user, can be used by the application if needed |
| ProxySQLAdmin | proxyadmin | proxyadmin | ProxySQL administrative user, can be used to add general-purpose ProxySQL users |
| Backup | xtrabackup | xtrabackup | The user to run backups , granted all privileges for the point-in-time recovery needs |
| Monitoring | monitor | monitor | User for internal monitoring purposes like liveness/readiness checks and PMM agent |
| PMM Server token | Should be set through the operator options | pmmservertoken | The service token used to access PMM server version 3. For PMM 2, use API key. |
| Operator Admin | operator | operator | Database administrative user, should be used only by the Operator |
| Replication | replication | replication | Administrative user needed for cross-site Percona XtraDB Cluster |
Note
The administrative database user operator is always created in MySQL as operator@'%'. Using an operator user with a different host value (for example, operator@'hostname') is not supported and such users should not exist in the database.
YAML object format¶
The default name of the Secrets object for the system users is cluster1-secrets. You can create your own Secret and reference it in the Custom Resource for your cluster in the spec.secretsName key.
When you create the Secrets object yourself, your YAML file should match the following simple format:
apiVersion: v1
kind: Secret
metadata:
name: cluster1-secrets
type: Opaque
stringData:
root: root_password
xtrabackup: backup_password
monitor: monitory
proxyadmin: admin_password
operator: operatoradmin
replication: repl_password
pmmservertoken: my_pmm_server_token
The example above matches the default deploy/secrets.yaml file, which includes sample passwords. These are intended only for development or automated testing. Don’t use them in production.
Update the Secret¶
When you create the Secrets object, you use the stringData type and specify all values for each key/value pair in plain text format. However, the resulting Secrets object contains passwords stored as base64-encoded strings in the data type.
To update any field, you’ll need to encode the value into the base64 format.
Here’s how to do it:
-
Run the following command in your local shell to encode the new value. Replace
new_passwordwith your value:echo -n "new_password" | base64 --wrap=0echo -n "new_password" | base64 -
Update the Secrets object. For example, the following command updates the Admin user’s password to
new_passwordin thecluster1-secretsobject:kubectl patch secret/cluster1-secrets -p '{"data":{"root": "'$(echo -n new_password | base64 --wrap=0)'"}}'kubectl patch secret/cluster1-secrets -p '{"data":{"root": "'$(echo -n new_password | base64)'"}}'
Internal Secret and its usage¶
The Operator creates and updates an additional Secrets object which is named based on the cluster name, like internal-cluster1. This Secrets object is used only by the Operator. Users must not change it.
This object contains secrets with the same passwords as the one specified in spec.secretsName (e.g., cluster1-secrets). When you update the cluster1-secrets Secret, the Operator propagates these changes to the internal internal-cluster1 Secrets object.
Password rotation policies and timing¶
When there is a change in user secrets, the Operator creates the necessary transaction to change passwords. This rotation happens almost instantly (the delay can be up to a few seconds), and you don’t need to take any action beyond changing the password.
Note
Please don’t change the secretsName option in the CR. Make changes inside the secrets object itself.
Starting from the Operator version 1.13.0, system users are created with the PASSWORD EXPIRE NEVER policy. This policy is automatically applied to system users on existing clusters when the Operator is upgraded to version 1.13.0.
Marking system users in MySQL¶
Starting with MySQL 8.0.16, a new feature called Account Categories has been implemented, which allows you to mark system users as such. See the official documentation on this feature for more details.
Development mode¶
To make development and testing easier, the deploy/secrets.yaml secrets file contains default passwords for Percona XtraDB Cluster system users.
These development-mode credentials from deploy/secrets.yaml are:
| Secret Key | Secret Value |
|---|---|
| root | root_password |
| xtrabackup | backup_password |
| monitor | monitory |
| proxyadmin | admin_password |
| operator | operatoradmin |
| replication | repl_password |
Warning
Do not use the default Percona XtraDB Cluster user passwords in production!
Created: September 19, 2022