EKSでMattermostを構築した話：5-2. Mattermost Configの設定(helmのチューニング02)

## これまでの復習
- EKSでMattermostを構築ということで少しずつ進めてきました。

1.  [EKSでMattermostを構築した話：0.概要編 - Qiita](https://qiita.com/tnagano1981/items/555301cecd3ed309fa43)
1.  [EKSでMattermostを構築した話：1. VPC作成編 - Qiita](https://qiita.com/tnagano1981/items/75408d509c0660408c97)
1.  [EKSでMattermostを構築した話：2. EKSクラスター作成編 - Qiita](https://qiita.com/tnagano1981/items/fc5d96ddf9a3b5c4fb03)
1.  [EKSでMattermostを構築した話：3-1. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/c91d27fa2e286a96b6ff)
1. [EKSでMattermostを構築した話：3-2. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/b477f3a6a21038b76db2)
1. [EKSでMattermostを構築した話：4-1. Mattermostのインストール(helm理解編) - Qiita](https://qiita.com/tnagano1981/items/9c36cf9f0a6196fcf865)
1. [EKSでMattermostを構築した話：4-2. Mattermostのインストール(helm適用編) - Qiita](https://qiita.com/tnagano1981/items/289d375135f64f5241a2)
1. [EKSでMattermostを構築した話：5-1. Mattermost Configの設定(helmのチューニング01) - Qiita](https://qiita.com/tnagano1981/items/9e06f71c25ceccfaf6fb)
1. Mattermost Configの設定(helmのチューニング02) ← `今回はここ`

## Mattermost Configの設定を続けていきます

- 前回では3まで対応したので、4から対応していきます。
    1. `S3連携` データを消失させないために、S3と連携させる
    1. `RDS連携` データベースを切り出すために、RDSと連携させる
    1. `SES連携`Mattermostユーザーがパスワードを忘れた際に再設定をさせるために、SESと連携させる
    1. `EFS連携`Mattermostのプラグイン機能を実現するために、EFSと連携させる
    1. `ALB連携` アプリケーションロードバランサーを構築するために、ALBと連携させる
    1. `Route53連携` ALBのDNS名を自動的に指定したFQDNと紐付けるために、Route53と連携させる



### 4. `EFS連携`Mattermostのプラグイン機能を実現するために、EFSと連携させる
- 前提
    - Mattermostはチャットアプリなので、投稿(テキスト)や添付ファイル(画像やExcelなど)をチャットのやりときで利用します。これらは手順の1や2で対応した結果、S3やRDSに保存されるようになっています。
    - ではEFS(共有ストレージ)の使い所はどこかというと、`プラグイン`機能を提供するための領域となります。
    - `プラグイン`は何かというと、Mattermost上でToDoリストを利用できるようにしたり、GitHub・GitLabと連携できるようにしたりする(他にも色んな機能を提供するプラグインがあります)ものです。
- で、このプラグインを利用するためにはMattermostの機能を提供するコンテナが`/plugins`という領域をマウントしてそこにプラグインの機能を提供する各種ファイルを置く必要があります。この`/plugins`を共有領域としてマウントしたいというのが、ここでの目的になります。
    - なぜ共有領域にしたいかというと、以下のような問題の解決が目的となります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/9e63388c-3160-6147-98c5-d68ed7edc5a0.png)
    - 共有領域を利用することで以下のように解決できる。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/08c2c539-5e37-cdca-98d1-add327d9c50e.png)

- では、設定をしていくのですがまずはEFSの設定が必要です。
    - これは以下で対応しています。
        - [EKSでMattermostを構築した話：3-2. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/b477f3a6a21038b76db2)
    - 上記で連携されているEFSをEKS上で利用するには、以下の3つの設定が必要です
        - ストレージクラス(SC)
        - パーシステントボリューム(PV)
        - パーシステントボリュームクレーム(PVC)

#### SCを作成します
- 以下のyamlを用意します。

```yaml:storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc-mm
provisioner: efs.csi.aws.com
```

- これを適用します。

```
$kubectl apply -f storageclass.yaml
storageclass.storage.k8s.io/efs-sc created
```

- 確認します。

```
$ kubectl get sc
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
efs-sc-mm       efs.csi.aws.com         Delete          Immediate              false                  40d
gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  48d
```

- `efs-sc-mm`の方が作成した方ですね。

#### PVを作成します
- 以下のyamlを用意します。

```yaml:pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-pv-mm
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: efs-sc-mm
  csi:
    driver: efs.csi.aws.com
    volumeHandle: fs-148a9a35
```

- 適用します。

```

$kubectl apply -f pv.yaml
persistentvolume/efs-pv-mm created
```

- 確認します。

```
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                STORAGECLASS   REASON   AGE
efs-pv-mm                                  1Gi        RWX            Retain           Bound    default/mattermost-team-edition-1603370901-plugins   efs-sc-mm               26d
pvc-8017a2eb-3b27-482d-bee2-e435ee131062   10Gi       RWO            Delete           Bound    default/mattermost-team-edition-1603370901           gp2                     26d
```

- `efs-pv-mm `ができています。

#### PVCを作成します
- PVCについてはhelmの`values.yaml`に記載します。この辺りの設定箇所がバラバラな感じもいけてないですね、、、なるべく設定変更箇所は1つにまとめていきたい。今後の課題です。
    - オリジナルな`values.yaml`だと33行目あたりです

```yaml:values.yaml
persistence:
  ## This volume persists generated data from users, like images, attachments...
  ##
  data:
    enabled: true
    size: 10Gi
    ## If defined, volume.beta.kubernetes.io/storage-class: <storageClass>
    ## Default: volume.alpha.kubernetes.io/storage-class: default
    ##
    storageClass: gp2
    accessMode: ReadWriteOnce"
  plugins: #★設定変更するのは以下から
    enabled: true
    size: 1Gi
    ## If defined, volume.beta.kubernetes.io/storage-class: <storageClass>
    # volume.beta.kubernetes.io/storage-class: efs-sc
    ## Default: volume.alpha.kubernetes.io/storage-class: default
    ##
    storageClass: efs-sc-mm #★ここを作成したscにしています
    accessMode: ReadWriteMany #★ここは最初は「ReadWriteOnce」だったのを変更
    # accessMode: ReadWriteOnce
```

- 適用はここだけhelmコマンドです
    - `mattermost-team-edition-xxxxxx`の部分は`helm list`で出てきた値にしています

```
$ helm upgrade mattermost-team-edition-xxxxxx ./mattermost-team-edition
Release "mattermost-team-edition-1603370901" has been upgraded. Happy Helming!
(以下、略)
```

- 確認します。

```
$ kubectl get pvc
NAME                                         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mattermost-team-edition-1603370901           Bound    pvc-8017a2eb-3b27-482d-bee2-e435ee131062   10Gi       RWO            gp2            26d
mattermost-team-edition-1603370901-plugins   Bound    efs-pv-mm                                  1Gi        RWX            efs-sc-mm      26d
```

- `mattermost-team-edition-1603370901-plugins`というPVCができました。

#### さらにもう1つ設定
- これでPVCもできたので、上手くプラグインが利用できるかなと思いましたが、上手くいきません、、、
    - 以下のようなエラーが出てしまいます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/7c01cc1c-1228-9996-7da0-b913c91e220c.png)

- 原因はPodがEFSをマウントする時の`権限がrootになっている`というものでした。

```
$ ls -la
total 228
drwxr-sr-x    1 mattermo mattermo        40 Sep  4 06:26 .
drwxr-xr-x    1 root     root            46 Sep  4 06:24 ..
-rw-------    1 mattermo mattermo         7 Sep  4 06:26 .ash_history
-rw-r--r--    1 mattermo mattermo      1239 Sep  4 02:08 MIT-COMPILED-LICENSE.md
-rw-r--r--    1 mattermo mattermo    196761 Sep  4 02:08 NOTICE.txt
-rw-r--r--    1 mattermo mattermo      5554 Sep  4 02:08 README.md
drwxr-xr-x    2 mattermo mattermo        53 Sep  4 02:30 bin
drwxr-xr-x    1 mattermo mattermo       196 Sep  4 02:30 client
drwxr-xr-x    2 mattermo mattermo        42 Sep  4 06:24 config
drwxrwsr-x    3 root     mattermo      4096 Sep  4 05:25 data
drwxr-xr-x    2 mattermo mattermo        44 Sep  4 02:30 fonts
drwxr-xr-x    2 mattermo mattermo       255 Sep  4 02:30 i18n
drwxr-xr-x    2 mattermo mattermo        28 Sep  4 06:24 logs
drwxrwsr-x    5 root     root          6144 Sep  4 06:25 plugins ★ここがrootになっている
drwxr-xr-x    2 mattermo mattermo      4096 Sep  4 02:30 prepackaged_plugins
drwxr-xr-x    2 mattermo mattermo      4096 Sep  4 02:30 templates
```

- Mattermostのpodはmattermostユーザーで実行されているので、plugins領域がrootだと権限がなくてファイルの読み書きができません。
- 色々と試した(`fsGroup`)のですがそれでも上手く行かず、、、最終的には`EFSの権限を変えてしまう`という方法で対応をしました。
    - 実際に行ったのは、踏み台サーバからEFSに対して権限を変更するコマンドを実行しました。
    - 踏み台でEFSの設定をした際に参考にした情報
        - [UbuntuでEFSをマウントする - Qiita](https://qiita.com/SSMU3/items/fe2f6b74ab363b39e2f6)
        - [Amazon Elastic File System - ユーザーガイド](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/efs-ug.pdf)
            - 上記のユーザーガイドのP.175に記載していた方法を実施  
            
            > • Amazon EFS ファイルシステムの所有権を非ルートユーザーとグループに変更するには、以下を使用します。  
> $ sudo chown user:group /EFSroot  
> • ファイルシステムのアクセス許可をより制限の低いものに変更するには、以下を使用します。  
> $ sudo chmod 777 /EFSroot  
> このコマンドは、ファイルシステムがマウントされているすべての EC2 インスタンス上のすべてのユーザーに読み取り/書き込み/実行の権限を許可します。

- 結果、pluginsのディレクトリの所有者はrootのままですが、権限が777になったのでmattermostユーザからも利用できるようになり、プラグイン機能が正常に動くこととなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/6cc9883f-fcc3-6839-f0bd-5bb613e3582c.png)

### 5. `ALB連携` アプリケーションロードバランサーを構築するために、ALBと連携させる
- 次はALBです。
    - こちらも前準備は[EKSでMattermostを構築した話：3-1. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/c91d27fa2e286a96b6ff)で対応しています。
- なので、ここで紹介するのはALBをhelmから利用する方法となります。

#### values.yamlを編集する
-

```yaml:values.yaml
service:
  type: NodePort #★ここをClusterIPから変更
  externalPort: 8065
  internalPort: 8065
  annotations: {}
  loadBalancerSourceRanges: []

ingress:
  enabled: true #★ここをtrueに変更
  #path: /
  annotations:
    kubernetes.io/ingress.class: alb #★ここから下をALBで利用する設定に変更
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-1:394923402640:certificate/78708c9d-4d8f-42bc-8fb7-de9b7b5b4f9f #★ここはACMで取得した証明書のARNを指定
  spec:
    rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: "mattermost"
              servicePort: 8065

    # kubernetes.io/ingress.class: nginx
    # certmanager.k8s.io/issuer:  your-issuer
    # nginx.ingress.kubernetes.io/proxy-body-size: 50m
    # nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    # nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    # nginx.ingress.kubernetes.io/proxy-buffering: "on"
    # nginx.ingress.kubernetes.io/configuration-snippet: |
    #   proxy_cache mattermost_cache;
    #   proxy_cache_revalidate on;
    #   proxy_cache_min_uses 2;
    #   proxy_cache_use_stale timeout;
    #   proxy_cache_lock on;
    #### To use the nginx cache you will need to set an http-snippet in the ingress-nginx configmap
    #### http-snippet: |
    #### proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
  hosts:
    - xx.xx.xxxxx.co.jp #★ここに利用したいFQDNを指定する
 #tls:
   #- secretName: mattermost.example.com-tls
   #- hosts:
   #  - mm.srv.stylez.co.jp
```

- 上記のようにvalues.yamlを編集したあとにhelmを適用すると自動でALBが作成されてターゲットグループやSSL証明書の設定も自動でよしなにやってくれます。

### 6. `Route53連携` ALBのDNS名を自動的に指定したFQDNと紐付けるために、Route53と連携させる
- 最後に`Route53`です。
    - ここでは上記のALBが自動で作成されたら、そのALBのDNS名を利用したいFQDNと自動で紐付けるようにします。
- ここも前準備は[EKSでMattermostを構築した話：3-2. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/b477f3a6a21038b76db2#external-dns%E3%81%AE%E8%A8%AD%E5%AE%9A)で`external dns`の設定をしているのであとはvalues.yamlの編集だけです。
- その編集内容も、実は先程のALBの設定の中で記載していた以下の箇所と同じです。

```
  hosts:
    - xx.xx.xxxxx.co.jp #★ここに利用したいFQDNを指定する
```

- 簡単ですね！！

## まとめ
- 以上でMattermostのConfigを含めた`helmのvalues.yaml`の編集が終わりました。
- この状態で`helm install` もしくは `helm upgrade`をすると、最低限利用できるようなMattermostができあがるかなと思います。
    - とはいえ、まだまだ考慮するべき点が沢山のこっています。例えば以下のような項目です。
        - ローリングアップデートするには？
        - hpaの設定をするには？
        - Kubernetesのバージョンをあげるには？
            - その他たくさん、、、
    - 実際に上記の状況で数ヶ月稼働させてみた結果、色んな問題が出ています、、、
        - でも、稼働させてみないと分からなかった問題がでてきていて、それは次の課題にもなってくるので、個人的にはとても良い勉強になっています。
- 上記の残課題や、稼働させてみて分かった`最初から考慮しておきたかった点`などは、またこちらに記載していければと思っています。

## 関連記事
-   [EKSでMattermostを構築した話：0.概要編 - Qiita](https://qiita.com/tnagano1981/items/555301cecd3ed309fa43)
-   [EKSでMattermostを構築した話：1. VPC作成編 - Qiita](https://qiita.com/tnagano1981/items/75408d509c0660408c97)
-   [EKSでMattermostを構築した話：2. EKSクラスター作成編 - Qiita](https://qiita.com/tnagano1981/items/fc5d96ddf9a3b5c4fb03)
-   [EKSでMattermostを構築した話：3-1. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/c91d27fa2e286a96b6ff)
-   [EKSでMattermostを構築した話：3-2. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/b477f3a6a21038b76db2)
-   [EKSでMattermostを構築した話：4-1. Mattermostのインストール(helm理解編) - Qiita](https://qiita.com/tnagano1981/items/9c36cf9f0a6196fcf865)
-   [EKSでMattermostを構築した話：4-2. Mattermostのインストール(helm適用編) - Qiita](https://qiita.com/tnagano1981/items/289d375135f64f5241a2)
-   [EKSでMattermostを構築した話：5-1. Mattermost Configの設定(helmのチューニング01) - Qiita](https://qiita.com/tnagano1981/items/9e06f71c25ceccfaf6fb)