README.md.gotmpl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. {{- /*
  2. Copyright Materialize, Inc. and contributors. All rights reserved.
  3. Use of this software is governed by the Business Source License
  4. included in the LICENSE file at the root of this repository.
  5. As of the Change Date specified in that file, in accordance with
  6. the Business Source License, use of this software will be governed
  7. by the Apache License, Version 2.0.
  8. */ -}}
  9. # {{ template "chart.description" . }}
  10. ![Version: {{ .Version }}](https://img.shields.io/badge/Version-{{ .Version | replace "-" "--" }}-informational?style=flat-square) {{ if .Type }}![Type: {{ .Type }}](https://img.shields.io/badge/Type-{{ .Type }}-informational?style=flat-square) {{ end }}{{ if .AppVersion }}![AppVersion: {{ .AppVersion }}](https://img.shields.io/badge/AppVersion-{{ .AppVersion | replace "-" "--" }}-informational?style=flat-square) {{ end }}
  11. {{ template "chart.description" . }}
  12. This Helm chart deploys the Materialize operator on a Kubernetes cluster. The operator manages Materialize environments within your Kubernetes infrastructure.
  13. ## Prerequisites
  14. - Kubernetes 1.29+
  15. - Helm 3.2.0+
  16. ### Kubernetes Storage Configuration
  17. Materialize requires fast, locally-attached NVMe storage for optimal performance. Network-attached storage (like EBS volumes) is not supported.
  18. We recommend using OpenEBS with LVM Local PV for managing local volumes. While other storage solutions may work, we have tested and recommend OpenEBS for optimal performance.
  19. #### Installing OpenEBS
  20. ```bash
  21. # Install OpenEBS operator
  22. helm repo add openebs https://openebs.github.io/openebs
  23. helm repo update
  24. # Install only the Local PV Storage Engines
  25. helm install openebs --namespace openebs openebs/openebs \
  26. --set engines.replicated.mayastor.enabled=false \
  27. --create-namespace
  28. ```
  29. Verify the installation:
  30. ```bash
  31. kubectl get pods -n openebs -l role=openebs-lvm
  32. ```
  33. #### LVM Configuration
  34. LVM setup varies by environment. Below is our tested and recommended configuration:
  35. ##### AWS EC2 with Bottlerocket AMI
  36. Tested configurations:
  37. - Instance types: r6g, r7g families
  38. - AMI: AWS Bottlerocket
  39. - Instance store volumes required
  40. Setup process:
  41. 1. Use Bottlerocket bootstrap container for LVM configuration
  42. 2. Configure volume group name as `instance-store-vg`
  43. **Note:** While LVM setup may work on other instance types with local storage (like i3.xlarge, i4i.xlarge, r5d.xlarge), we have not extensively tested these configurations.
  44. #### Storage Configuration
  45. Once LVM is configured, set up the storage class (for example in misc/helm-charts/operator/values.yaml):
  46. ```yaml
  47. storage:
  48. storageClass:
  49. create: true
  50. name: "openebs-lvm-instance-store-ext4"
  51. provisioner: "local.csi.openebs.io"
  52. parameters:
  53. storage: "lvm"
  54. fsType: "ext4"
  55. volgroup: "instance-store-vg"
  56. ```
  57. While OpenEBS is our recommended solution, you can use any storage provisioner that meets your performance requirements by overriding the provisioner and parameters values.
  58. For example, to use a different storage provider:
  59. ```yaml
  60. storage:
  61. storageClass:
  62. create: true
  63. name: "your-storage-class"
  64. provisioner: "your.storage.provisioner"
  65. parameters:
  66. # Parameters specific to your chosen storage provisioner
  67. ```
  68. ## Installing the Chart
  69. To install the chart with the release name `my-materialize-operator`:
  70. ```shell
  71. helm install my-materialize-operator misc/helm-charts/operator --namespace materialize --create-namespace
  72. ```
  73. This command deploys the Materialize operator on the Kubernetes cluster with default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation.
  74. ## Uninstalling the Chart
  75. To uninstall/delete the `my-materialize-operator` deployment:
  76. ```shell
  77. helm delete my-materialize-operator
  78. ```
  79. This command removes all the Kubernetes components associated with the chart and deletes the release.
  80. ## Parameters
  81. The following table lists the configurable parameters of the Materialize operator chart and their default values.
  82. | Parameter | Description | Default |
  83. |-----------|-------------|---------|
  84. {{- range .Values }}
  85. | `{{ .Key }}` | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | {{ if .Default }}`{{ .Default }}`{{ else }}{{ .AutoDefault }}{{ end }} |
  86. {{- end }}
  87. Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:
  88. ```shell
  89. helm install my-materialize-operator \
  90. --set operator.image.tag={{ .AppVersion }} \
  91. materialize/materialize-operator
  92. ```
  93. Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example:
  94. ```shell
  95. helm install my-materialize-operator -f values.yaml materialize/materialize-operator
  96. ```
  97. ## Deploying Materialize Environments
  98. To deploy a Materialize environment, create a `Materialize` custom resource definition with the desired configuration.
  99. ```yaml
  100. apiVersion: v1
  101. kind: Namespace
  102. metadata:
  103. name: materialize-environment
  104. ---
  105. apiVersion: v1
  106. kind: Secret
  107. metadata:
  108. name: materialize-backend
  109. namespace: materialize-environment
  110. stringData:
  111. metadata_backend_url: "postgres://materialize_user:materialize_pass@postgres.materialize.svc.cluster.local:5432/materialize_db?sslmode=disable"
  112. persist_backend_url: "s3://minio:minio123@bucket/12345678-1234-1234-1234-123456789012?endpoint=http%3A%2F%2Fminio.materialize.svc.cluster.local%3A9000&region=minio"
  113. ---
  114. apiVersion: materialize.cloud/v1alpha1
  115. kind: Materialize
  116. metadata:
  117. name: 12345678-1234-1234-1234-123456789012
  118. namespace: materialize-environment
  119. spec:
  120. environmentdImageRef: materialize/environmentd:{{ .AppVersion }}
  121. backendSecretName: materialize-backend
  122. environmentdResourceRequirements:
  123. limits:
  124. memory: 16Gi
  125. requests:
  126. cpu: "2"
  127. memory: 16Gi
  128. balancerdResourceRequirements:
  129. limits:
  130. memory: 256Mi
  131. requests:
  132. cpu: 100m
  133. memory: 256Mi
  134. ```
  135. ## Configuration and Installation Details
  136. ### RBAC Configuration
  137. The chart creates a `ClusterRole` and `ClusterRoleBinding` by default. To use an existing `ClusterRole`, set `rbac.create=false` and specify the name of the existing `ClusterRole` using the `rbac.clusterRole` parameter.
  138. ### Observability
  139. To enable observability features, set `observability.enabled=true`. This will create the necessary resources for monitoring the operator. If you want to use Prometheus, also set `observability.prometheus.enabled=true`.
  140. ### Network Policies
  141. Network policies can be enabled by setting `networkPolicies.enabled=true`. By default, the chart uses native Kubernetes network policies. To use Cilium network policies instead, set `networkPolicies.useNativeKubernetesPolicy=false`.
  142. ## Troubleshooting
  143. If you encounter issues with the Materialize operator, check the operator logs:
  144. ```shell
  145. kubectl logs -l app.kubernetes.io/name=materialize-operator -n materialize
  146. ```
  147. For more detailed information on using and troubleshooting the Materialize operator, refer to the [Materialize documentation](https://materialize.com/docs).
  148. ## Upgrading
  149. Once you have the Materialize operator installed and managing your Materialize instances, you can upgrade both components. While the operator and instances can be upgraded independently, you should ensure version compatibility between them. The operator can typically manage instances within a certain version range - upgrading the operator too far ahead of your instances may cause compatibility issues.
  150. We recommend:
  151. - Upgrade the operator first
  152. - Always upgrade your Materialize instances after upgrading the operator to ensure compatibility
  153. ### Upgrading the Helm Chart
  154. To upgrade the Materialize operator to a new version:
  155. ```shell
  156. helm upgrade my-materialize-operator materialize/misc/helm-charts/operator
  157. ```
  158. If you have custom values, make sure to include your values file:
  159. ```shell
  160. helm upgrade my-materialize-operator materialize/misc/helm-charts/operator -f my-values.yaml
  161. ```
  162. ### Upgrading Materialize Instances
  163. To upgrade your Materialize instances, you'll need to update the Materialize custom resource and trigger a rollout.
  164. By default, the operator performs rolling upgrades (`inPlaceRollout: false`) which minimize downtime but require additional Kubernetes cluster resources during the transition. However, keep in mind that rolling upgrades typically take longer to complete due to the sequential rollout process. For environments where downtime is acceptable, you can opt for in-place upgrades (`inPlaceRollout: true`).
  165. #### Determining the Version
  166. The compatible version for your Materialize instances is specified in the Helm chart's `appVersion`. For the installed chart version, you can run:
  167. ```shell
  168. helm list -n materialize
  169. ```
  170. Or check the `Chart.yaml` file in the `misc/helm-charts/operator` directory:
  171. ```yaml
  172. apiVersion: v2
  173. name: materialize-operator
  174. # ...
  175. version: v25.3.0-beta-1
  176. appVersion: v0.147.0 # Use this version for your Materialize instances
  177. ```
  178. Use the `appVersion` (`v0.147.0` in this case) when updating your Materialize instances to ensure compatibility.
  179. #### Using `kubectl` patch
  180. For standard upgrades such as image updates:
  181. ```shell
  182. # For version updates, first update the image reference
  183. kubectl patch materialize <instance-name> \
  184. -n <materialize-instance-namespace> \
  185. --type='merge' \
  186. -p "{\"spec\": {\"environmentdImageRef\": \"materialize/environmentd:v0.147.0\"}}"
  187. # Then trigger the rollout with a new UUID
  188. kubectl patch materialize <instance-name> \
  189. -n <materialize-instance-namespace> \
  190. --type='merge' \
  191. -p "{\"spec\": {\"requestRollout\": \"$(uuidgen)\"}}"
  192. ```
  193. You can combine both operations in a single command if preferred:
  194. ```shell
  195. kubectl patch materialize 12345678-1234-1234-1234-123456789012 \
  196. -n materialize-environment \
  197. --type='merge' \
  198. -p "{\"spec\": {\"environmentdImageRef\": \"materialize/environmentd:v0.147.0\", \"requestRollout\": \"$(uuidgen)\"}}"
  199. ```
  200. #### Using YAML Definition
  201. Alternatively, you can update your Materialize custom resource definition directly:
  202. ```yaml
  203. apiVersion: materialize.cloud/v1alpha1
  204. kind: Materialize
  205. metadata:
  206. name: 12345678-1234-1234-1234-123456789012
  207. namespace: materialize-environment
  208. spec:
  209. environmentdImageRef: materialize/environmentd:v0.147.0 # Update version as needed
  210. requestRollout: 22222222-2222-2222-2222-222222222222 # Generate new UUID
  211. forceRollout: 33333333-3333-3333-3333-333333333333 # Optional: for forced rollouts
  212. inPlaceRollout: false # When false, performs a rolling upgrade rather than in-place
  213. backendSecretName: materialize-backend
  214. ```
  215. Apply the updated definition:
  216. ```shell
  217. kubectl apply -f materialize.yaml
  218. ```
  219. #### Forced Rollouts
  220. If you need to force a rollout even when there are no changes to the instance:
  221. ```shell
  222. kubectl patch materialize <instance-name> \
  223. -n materialize-environment \
  224. --type='merge' \
  225. -p "{\"spec\": {\"requestRollout\": \"$(uuidgen)\", \"forceRollout\": \"$(uuidgen)\"}}"
  226. ```
  227. The behavior of a forced rollout follows your `inPlaceRollout` setting:
  228. - With `inPlaceRollout: false` (default): Creates new instances before terminating the old ones, temporarily requiring twice the resources during the transition
  229. - With `inPlaceRollout: true`: Directly replaces the instances, causing downtime but without requiring additional resources
  230. ### Verifying the Upgrade
  231. After initiating the rollout, you can monitor the status:
  232. ```shell
  233. # Watch the status of your Materialize environment
  234. kubectl get materialize -n materialize-environment -w
  235. # Check the logs of the operator
  236. kubectl logs -l app.kubernetes.io/name=materialize-operator -n materialize
  237. ```
  238. ### Notes on Rollouts
  239. - `requestRollout` triggers a rollout only if there are actual changes to the instance (like image updates)
  240. - `forceRollout` triggers a rollout regardless of whether there are changes, which can be useful for debugging or when you need to force a rollout for other reasons
  241. - Both fields expect UUID values and each rollout requires a new, unique UUID value
  242. - `inPlaceRollout`:
  243. - When `false` (default): Performs a rolling upgrade by spawning new instances before terminating old ones. While this minimizes downtime, there may still be a brief interruption during the transition.
  244. - When `true`: Directly replaces existing instances, which will cause downtime.
  245. # Operational Guidelines
  246. Beyond the Helm configuration, there are other important knobs to tune to get the best out of Materialize within a
  247. Kubernetes environment.
  248. ## Instance Types
  249. Materialize has been vetted to work on instances with the following properties:
  250. - ARM-based CPU
  251. - 1:8 ratio of vCPU to GiB memory
  252. - 1:16 ratio of vCPU to GiB local instance storage (if enabling spill-to-disk)
  253. When operating in AWS, we recommend using the `r7gd` and `r6gd` families of instances (and `r8gd` once available)
  254. when running with local disk, and the `r8g`, `r7g`, and `r6g` families when running without local disk.
  255. ## CPU Affinity
  256. It is strongly recommended to enable the Kubernetes `static` [CPU management policy](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy).
  257. This ensures that each worker thread of Materialize is given exclusively access to a vCPU. Our benchmarks have shown this
  258. to substantially improve the performance of compute-bound workloads.
  259. ## Learn More
  260. - [Materialize Documentation](https://materialize.com/docs)
  261. - [Materialize GitHub Repository](https://github.com/MaterializeInc/materialize)
  262. {{ template "helm-docs.versionFooter" . }}