Skip to content

Instantly share code, notes, and snippets.

@coltoneshaw
Last active October 30, 2023 18:28
Show Gist options
  • Save coltoneshaw/88dedf92d486529d351620403966cec6 to your computer and use it in GitHub Desktop.
Save coltoneshaw/88dedf92d486529d351620403966cec6 to your computer and use it in GitHub Desktop.
Mattermost Kubernetes Azure setup

Mattermost Kubernetes Azure setup

This guide shows you how to setup Mattermost deployed via Kubernetes.

Prereqs

  • Have an Azure account
  • Have a domain name that can be used.

Setup

  1. Download the azure CLI for your OS

    macOS:

    brew update && brew install azure-cli
  2. Authenticate the CLI

    This will open a new window to log into your Microsoft account.

    az login
  3. Create an azure resource group.

    Replace myResourceGroup with a group name you choose.

    az group create --name myResourceGroup --location eastus
  4. Create a PostgreSQL database.

    Note: You must use a flexible-server because single-server does not included Postgres > 11.

    • name : Replace with a name for your database
    • resource-group: The same resource group you created above.
    • database-name: The name of the database to be created when provisioning the database server.
    • admin-user: PostgreSQL admin user
    • admin-password: password for the PostgreSQL admin user.
    • tier: The Azure database tier that has the sku-name needed.
    • sku-name: The sku that has the resources you want in the tier you're in. You can find the descriptions on the above link under the tier you pick.
    • storage-size : The storage capacity of the server. Minimum is 32 GiB and max is 16 TiB. Default: 128.
    • version: PostgreSQL version of the server.
    • public-access : Determines the public access. Enter single or range of IP addresses to be included in the allowed list of IPs. IP address ranges must be dash-separated and not contain any spaces. Specifying 0.0.0.0 allows public access from any resources deployed within Azure to access your server. Setting it to "None" sets the server in public access mode but does not create a firewall rule.
    az postgres flexible-server create \
        --name mattermost-postgres \
        --resource-group myResourceGroup \
        --database-name mattermost \
        --location "East US" \
        --admin-user mmuser \
        --admin-password Testpassword123! \
        --tier MemoryOptimized \
        --sku-name Standard_E4ads_v5 \
        --storage-size 128 \
        --public-access 0.0.0.0 \
        --version 14

    Copy the connectionString value returned for later.

  5. Create an AKS cluster.

    az aks create \
        -g myResourceGroup \
        -n myAKSCluster \
        --enable-managed-identity \
        --node-count 2 \
        --generate-ssh-keys \
        --network-policy calico \
        --network-plugin kubenet \
        --enable-blob-driver
  6. Install the AKS credentials to kubectl

    Replace myResourceGroup and myAKSCluster with the group and name you created above.

    az aks get-credentials --resource-group myResourceGroup --admin --name myAKSCluster
  7. Install the NGINX controller to the AKS cluster

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
  8. Install the Mattermost Operator

kubectl create ns mattermost-operator
kubectl apply -n mattermost-operator -f https://raw.githubusercontent.com/mattermost/mattermost-operator/master/docs/mattermost-operator/mattermost-operator.yaml

