AKS上でMongoDBを起動するときにMongoDBのファイルをPod外に保存する

# はじめに(免責事項はページ最後にあります）
この記事では、Azure Kubernetes（AKS）上で稼働するPodにMongoDBを起動しようとして、ReadWriteOnceな、managed-cliをStorageClassに選択してしまったがゆえに、mongodbの初期化処理が失敗したことから調べて記述した記事です。

# 背景
以下の環境を構築して、AKSが停止しても、MongoDBのデータが残るようにしようとした。
・PVを、MongoDB用のPodにマウント
・Mongodのデータは、そのPVに保存
・DeploymentにPodとMountについて記述しておき、AKSを起動・再起動してもデータが復元されるようにした
・Kubernetesの再学習に加えて、AKSを学習しようとしていた

# 失敗に至る前段階の頭の中
1.Node数が1の最小構成で実施していたため、ReadWriteOnceのStorageClassでいいだろくらいに思っていた
2.調べたところ、組み込みのStorageClassに、managed-csiがあり、それを使おうと思った
3.調べたところ、これらは、「ReadWriteOnce」でしか使えないとあったが、Nodeが１つなのでこれでいいと思っていた
で、開始

# 失敗構成と手順
* 構成
  * k8s: 1.22.11
  * mongoのPod: 
      * mongo5.0をインストールして、MongoのユーザやDBをスクリプトで作成するよう記述
      * そのスクリプトをENTRYPOINTにしてalpine:3.9をベースイメージにしてイメージ作成
      * ACRにイメージをPush
      * Deployment用のYamlを作成
          * PVCに、StorageClass: managed-csiを指定
          * そのPVCを、PodにMount
* 失敗と思われる挙動
    * Podは正常に起動する
    * Podに入って、mongodで確認すると、デーモンはあがっている
    * mongoで入ってdb switchなどはできることを確認
    * が、しかし、db.authで認証しようとしてもなぜか空ブル。
    
* それからどうしたか・・・
    * まず、podのlogを確認
    * ついで、mongoにlogを出力するようにしていたので、mongoのログを確認
    * Initializeで、Storageが、このStorageTypeじゃだめだよと出ていることに気づく。ほかのサンプルを見ると、HostのDirectoryをバインドしている例などもあったが、AKSの場合、FileSystemをマウントするほうが正しそうに見えた。
    * ということで、独自のStorageClass（といっても、MSのページを参考にして）を作成し、そのStorageClassを指定するPVCを作成。
    * 作成したPVCを使って、Volumesを定義。
    * そのVolumesをPodにMount。
   
* そうしたところ・・・
    * Podにexec -it shで入った
    * mongo -> use <db name> -> db.auth("user", "pass") ------ 1(Success!!!!)
    * show dbsで、すべて見えるように！！

**めでたしめでたし**

# 終わりに
初歩的な部分で躓き、mongoのデータやらを外部Volumeにマウントする流れではまってしまいましたが、うまくいきました。
最終的なYamlは以下のような感じです。
もちろん、これとは別に、Dockerfileを用意して、Imageを作成する必要があります。
※主に、Mongoのインストールなど

また、そのDockerfileのENTRYPOINTで実行するshファイルの作成も必要。（shファイル内では、MongoのUser作成など）

そのイメージを、ACRに乗せて、下記のYAMLの＜Image Path＞に埋め込めば、外部ファイルにデータを保管するMonogoDB Podの出来上がりでございました👍👍

