Deploy Helm* Charts =================== `Helm `_ is a powerful package manager for Kubernetes\* that provides a way to define, install, and upgrade cloud-native applications. Helm\* uses a packaging format called Charts, which are a collection of files that describe an application's deployment. There are many online guides and tutorials on how to create Helm Charts, and the `Helm documentation `_ is a good place to start. Development Process ------------------- The following steps outline the development process for creating Helm Charts: #. Create a new Helm Chart using the Helm CLI. This is a pretty complex NGINX\* chart and can be simplified for your application. Change directory into the newly created chart directory. .. code:: bash helm create mychart cd mychart #. Customize the Helm **Chart.yaml** and **values.yaml** to point to your application container image. #. Add, remove, or adjust the templated definitions of Kubernetes\* resources in the **templates** folder. #. Check the Helm chart syntax using: .. code:: bash helm lint . #. Examine the Helm chart rendered format with the `helm template` command. This will reveal how values are applied to the templates in the Chart. .. code:: bash helm -n test template --release-name foobar . .. note:: With Helm commands like `template` and `install`, additional override values.yaml can be imposed with **-f override-values.yaml**. This can be useful for testing different configurations of the Helm Chart, and is the method used by the |software_prod_name| to handle Profiles (see :doc:`../../app_orch/arch/data_model`). #. Try out the Helm chart on a Kubernetes cluster (`RKE2\* `_ is recommended). Ensure you can use the `kubectl` command. Ensure the `test` namespace exists. Use the command `helm -n test install foobar .` .. code:: shell kubectl get node kubectl create namespace test helm -n test install foobar . #. Check the Helm chart is installed correctly using `helm list`. If the chart is not installed correctly, use `helm uninstall` to remove the chart. .. code:: shell helm -n test list helm -n test uninstall foobar .. note:: The Helm Chart could be tested on the Edge Node cluster before it is pushed to the |software_prod_name| platform. The User guide describes how to access the KUBECONFIG file of an Edge Node cluster, which will allow testing. While this is an experimental approach, it can help with development and may give further insights into how the application will behave when deployed on the |software_prod_name| platform. #. Once you have a working Helm Chart, you can package it up and distribute it to other users. This can be done by packaging the chart with the Helm CLI. This will create a tarball of the Helm Chart, taking the name and version from the Chart.yaml file, and includes the values.yaml file. .. code:: shell helm package . #. It can be pushed to a Helm repository with: .. code:: shell helm push mychart-0.1.0.tgz oci://registry name/registry project .. note:: The |software_prod_name| platform comes with its own OCI-compatible registry capable of storing and distributing Helm charts and other artifacts. Deploy Applications Through |software_prod_name| ------------------------------------------------ The |software_prod_name| uses a Deployment Package to describe the deployment of an application (Helm Chart), covered in :doc:`../deployment-packages/index`. Helm Chart Best Practices ------------------------- When deploying an application onto Edge Node clusters through the |software_prod_name| platform, it is deployed using `Fleet `_ controller. This deploys Helm Charts using a built-in version of the Helm command. It also has the additional advantage that it tracks the lifecycle of each Kubernetes resource deployed, so that when it comes time to upgrade or delete the Helm Chart, it is done seamlessly. There are some caveats though that need to be observed to make this flow work properly: #. The Helm chart must restrict Jobs and Hooks that will change the values in resources that were deployed. This is because |software_prod_name| monitors the state of resources *it* deployed on the Edge Node cluster, to check their values are as expected. If something else is changing the values, then the deployment will not complete. This only applies to resources specified in the chart, and does not apply to **new** resources that might be created by a Job or Hook. They will be owned by whatever created them. #. It is not recommended to create a namespace in the Helm chart. |software_prod_name| has a method to manage namespaces outside of the Helm Chart that ensures they are cleaned up properly on delete. Neither should you specify the namespace in resources in your Helm\* Chart unless completely necessary. Helm\* will populate the namespace when none is specified. #. If the Helm Chart includes Custom Resource Definitions (CRDs), please follow the `Helm best practices document `_. #. If deploying to :doc:`Edge Microvisor Toolkit ` please be aware that it features an immutable root file system, and this may require additional effort to ensure that your application does not use Host Paths or other features that might attempt to write to the immutable partition. #. Lint the helm chart with **helm lint** before deploying it. This will check for common mistakes and issues in the chart. Use **helm template** to do a visual inspection of how the helm chart values files are applied to the templates. .. code:: shell helm lint . helm -n testns template --release-name foobar . -f #. Be aware of the preinstalled network policies applied to various namespaces on the Edge Node cluster. These can be seen in `network-policies `_ or by running `kubectl` on the Edge Node: .. code:: shell kubectl get networkpolicy -A kubectl get globalnetworkpolicies.crd.projectcalico.org -A kubectl get networkpolicies.crd.projectcalico.org -A Do not install a Helm resources in to the `default` or `kube-system` namespaces. #. Try to reuse the **preinstalled** facilities of the Edge Node where possible, rather than deploying your own. For example the Edge Node standard installation includes these preinstalled facilities: * cert-manager * prometheus * openebs See `base-extensions `_ for the full list. #. Try to reuse the **optional** Extensions that can be used alongside your application on the Edge Node. These are listed in detail in :doc:`/user_guide/package_software/extension_package` Examples include: * Load Balancer - includes MetalLB\* and NGINX\* ingress controller * Intel® GPU - a Kubernetes device plugin for Intel® GPUs * SRIOV - a Kubernetes device plugin for SRIOV devices #. Be aware of the different :doc:`/user_guide/additional_howtos/set_up_a_cluster_template` that are in effect on the Edge Node(s) that you are deploying to. The **Privileged** cluster template is the most permissive template but also provides the least secure enforcement. While choosing `Privileged` may lead to a successful deployment, a more thorough evaluation of the templates and your application’s may allow you to use **BaseLine** or **Restricted** instead and will lead to a more secure experience for our customers. The following rules apply: * `Restricted` - if your application can work with `Restricted` cluster template then it will work with Edge Node clusters that have been setup with any cluster template. * `Baseline` - if your application requires `Baseline` it will work only with Edge Node clusters that have been setup with `Baseline` or `Privileged`. * `Privileged` - if your application requires `Privileged` it will work only with Edge Node clusters that have been setup with `Privileged`. The Cluster Template also covers some of the networking configuration including CNI. If the application is not dependent on any specific configuration, then default configuration can be left as is. #. Scan the Helm Chart for security vulnerabilities. This can be done using `Trivy `_. .. code:: shell trivy config . --severity HIGH,CRITICAL Service Link Support -------------------- |software_prod_name| has a feature called Service Link (Application Service Proxy) that allows the deployed application to be launched directly from the |software_prod_name| Web UI. This is done by configuring the Kubernetes Service with an extra annotation that will be handled in a special way by the |software_prod_name|. See :doc:`Service Link Support ` for more details.