Check that the operator pod is running with kubectl get pod -n mattermost-operator

  1. Create the namespace for mattermost.

    Your namespace can be anything you want like such as "mattermost".

    kubectl create namespace mattermost
  2. Create your installation file and add a database block.

    1. Create the mattermost-install.yaml file.

      touch mattermost-install.yaml
    2. Grab your connection string from step 4 and paste it into a text editor. Replace postgresql:// with postgres://

      It should look like the below now:

      postgres://mmuser:Testpassword123!@mattermost-postgres2.postgres.database.azure.com/postgres-mattermost?sslmode=require
    3. Base64 encode the string, any method you like.

      > echo -n 'postgres://mmuser:example@mattermost.postgres.database.azure.com/postgres-mattermost?sslmode=require' | base64
      cG9zdGdyZXM6Ly9tbXVzZXI6ZXhhbXBsZUBtYXR0ZXJtb3N0LnBvc3RncmVzLmRhdGFiYXNlLmF6dXJlLmNvbS9wb3N0Z3Jlcy1tYXR0ZXJtb3N0P3NzbG1vZGU9cmVxdWlyZQ==
    4. Paste the above encoded string into the file below in place of the base64String. Both DB_CONNECTION_CHECK_URL and DB_CONNECTION_STRING should match.

      apiVersion: v1
      data:
          DB_CONNECTION_CHECK_URL: base64String
          DB_CONNECTION_STRING: base64String
      kind: Secret
      metadata:
          name: my-postgres-connection
      type: Opaque
      
      ---
    5. Save the file.

  3. Add a license file block to the mattermost-install.yaml file.

    1. Paste the below value into the mattermost-install.yaml file under the last --- line.

      apiVersion: v1
      kind: Secret
      metadata:
          name: mattermost-license
      type: Opaque
      stringData:
          # Text from the mattermost-license file.
          license: licenseFileString
      
      ---
    2. Replace the licenseFileString with the text from your mattermost license file.

    3. Save the file.

  4. Add the storage block to the mattermost-install.yaml file.

    1. Place the below value into the mattermost-install.yaml file under the --- link.

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
          # Can be anything you'd like to name your volume.
          name: mattermost-storage
          annotations:
              #  the same storage class you use in `storageClassName`
              volume.beta.kubernetes.io/storage-class: azureblob-nfs-premium
      
      spec:
          accessModes: ["ReadWriteMany"]
          # The options available are [here](https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/aks/concepts-storage.md#storage-classes).
          storageClassName: azureblob-nfs-premium
          resources:
              requests:
                  # the size of the storage space. You can scale this up later as needed. 
                  storage: 100Gi
      ---
    2. Modify the values with commends above them.

    3. Save the file

  5. Add the mattermost block to the mattermost-install.yaml file.

    1. Place the below values into the mattermost-install.yaml file under the previous --- link.

      apiVersion: installation.mattermost.com/v1beta1
      kind: Mattermost
      metadata:
          # Name of the Mattermost cluster as shown in Kubernetes.
          name: mattermost-service 
      spec:
      database:
          external:
              # postgres secret name from step 10.
              secret: my-postgres-connection
      elasticSearch: {}
      # Name of a Kubernetes secret that contains Mattermost license. Required only for enterprise installation.
      licenseSecret: "mattermost-license"
      fileStore:
          externalVolume:
          # Volume name from step 12
          volumeClaimName: mattermost-storage
      image: mattermost/mattermost-enterprise-edition
      imagePullPolicy: IfNotPresent
      ingress:
          enabled: true
          # Leave this as is and it will be removed in the next step.
          host: mattermost.example.com
          annotations:
              kubernetes.io/ingress.class: nginx
      podExtensions: {}
      probes:
          livenessProbe: {}
          readinessProbe: {}
      # Number of Mattermost replicas
      replicas: 3
      # version of Mattermost
      version: 9.1.0
    2. Modify any necessary values as noted by the comments.

  6. Apply the config file

    Note: -n mattermost - This is the namespace you created above.

    kubectl apply -n mattermost -f mattermost-installation.yaml
  7. Monitor until complete. This process takes 2-3 minutes.

    Note: -n mattermost - This is the namespace you created above.

    kubectl -n mattermost get mm -w

    If you need to debug anything you can use the below commands. Usually the error is in the operator events/logs or the mattermost pods.

    Common Commands

    • kubectl get pods -A - Returns a list of the existing pods. You'll see mattermost-service pods that are bring create.
    • kubectl logs -n [namespace] [pod] - View logs for a specific namespace / pod
    • kubectl events -n [namespace] [pod]- view events for a specific namespace / pod
  8. Access your Mattermost install via the domain name and confirm all is working.

Final File

apiVersion: v1
data:
    DB_CONNECTION_CHECK_URL: base64String
    DB_CONNECTION_STRING: base64String
kind: Secret
metadata:
    name: my-postgres-connection
type: Opaque

---

apiVersion: v1
kind: Secret
metadata:
  name: mattermost-license
type: Opaque
stringData:
  license: licenseFileString

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    # Can be anything you'd like to name your volume.
    name: mattermost-storage
    annotations:
        #  the same storage class you use in `storageClassName`
        volume.beta.kubernetes.io/storage-class: azureblob-nfs-premium
spec:
    accessModes: ["ReadWriteMany"]
    # The options available are [here](https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/aks/concepts-storage.md#storage-classes).
    storageClassName: azureblob-nfs-premium
    resources:
        requests:
            # the size of the storage space. You can scale this up later as needed. 
            storage: 100Gi
---

apiVersion: installation.mattermost.com/v1beta1
kind: Mattermost
metadata:
    # Name of the Mattermost cluster as shown in Kubernetes.
    name: mattermost-service 
spec:
    size: 1000users
    database:
        external:
            # postgres secret name from step 10.
            secret: my-postgres-connection
    elasticSearch: {}
    # Name of a Kubernetes secret that contains Mattermost license. Required only for enterprise installation.
    licenseSecret: "mattermost-license"
    fileStore:
        externalVolume:
            # Volume name from step 12
            volumeClaimName: mattermost-storage
    image: mattermost/mattermost-enterprise-edition
    imagePullPolicy: IfNotPresent
        ingress:
        annotations:
            kubernetes.io/tls-acme: "true"
            # nginx.ingress.kubernetes.io/configuration-snippet: "\n\t\t\t\t  proxy_force_ranges
            # on;\n\t\t\t\t  add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\"
            # always;\n\t\t\t\t  proxy_cache mattermost_cache;\n\t\t\t\t  proxy_cache_revalidate
            # on;\n\t\t\t\t  proxy_cache_min_uses 2;\n\t\t\t\t  proxy_cache_use_stale timeout;\n\t\t\t\t
            # \ proxy_cache_lock on;\n\t\t\t\t  proxy_cache_key \"$host$request_uri$cookie_user\";"
            nginx.ingress.kubernetes.io/proxy-body-size: 100m
            nginx.ingress.kubernetes.io/proxy-buffering: "on"
            nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0"
            nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
            nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
            nginx.ingress.kubernetes.io/ssl-redirect: "true"
            nginx.org/server-snippets: gzip on;
            kubernetes.io/ingress.class: nginx
        enabled: true
        # Leave this as is and it will be removed in the next step.
        host: mattermost.example.com
    ingressName: ""
    podExtensions: {}
    probes:
        livenessProbe: {}
        readinessProbe: {}
    # Number of Mattermost replicas
    # replicas: 3
    # version of Mattermost
    version: 9.1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment