github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/docs/developer_docs/integration/parameter-template.md (about)

     1  ---
     2  title: Parameter template
     3  description: How to configure parameter templates in KubeBlocks 
     4  keywords: [parameter template]
     5  sidebar_position: 4
     6  sidebar_label: Parameter template
     7  ---
     8  
     9  import Tabs from '@theme/Tabs';
    10  import TabItem from '@theme/TabItem';
    11  
    12  # Parameter template
    13  
    14  This tutorial demonstrates how to configure parameter templates in KubeBlocks with Oracle MySQL as an example. You can find [the full PR here](https://github.com/apecloud/learn-kubeblocks-addon/tree/main/tutorial-3-config-and-reconfig/).
    15  
    16  ## Before you start
    17  
    18  1. Grasp basic concepts of Kubernetes, such as Pod and ConfigMap.
    19  2. Finish [Tutorial 1](./how-to-add-an-add-on.md).
    20  3. Know something about Go Template (Optional).
    21  
    22  ## Introduction
    23  
    24  When creating a cluster, developers typically configure parameters according to resource availability, performance needs, environment, etc. Cloud database providers like AWS and Alibaba Cloud have therefore offered various parameter templates (such as high-performance and asynchronous templates for RDS) to facilitate a quick startup for users.
    25  
    26  In this tutorial, you will learn how to configure parameters in KubeBlocks, which includes adding parameter templates, configuring parameters, and configuring parameter validation.
    27  
    28  Although Kubernetes allows users to mount parameter files as ConfigMap on volumes of the Pod, it only manages ConfigMap updates and synchronizes them to the volume. Therefore, if the database engine (such as MySQL and Postgres) fails to support dynamic loading of configuration files, you can only log in to the database to perform update operations, which can easily lead to configuration drift.
    29  
    30  To prevent that, KubeBlocks manages all parameters through ConfigMap with the principle that `ConfigMap is the only source-of-truth`. It means that all parameter configurations are first applied to ConfigMap, and then, depending on different ways the parameters take effect, applied to each Pod in the cluster. A comprehensive guide on how to configure parameters will be provided in the next tutorial.
    31  
    32  ## ConfigTemplate
    33  
    34  KubeBlocks renders parameter templates with ***Go Template***. Apart from common functions, it also includes some frequently-used calculation functions such as `callBufferSizeByResource` and `getContainerCPU`.
    35  
    36  With KubeBlocks's enhanced rendering capabilities, you can quickly create an ***Adaptive ConfigTemplate*** and generate appropriate configuration files based on the context, such as memory and CPU.
    37  
    38  ### Add a parameter template
    39  
    40  ```yaml
    41  1 apiVersion: v1
    42  2 kind: ConfigMap
    43  3 metadata:
    44  4   name: oracle-mysql-config-template
    45  5   labels:
    46  6     {{- include "oracle-mysql.labels" . | nindent 4 }}
    47  7 data:
    48  8   my.cnf: |-
    49  9     {{`
    50  10      [mysqld]
    51  11      port=3306
    52  12      {{- $phy_memory := getContainerMemory ( index $.podSpec.containers 0 ) }}
    53  13      {{- $pool_buffer_size := ( callBufferSizeByResource ( index $.podSpec.containers 0 ) ) }}
    54  14      {{- if $pool_buffer_size }}
    55  15      innodb_buffer_pool_size={{ $pool_buffer_size }}
    56  16      {{- end }}
    57  17 
    58  18      # If the memory is less than 8Gi, disable performance_schema
    59  19      {{- if lt $phy_memory 8589934592 }}
    60  20      performance_schema=OFF
    61  21      {{- end }}
    62  22 
    63  23      [client]
    64  24      port=3306
    65  25      socket=/var/run/mysqld/mysqld.sock
    66  26      `
    67  27    }}
    68  ```
    69  
    70  The above example illustrates an adaptive ConfigTemplate for MySQL defined through ConfigMap. It includes several common MySQL parameters, such as `port` and `innodb_buffer_pool_size`.
    71  
    72  Based on the memory parameter configured when the container is started, it can:
    73  
    74  - Calculate the size of `innodb_buffer_size` (Line 11 to 15);
    75  - Disable `performance_schema` when the memory is less than 8Gi to reduce performance impact (Line 19 to 21).
    76  
    77  `callBufferSizeByResource` is a predefined bufferPool calculation rule, primarily for MySQL. You can also customize your calculation formulas by querying memory and CPU:
    78  
    79  - `getContainerMemory` retrieves the memory size of a particular container in the Pod.
    80  - `getContainerCPU` retrieves the CPU size of a particular container in the Pod.
    81  
    82  :::note
    83  
    84  Tailor additional parameter calculation options as you wish:
    85  
    86  - Calculate an appropriate `max_connection` value based on memory size.
    87  - Calculate reasonable configurations for other components based on the total memory available.
    88  
    89  :::
    90  
    91  ### Use a parameter template
    92  
    93  #### Modify ClusterDefinition
    94  
    95  Specify parameter templates through `configSpecs` in `ClusterDefinition` and quote the ConfigMap defined in [Add a parameter template](#add-a-parameter-template).
    96  
    97  ```yaml
    98    componentDefs:
    99      - name: mysql-compdef
   100        configSpecs:
   101          - name: mysql-config
   102            templateRef: oracle-mysql-config-template # Defines the ConfigMap name for the parameter template
   103            volumeName: configs                       # Name of the mounted volume          
   104            namespace: {{ .Release.Namespace }}       # Namespace of the ConfigMap
   105        podSpec:
   106          containers:
   107           - name: mysql-container
   108             volumeMounts:
   109               - mountPath: /var/lib/mysql
   110                 name: data
   111               - mountPath: /etc/mysql/conf.d       # Path to the mounted configuration files, engine-related  
   112                 name: configs                      # Corresponds to the volumeName on Line 6    
   113             ports:
   114              ...
   115  ```
   116  
   117  As shown above, you need to modify `ClusterDefinition.yaml` file by adding `configSpecs`. Remember to specify the following:
   118  
   119  - templateRef: The name of the ConfigMap where the template is.
   120  - volumeName: The name of the volume mounted to the Pod.
   121  - namespace: The namespace of the template file (ConfigMap is namespace-scoped, usually in the namespace where KubeBlocks is installed).
   122  
   123  #### View configuration info
   124  
   125  When a new cluster is created, KubeBlocks renders the corresponding ConfigMap based on configuration templates and mounts it to the `configs` volume.
   126  
   127  1. Install a Helm chart.
   128  
   129     ```bash
   130     helm install oracle-mysql path-to-your-helm-char/oracle-mysql
   131     ```
   132  
   133  2. Create a cluster.
   134  
   135     ```bash
   136     kbcli cluster create mycluster --cluster-definition oracle-mysql --cluster-version oracle-mysql-8.0.32
   137     ```
   138  
   139  3. View configuration.
   140  
   141     kbcli provides the subcommand `describe-config` to view the configuration of a cluster.
   142  
   143     ```bash
   144     kbcli cluster describe-config mycluster --component mysql-compdef
   145     >
   146     ConfigSpecs Meta:
   147     CONFIG-SPEC-NAME   FILE     ENABLED   TEMPLATE                       CONSTRAINT   RENDERED                               COMPONENT       CLUSTER
   148     mysql-config       my.cnf   false     oracle-mysql-config-template                mycluster-mysql-compdef-mysql-config   mysql-compdef   mycluster
   149  
   150     History modifications:
   151     OPS-NAME   CLUSTER   COMPONENT   CONFIG-SPEC-NAME   FILE   STATUS   POLICY   PROGRESS   CREATED-TIME   VALID-UPDATED
   152     ```
   153  
   154  You can view:
   155  
   156  - Name of the configuration template: oracle-mysql-config-template
   157  - Rendered ConfigMap: mycluster-mysql-compdef-mysql-config
   158  - Name of the file loaded: my.cnf
   159  
   160  ## Summary
   161  
   162  This tutorial introduces how to render "adaptive" parameters with configuration templates in KubeBlocks.
   163  
   164  In Kubernetes, ConfigMap changes are periodically synchronized to Pods, but most database engines (such as MySQL, PostgreSQL, and Redis) do not actively load new configurations. This is because modifying ConfigMap alone does not provide the capability to Reconfig (parameter changes).
   165  
   166  ## Appendix
   167  
   168  ### A.1 How to configure multiple parameter templates?
   169  
   170  To meet various requirements, developers often need to configure multiple parameter templates in a production environment. For example, Alibaba Cloud provides many high-performance parameter templates and asynchronous templates for customized needs.
   171  
   172  In KubeBlocks, developers can use multiple `ClusterVersion` to achieve their goals.
   173  
   174  $$Cluster = ClusterDefinition.yaml \Join ClusterVersion.yaml \Join Cluster.yaml
   175  $$
   176  
   177  The JoinKey is the Component Name.
   178  
   179  As the cluster definition formula indicates, multiple ClusterVersion can be combined with the same ClusterDefinition to set up different configurations.
   180  
   181  ```yaml
   182  ## The first ClusterVersion, uses configurations from ClusterDefinition
   183  apiVersion: apps.kubeblocks.io/v1alpha1
   184  kind: ClusterVersion
   185  metadata:
   186    name: oracle-mysql
   187  spec:
   188    clusterDefinitionRef: oracle-mysql
   189    componentVersions:
   190    - componentDefRef: mysql-compdef
   191      versionsContext:
   192        containers:
   193          - name: mysql-container
   194            ...
   195  ---
   196  ## The second ClusterDefinition, defines its own configSpecs and overrides the configuration of ClusterDefinition
   197  apiVersion: apps.kubeblocks.io/v1alpha1
   198  kind: ClusterVersion
   199  metadata:
   200    name: oracle-mysql-perf
   201  spec:
   202    clusterDefinitionRef: oracle-mysql
   203    componentVersions:
   204    - componentDefRef: mysql-compdef
   205      versionsContext:
   206        containers:
   207          - name: mysql-container
   208           ...
   209      # The name needs to be consistent with that of the ConfigMap defined in ClusterDefinition
   210      configSpecs:
   211        - name: mysql-config    
   212          templateRef: oracle-mysql-perf-config-template
   213          volumeName: configs
   214  ```
   215  
   216  As shown above, two ClusterVersion objects are created.
   217  
   218  The first one uses the default parameter template (without any configuration), and the second one specifies a new parameter template `oracle-mysql-perf-config-template` through `configSpecs`.
   219  
   220  When creating a cluster, you can specify `ClusterVersion` to create clusters with different configurations, such as:
   221  
   222  ```bash
   223  kbcli cluster create mysqlcuster --cluster-definition oracle-mysql --cluster-version  oracle-mysql-perf
   224  ```
   225  
   226  :::note
   227  
   228  KubeBlocks merges configurations from ClusterVersion and ClusterDefinition via `configSpecs.name`. Therefore, make sure that `configSpecs.name` defined in ClusterVersion matches the name defined in ClusterDefinition.
   229  
   230  :::