```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: my-azurefile
provisioner: file.csi.azure.com # replace with "kubernetes.io/azure-file" if aks version is less than 1.21
allowVolumeExpansion: true
mountOptions:
  - dir_mode=0777
  - file_mode=0777
  - uid=0
  - gid=0
  - mfsymlinks
  - cache=strict
  - actimeo=30
parameters:
  skuName: Premium_LRS
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: storage-pvc
  namespace: default
  labels:
    app: weblog
    type: storage
spec:
  storageClassName: my-azurefile
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
  namespace: default
type: Opaque
data:
  keyfile: c3R5dHAwdVhldE0vRkMwV01ZL3lRSTQ5TUFhUWZZaGVBSTNKeEpidU9qNzBYRXFVR0ZPY3Jhd0NKUUVqenpaM2kzOEsxWmlqcFJCUUdGQmMyWmh0NVRPdUlNUjZOd01sZGV0Q0U5Y2sxSkM2bzZ3d2d0OGNSZmxaSTV2U3lOV3h6Wk9PdnFhMyt1aWpVTy9ocVdVS3M5c1NqNWdkRDVNdjdZbHRjajRjOUxwMEJJUHZEc2VXRUxmNzVFcDREcDk2MVI5VW9oK3Z5N3owc0JPelFoVVlXdjJCSmhjYkVXNXBDNFdVZDZndXlUMUZjdnpFWG5TQzFGMjBHU2JSVWcxK2c4d3VFQllGVDR0M1NkRWRGVlJPdVEvS2pWTVpOaThqY0RSc3htbDhVSFEyd21PLzJ0cWpCdDAxeTFOdXFEbmNWRjR0NVlVSkFQVFc1RE9xMkJFcWRNTnJtL2N2NFRiN0ZhS0tGSDFRWlA4VWJpWUh5V0ZINlFFNnFEV0dWZ21UTE9wTmxraXZTYTlCeW5pODhIdzVydDh5Qkd3NlNqN3RmcGx1RlZENmxtTHNhNUVEejEzbTdOeGREY0ZWbU1mSkJFVVc0cW13QU94VnIvSndncGhvWGtaeFVRMWltOG5DN1pyOVFHa1h2dXZmNFNxZzVMWUdOeTlKd0NOTENCY0ordWMzbFBzaTZhME1rUUlzM0dXK2xBaU9FR0pLWVpNZTgzSTFHSGREcVJaMi84eGZiMk9BMWlLTTUyR1VzeE8xblMwUkZuSFNqQ0NTNVN0RGR3NXBpQ0x6R044dXp6TG90QW5kT0lkTTk2SHo5TTBadVNMUzZGZFJRQmdtNDlYQWNkd2RJYzZEdW4rd1FHTnV1SXpTQVczZ24yVTVtNWRZaGFmcHFVazJ1eDU4R0dpeGxFTVU1ZWgvcGU2cVM1MmNmRW9zT0xYRDIxMXljMGZ2QW44Y0ZaR3A4UDM1ckU5eWVqUmxXSkl3OGMwQmZKaktXMDY2Z3EyZ1QyRE1TK0RwWEhvbVZqdUJudy96c1ZtWmtWWEZLcktDaXY2a1VaL0VsYzU3UlFIZjRMVDF4dk1Mck45blREWFdHb2dCcldnYyswMDJMMEdBbFFySnRMcUFsL0pXV1ZiSjAyeEFvaFZjeXB0ejhIK1Urb3E0ZDg5ZmFjV3ZOYitESnRyVks3b3JZOEN2eEFEc3pjaTU3WW8vZ1VlNmtSQTBIVWFvamZTNkJzV1BBaXBqd2hIS3E2Rk1LenNJYlFqMnQ2SFNubVJGZVJxdEFSaHYzdEtkZmhKbWVhYWxGbUxOSXF4enRBQS9tMlFobHlORVRpQjR1YUVYbzREb09EL1dJTURXTkV6eQo=
  root_password: UGFzc3dvcmQ=
  root_username: YWRtaW4=
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: weblog
      type: database
  template:
    metadata:
      name: mongodb
      labels:
        app: weblog
        type: database
    spec:
      containers:
        - name: mongodb
          image: <image path>
          args:
            - "mongod"
            - "--auth"
            - "--bind_ip_all"
          env:
            - name: "MONGO_INITDB_ROOT_USERNAME"
              valueFrom:
                secretKeyRef:
                  name: mongo-secret
                  key: root_username
            - name: "MONGO_INITDB_ROOT_PASSWORD"
              valueFrom:
                secretKeyRef:
                  name: mongo-secret
                  key: root_password
            - name: "MONGO_INITDB_DATABASE"
              value: "admin"
          volumeMounts:
            - name:  storage
              mountPath:  /data/db
            - mountPath: /home/mongodb
              name: secret
      volumes:
        - name:  storage
          persistentVolumeClaim:
            claimName: storage-pvc
        - name: secret
          secret: 
            secretName: mongo-secret
            items:
              - key: keyfile
                path: keyfile
                mode: 0700
```

それでは今回はこの辺で。
See you next Time!

# 免責事項
本記事は、著者が独自で調査・検証を行い、解決に至った内容です。
Microsoft公式のページを参考にしていますが、Microsoftが公式にすべての手順を公開している内容を引用しているわけではなく、著者が様々な情報を調べて導き出した結果です。
Microsoftの公式見解またはベストプラクティスとは異なる解説をしている可能性があります。
また、環境を考慮した設定ではないので（動かすための任意の構成）、本番環境などではさらに熟慮が必要なはずです。

本記事を参考にして行った作業に関して発生するすべての損害、問題、課題について、当方では一切の責任を負えませんのであらかじめご了承ください。