diff --git a/.github/workflows/helm-chart.yml b/.github/workflows/helm-chart.yml new file mode 100644 index 0000000..e53635d --- /dev/null +++ b/.github/workflows/helm-chart.yml @@ -0,0 +1,44 @@ +name: Prerelease Helm Chart + +on: + workflow_dispatch: + push: + branches: + - Helm_artifacts + +env: + HELM_CHART_VERSION: 1.1.0 + MATLAB_APP_VERSION: "R2024b" + +jobs: + release-helm-chart: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Install Helm + uses: azure/setup-helm@v4 + + - name: Check that chart exists + run: | + CHART_DIR="releases/${{ env.MATLAB_APP_VERSION }}/matlab-prodserver" && cat ${CHART_DIR}/Chart.yaml + echo "CHART_DIR=${CHART_DIR}" >> $GITHUB_ENV # Add to env if exists + + - name: Check chart versions + run: | + grep 'version: ${{ env.HELM_CHART_VERSION }}' ${CHART_DIR}/Chart.yaml && grep 'appVersion: "${{ env.MATLAB_APP_VERSION }}"' ${CHART_DIR}/Chart.yaml + + - name: Package the chart + run: helm package ${CHART_DIR} --version ${{ env.HELM_CHART_VERSION }} --app-version ${{ env.MATLAB_APP_VERSION }} + + - name: Login to GitHub Container Registry + run: echo ${{ secrets.CR_TOKEN }} | helm registry login ${{ secrets.MATHWORKS_REGISTRY }} --username ${{ secrets.CR_USER }} --password-stdin + + - name: Deploy the chart + run: helm push matlab-prodserver-k8s-${{ env.HELM_CHART_VERSION }}.tgz oci://${{ secrets.MATHWORKS_REGISTRY }} + diff --git a/README.md b/README.md index 9d6fe9f..bef5930 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,42 @@ Before starting, you need the following: * [Git™](https://git-scm.com/) * [Docker®](https://www.docker.com/) * Running [Kubernetes](https://kubernetes.io/) cluster that meets the following conditions: - * Uses Kubernetes version 1.27 or later. + * Uses Kubernetes version 1.28 or later. * Each MATLAB Production Server container in the Kubernetes cluster requires at least 1 CPU core and 2 GiB RAM. * [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) command-line tool that can access your Kubernetes cluster * [Helm](https://helm.sh/) package manager to install Helm charts that contain preconfigured Kubernetes resources for MATLAB Production Server - * Uses Helm version v3.13.0 or later. + * Uses Helm version v3.14 or later. If you do not have a license, please contact your MathWorks representative [here](https://www.mathworks.com/company/aboutus/contact_us/contact_sales.html) or [request a trial license](https://www.mathworks.com/campaigns/products/trials.html?prodcode=PR). +## Quick Start +The Quick Start option is recommended for the following cases: +* You are deploying MATLAB Production Server R2024b or newer +* You don't require significant changes to the Helm chart +* You are not running MATLAB Production server on Kubernetes as part of a CI/CD workflow +For CI/CD workflows, we recommend that you cache docker images in your private container registry. For more complex workflows, use the [Deployment Steps](#Deployment-Steps) + +The Quick Start option only requires you to download a single file, rather than cloning the full GitHub repository. For more complex workflows, use the [Deployment Steps](#Deployment-Steps) + +1. Download the `values-overrides.yaml` file containing configuration options that apply across all release deployments from the MATLAB Production Server on Kubernetes GitHub repository. You can use the cURL command below or click the "Download Raw File" icon. + ``` + curl -O https://raw.githubusercontent.com/mathworks-ref-arch/matlab-production-server-on-kubernetes/main/values-overrides.yaml + ``` + +2. Complete the steps in [Provide Mapping for Deployable Archives](#Provide-Mapping-for-Deployable-Archives). + +3. Before installing the chart, first set parameters that state your agreement to the MathWorks cloud reference architecture license and specify the address of the network license manager. In the top-level values-overrides.yaml file, set these parameters: + + To accept the license terms, set global > agreeToLicense to "yes". + To specify the address of the license server, set global > licenseServer using the format port_number@host. + + Next, install the Helm chart for MATLAB Production Server by using the following `helm install` command: + + ``` + helm install -f [-n ] --generate-name oci://containers.mathworks.com/matlab-prodserver-k8s --version 1.1.0 + ``` +4. After the deployment is complete, upload the MATLAB Production Server deployable archive to your network file server or Azure file share. All users must have read permission to the deployable archive. + ## Deployment Steps ### Clone GitHub® Repository that Contains Helm Chart The MATLAB Production Server on Kubernetes GitHub repository contains Helm charts that reference Ubuntu-based Docker container images for MATLAB Production Server deployment. @@ -43,7 +71,7 @@ The MATLAB Production Server on Kubernetes GitHub repository contains Helm chart ``` This repository includes Helm chart folders for each supported MATLAB Production Server release and a `values-overrides.yaml` file containing configuration options that apply across all release deployments. -2. Navigate to the Helm chart folder for the release you want to use. Replace `` with the release version, for example, `R2024a`. +2. Navigate to the Helm chart folder for the release you want to use. Replace `` with the release version, for example, `R2024b`. ``` cd matlab-production-server-on-kubernetes/releases//matlab-prodserver ``` @@ -60,7 +88,7 @@ The MATLAB Production Server on Kubernetes GitHub repository contains Helm chart ``` * `containers.mathworks.com` is the name of the container registry. * `matlab-production-server` is the name of the repository. - * `` is the tag name of the MATLAB Production Server release, for example, `r2024a`. + * `` is the tag name of the MATLAB Production Server release, for example, `r2024b`. The `values.yaml` file specifies these values in the `productionServer` section, in the `registry`, `repository`, and `tag` variables, respectively. @@ -71,7 +99,7 @@ The MATLAB Production Server on Kubernetes GitHub repository contains Helm chart ``` * `containers.mathworks.com` is the name of the container registry. * `matlab-runtime` is the name of the repository. - * `` is the tag name of the MATLAB Runtime release. Update this value to the release version of the MATLAB Runtime you are using, for example, `r2024a`. MATLAB Production Server supports MATLAB Runtime versions up to six releases back from the MATLAB Production Server version you are using. + * `` is the tag name of the MATLAB Runtime release. Update this value to the release version of the MATLAB Runtime you are using, for example, `r2024b`. MATLAB Production Server supports MATLAB Runtime versions up to six releases back from the MATLAB Production Server version you are using. The `values.yaml` file specifies these values in the `matlabRuntime` section, in the `registry`, `repository`, and `tag` variables, respectively. diff --git a/releases/R2021b/matlab-prodserver/templates/mps-1-service-ingress.yaml b/releases/R2021b/matlab-prodserver/templates/mps-1-service-ingress.yaml deleted file mode 100644 index 033a215..0000000 --- a/releases/R2021b/matlab-prodserver/templates/mps-1-service-ingress.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# -# Expose MATLAB Production Server internal endpoint -# -kind: Service -apiVersion: v1 -metadata: - name: matlab-production-server - namespace: {{ .Release.Namespace }} - labels: - app: mps - release: {{ .Release.Name }} -spec: - selector: - app: mps - ports: - - name: mps-port - port: 9910 - targetPort: 9910 - type: ClusterIP - ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: matlab-production-server-ingress - namespace: {{ .Release.Namespace }} - labels: - release: {{ .Release.Name }} - annotations: - {{ if .Values.global.ingressController }} - ## set ingress-conroller vendor-specific annotations: - {{- range $key, $value := .Values.global.ingressController.annotations }} - {{ $key }}: {{ quote $value }} - {{- end }} - {{ end }} -spec: - ingressClassName: {{ .Values.global.ingressController.name }} - rules: - - host: {{ .Values.global.ingressController.domainBase }} - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: matlab-production-server - port: - number: 9910 - diff --git a/releases/R2021b/matlab-prodserver/Chart.yaml b/releases/R2024b/matlab-prodserver/Chart.yaml similarity index 74% rename from releases/R2021b/matlab-prodserver/Chart.yaml rename to releases/R2024b/matlab-prodserver/Chart.yaml index 97460b3..fac2a9f 100644 --- a/releases/R2021b/matlab-prodserver/Chart.yaml +++ b/releases/R2024b/matlab-prodserver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: "R2021b" +appVersion: "R2024b" description: MATLAB Production Server Helm chart for Kubernetes name: matlab-prodserver-k8s -version: 0.1.0 +version: 1.1.0 diff --git a/releases/R2024b/matlab-prodserver/templates/mps-1-service-ingress.yaml b/releases/R2024b/matlab-prodserver/templates/mps-1-service-ingress.yaml new file mode 100644 index 0000000..0c2c9a5 --- /dev/null +++ b/releases/R2024b/matlab-prodserver/templates/mps-1-service-ingress.yaml @@ -0,0 +1,83 @@ +# +# Expose MATLAB Production Server internal endpoint +# +kind: Service +apiVersion: v1 +metadata: + name: matlab-production-server + namespace: {{ .Release.Namespace }} + labels: + app: mps + release: {{ .Release.Name }} +spec: + selector: + app: mps + ports: + - name: mps-port + port: 9910 + targetPort: 9910 + type: ClusterIP + +--- +{{- if .Values.global.ingressController.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: matlab-production-server-ingress + namespace: {{ .Release.Namespace }} + labels: + release: {{ .Release.Name }} + annotations: + {{ if .Values.global.ingressController }} + ## set ingress-conroller vendor-specific annotations: + {{- range $key, $value := .Values.global.ingressController.annotations }} + {{ $key }}: {{ quote $value }} + {{- end }} + {{ end }} +spec: + ingressClassName: {{ .Values.global.ingressController.name }} + {{ if .Values.global.ingressController.tls.enabled }} + tls: + - hosts: + - {{ .Values.global.ingressController.domainBase }} + {{- if .Values.global.ingressController.tls.secretName }} + secretName: {{ .Values.global.ingressController.tls.secretName }} + {{- end }} + {{ end }} + + rules: + - host: {{ .Values.global.ingressController.domainBase }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: matlab-production-server + port: + number: 9910 +{{- end }} + +--- +{{ if and (.Values.optionalSettings.Prometheus.enabled) (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: matlab-production-server-monitor + labels: + app: mps + app.kubernetes.io/part-of: {{ .Values.optionalSettings.Prometheus.matchOn }} + release: {{ .Values.optionalSettings.Prometheus.matchOn }} +spec: + selector: + matchLabels: + app: mps + release: {{ .Release.Name }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + endpoints: + - port: mps-port + path: /api/metrics +{{ end }} + diff --git a/releases/R2021b/matlab-prodserver/templates/mps-2-configmap.yaml b/releases/R2024b/matlab-prodserver/templates/mps-2-configmap.yaml similarity index 84% rename from releases/R2021b/matlab-prodserver/templates/mps-2-configmap.yaml rename to releases/R2024b/matlab-prodserver/templates/mps-2-configmap.yaml index 9f3e110..3b3dfec 100644 --- a/releases/R2021b/matlab-prodserver/templates/mps-2-configmap.yaml +++ b/releases/R2024b/matlab-prodserver/templates/mps-2-configmap.yaml @@ -9,7 +9,7 @@ data: main_config: | --http 9910 --ssl-verify-peer-mode no-verify-peer - --ssl-protocols TLSv1.1,TLSv1.2 + --ssl-protocols TLSv1.2 --ssl-ciphers ALL --mcr-root /opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }} --num-workers {{ .Values.matlabProductionServerSettings.numWorkers | default 1 }} @@ -42,6 +42,7 @@ data: --server-memory-threshold-overflow-action purge_responses --enable-discovery --enable-metrics + --routes-file ./config/routes.json {{- if .Values.optionalSettings.Redis.host }} mps_cache_config: | @@ -49,8 +50,18 @@ data: {"{{ .Values.optionalSettings.Redis.name }}": {"Provider":"Redis", "Host":{{ .Values.optionalSettings.Redis.host | quote }}, - "Port":{{ .Values.optionalSettings.Redis.port | default 6379 }}} + "Port":{{ .Values.optionalSettings.Redis.port | default 6379 }} + {{- if .Values.optionalSettings.Redis.auth }} + ,"Key":{{ .Values.optionalSettings.Redis.auth | quote }} + {{- end }} + } } } {{- end }} + routes.json: | + { + "version": "1.0.0", + "pathmap": [] + } + diff --git a/releases/R2021b/matlab-prodserver/templates/mps-3-deployment.yaml b/releases/R2024b/matlab-prodserver/templates/mps-3-deployment.yaml similarity index 70% rename from releases/R2021b/matlab-prodserver/templates/mps-3-deployment.yaml rename to releases/R2024b/matlab-prodserver/templates/mps-3-deployment.yaml index a319f63..1743fc8 100644 --- a/releases/R2021b/matlab-prodserver/templates/mps-3-deployment.yaml +++ b/releases/R2024b/matlab-prodserver/templates/mps-3-deployment.yaml @@ -19,25 +19,34 @@ spec: labels: app: mps annotations: + {{ if not .Values.optionalSettings.Prometheus.enabled }} prometheus.io/scrape: 'true' prometheus.io/path: '/api/metrics' prometheus.io/port: '9910' + {{ end }} spec: securityContext: runAsNonRoot: true - runAsUser: 1000 - runAsGroup: 1000 + runAsUser: 1001 + runAsGroup: 1001 containers: - name: mps - image: {{ .Values.images.productionServer.registry }}/{{ .Values.images.productionServer.repository }}:{{ .Values.images.productionServer.tag }} + image: {{ .Values.global.images.registry | default .Values.images.productionServer.registry }}/{{ .Values.images.productionServer.repository }}:{{ .Values.images.productionServer.tag }} env: - name: AGREE_TO_MATHWORKS_SOFTWARE_LICENSE - value: {{ .Values.global.agreeToLicense | default "no" | lower | quote }} + value: {{ required "agreeToLicense must be set to \"yes\"." .Values.global.agreeToLicense | default "no" | lower | quote }} - name: AGREE_TO_MATLAB_RUNTIME_LICENSE - value: {{ .Values.global.agreeToLicense | default "no" | lower | quote }} + value: {{ required "agreeToLicense must be set to \"yes\"." .Values.global.agreeToLicense | default "no" | lower | quote }} - name: LD_LIBRARY_PATH value: "/opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/runtime/glnxa64:/opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/bin/glnxa64:/opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/sys/os/glnxa64:/opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/extern/bin/glnxa64:/opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/sys/opengl/lib/glnxa64" + {{ if .Values.optionalSettings.Redis.secretName }} + - name: MPS_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.optionalSettings.Redis.secretName }} + key: {{ .Values.optionalSettings.Redis.secretKey | default "redis-password" }} + {{ end }} ports: - containerPort: 9910 @@ -62,8 +71,8 @@ spec: exec: command: - ls - - /opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/MCR_license.txt - initialDelaySeconds: 30 + - /opt/matlabruntime/{{ .Values.images.matlabRuntime.variant }}/matlabruntime_license_agreement.pdf + initialDelaySeconds: 10 periodSeconds: 30 livenessProbe: @@ -82,7 +91,7 @@ spec: initContainers: - name: matlab-runtime - image: {{ .Values.images.matlabRuntime.registry }}/{{ .Values.images.matlabRuntime.repository }}:{{ .Values.images.matlabRuntime.tag }} + image: {{ .Values.global.images.registry | default .Values.images.matlabRuntime.registry }}/{{ .Values.images.matlabRuntime.repository }}:{{ .Values.images.matlabRuntime.tag }} command: - /bin/sh @@ -97,10 +106,13 @@ spec: restartPolicy: {{ .Values.deploymentSettings.restartPolicy }} imagePullSecrets: + {{- if .Values.global.images.pullSecret }} + - name: {{ .Values.global.images.pullSecret }} + {{- end }} {{- if .Values.images.productionServer.pullSecret }} - name: {{ .Values.images.productionServer.pullSecret }} {{- end }} - {{- if .Values.images.matlabRuntime.pullSecret }} + {{- if and .Values.images.matlabRuntime.pullSecret (ne .Values.images.matlabRuntime.pullSecret .Values.images.productionServer.pullSecret) }} - name: {{ .Values.images.matlabRuntime.pullSecret }} {{- end }} @@ -120,6 +132,9 @@ spec: server: {{ .Values.matlabProductionServerSettings.autoDeploy.server }} path: {{ .Values.matlabProductionServerSettings.autoDeploy.path }} readOnly: true + {{- else if eq .Values.matlabProductionServerSettings.autoDeploy.volumeType "pvc" }} + persistentVolumeClaim: + claimName: {{ .Values.matlabProductionServerSettings.autoDeploy.claimName }} {{- else if eq .Values.matlabProductionServerSettings.autoDeploy.volumeType "azurefileshare" }} azureFile: shareName: {{ .Values.matlabProductionServerSettings.autoDeploy.shareName }} diff --git a/releases/R2021b/matlab-prodserver/values.yaml b/releases/R2024b/matlab-prodserver/values.yaml similarity index 57% rename from releases/R2021b/matlab-prodserver/values.yaml rename to releases/R2024b/matlab-prodserver/values.yaml index 79ac5d7..7386a7d 100644 --- a/releases/R2021b/matlab-prodserver/values.yaml +++ b/releases/R2024b/matlab-prodserver/values.yaml @@ -5,17 +5,28 @@ global: agreeToLicense: "" # Network License Manager: server host and port number, example: 27000@hostname licenseServer: 27000@hostname + # Override for a private container registry, example: cr.example.com, cr-secret + images: + registry: "" + pullSecret: "" ingressController: + enabled: false # Create 'Ingress' API object # Nginx settings (optional) name: nginx - annotations: - nginx.ingress.kubernetes.io/load-balance: "round_robin" + annotations: {} + + # Ingress host domainBase: matlabprodserver.mwcloudtest.com + # Ingress https (tls termination) + tls: + enabled: false + # Name of kubernetes.io/tls secret with certificate data + secretName: "" matlabProductionServerSettings: # CTF files are placed here for automatic deployment. autoDeploy: - # Inline mount options: hostpath, nfs, azurefileshare, empty (default) + # Inline mount options: hostpath, nfs, pvc, azurefileshare, empty (default) volumeType: "empty" # Node mount dir, example: /mnt/share/autodeploy hostpath: "" @@ -25,6 +36,9 @@ matlabProductionServerSettings: # NFS subpath, example: /vmgr/sandbox/share/autodeploy path: "" # ================================================================= + # Persistent-Volume-Claim name, example: autodeploy-pv-claim + claimName: "" + # ================================================================= # Azure storage account file share name, example: auto-deploy-share shareName: "" # Azure storage account key secret name, example: azure-file-secret @@ -37,16 +51,16 @@ images: productionServer: registry: containers.mathworks.com repository: matlab-production-server - tag: r2021b - variant: R2021b + tag: r2024b + variant: R2024b pullPolicy: IfNotPresent pullSecret: "" matlabRuntime: registry: containers.mathworks.com repository: matlab-runtime - tag: r2021b - variant: v911 + tag: r2024b + variant: R2024b pullPolicy: IfNotPresent pullSecret: "" @@ -58,6 +72,18 @@ deploymentSettings: optionalSettings: Redis: - host: {} + # Redis service fully qualified name, example: redis.namespace.svc.cluster.local + host: "" + auth: "" name: myRedis + port: 6379 + secretName: "" + secretKey: "" + Prometheus: + # Create a ServiceMonitor [monitoring.coreos.com/v1] for metrics discovery. + # Requires Prometheus and Prometheus Operator (CRDs) to be pre-installed. + enabled: false + # Helm release name or app.kubernetes.io/part-of label of Prometheus stack. + # ServiceMonitor needs to match on this value (if Prometheus is enabled). + matchOn: prometheus diff --git a/values-overrides.yaml b/values-overrides.yaml index a0f190e..1911581 100644 --- a/values-overrides.yaml +++ b/values-overrides.yaml @@ -12,7 +12,7 @@ global: # Ingress settings (optional) ingressController: - enabled: true # Create 'Ingress' API object + enabled: false # Create 'Ingress' API object name: nginx annotations: nginx.ingress.kubernetes.io/affinity: "cookie"