ROSAでEFSを利用する

# 概要
**R**ed Hat **O**penShift **S**ervice on **A**WS(ROSA)はAWS上で提供され、ManagedなOpenShiftが利用出来るサービスです。
ここでは詳細な説明は割愛しますが、OpenShiftはKubernetesにエンタープライズにも対応出来るようなサービス(ロールベースでのアクセス制御・ソースコードからのアプリケーションのデプロイ等)を追加したサービスです。

https://www.redhat.com/ja/technologies/cloud-computing/openshift

ROSAの場合はレイヤー毎にAWS・Red Hat・利用者で責任が分かれ、AWS・Red Hatのサポートを受けながらコンテナプラットフォームの運用を行うことになります。

https://access.redhat.com/documentation/ja-jp/red_hat_openshift_service_on_aws/4/html/introduction_to_rosa/rosa-policy-responsibility-matrix

ROSAを公式手順に従って導入・構築した段階では、EBSをPVとして標準利用出来るような設定がされています。一方で、EBS以外のストレージをPVとして利用出来るようにするためには利用者自身が設定を行う必要があります。
そこで、本記事ではROSAでEFS(Elastic File Sytem)を利用するための設定や考慮点についてご説明します。

# EFS CSI Driverの導入
まずROSAでEFSを利用するためにはEBSと同様CSI Driverが必要です。  
導入手順は公式ドキュメントにありますので、手順に従って導入しましょう。

https://access.redhat.com/documentation/ja-jp/red_hat_openshift_service_on_aws/4/html/storage/osd-persistent-storage-aws-efs-csi

概略としては以下の通りです。
①EFS CSI Driver Operatorの導入
②Operatorの利用する認証情報の設定
③EFS CSI Driverの導入
④EFSの作成
⑤ストレージクラスの作成
⑥PV/PVCの作成

# EFS利用時の考慮点
EFSの利用自体は上記の手順に従ってPV/PVCを作成することで可能ですが、EFSを利用する際に考慮すべき点がいくつかあります。
ここではパフォーマンス・可用性・運用性の観点で考慮すべきポイントを紹介します。

## パフォーマンス
パフォーマンスに関して問題になることはほとんど無いかもしれませんが、EFSはファイルストレージであるのに対して、EBSはブロックストレージです。
パフォーマンス等の理由によりブロックストレージが必要となる場合は、EFSでは要件に合致しないため、EBSを利用することになります。
一方でEBSを利用する場合は後述の可用性を検討する必要があります。

https://aws.amazon.com/jp/compare/the-difference-between-block-file-object-storage/

## 可用性
EFSは複数AZに分散されデータを保管するため、単一AZ障害時にも別AZで継続して稼働します。
ROSAも同様に複数AZにまたがってWorker Nodeがデプロイされるため、ROSAとEFSを組み合わせることで単一AZ障害に耐えられるアーキテクチャとすることが出来ます。
逆にパフォーマンス要件等でEBSを利用する必要がある場合は単一AZ障害を許容するか、許容出来ない場合は別のソリューションを検討する必要があります。

## 運用性(EFSの分割単位)
運用面で考える必要があるのは、EFSをどの単位で作成するかという問題です。
例えばアプリ単位やnamespace単位でEFSを作成する場合はアプリの数だけEFSを作成することになりますが、EFSリソースだけでなく以下の要素についても考慮が必要です。

### ストレージクラス
ストレージクラスは基本的にEFSリソースと1:1対応になります。
以下はRed Hat公式ドキュメントから引用したStorageClassの例です。`fileSystemId`としてEFSのIDを指定する必要があります。
```
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap 
  fileSystemId: fs-a12345 
  directoryPerms: "700" 
  gidRangeStart: "1000" 
  gidRangeEnd: "2000" 
  basePath: "/dynamic_provisioning" 
```
単一のEFSを利用する場合はストレージクラスを一つ作成するだけで良いですが、EFSをアプリ単位で作る場合はストレージクラスもアプリ単位で作ることになり、管理が煩雑になります。
また、単一のEFSを利用する場合はそのストレージクラスをデフォルト値として設定しておけば良いですが、複数のストレージクラスを用意する場合はnamespaceに対して都度ストレージクラスを設定することになります。

一方で複数のストレージクラスを用意するメリットとして、プロビジョニング設定をアプリ毎に変更出来ます。上記の例では`provisioningMode`を`efs-ap`とすることにより動的プロビジョニングモードとしていますが、この値を変更することで静的プロビジョニングのみを許すようにも出来ます。


また、ROSAクラスタを管理する基盤担当とコンテナアプリを管理するアプリ担当が異なるような運用体制の場合、ストレージ部分(EFS)を全てアプリ担当の責任とすることが出来ますので、役割分担が明瞭になるのもメリットと言えるかもしれません。

### バックアップ
EFSはサービス仕様としてディレクトリ単位でのバックアップは出来ません。
従って、単一のEFSを利用する場合、バックアップウィンドウはEFSを利用する全アプリに対して固定となります。
アプリ単位でEFSを用意すればアプリの都合に合わせてバックアップウィンドウを定めることが出来ますので、これが許容出来ない場合は複数のEFSを利用することになるでしょう。
バックアップについてはリストアと合わせて別の記事でもう少し詳しく取り扱います。

### AWSのリソースクォータ
AWSの各サービスにはリソースクォータ(サービス仕様上の制約)が存在します。
EFSの場合は、クォータの一つとしてアクセスポイントの数に制限が設けられています。
さらに、このクォータは制限緩和を申請出来ない項目なので、引っかかってしまうとどうしようもありません。

| 変更できない一般的なリソースクォータ | |
| --- | --- |
|リソース |	クォータ|
|各ファイルシステムのアクセスポイント数 | 1,000 |

https://docs.aws.amazon.com/ja_jp/efs/latest/ug/limits.html#limits-efs-resources-per-account-per-region

従って、複数EFSを利用する方針に舵を切る場合は将来的なシステムの利用規模を考慮し、問題ないことを確認してから実装を進める必要があります。
（もちろんEFSを別アカウントに用意するなどの回避策も考えられます）
特にROSAはエンタープライズ規模の環境で利用されることが多いと思われますので、リソースクォータが致命傷とならないようお気をつけください。

少し脱線ですが、どのリソースクォータが上限緩和可能か/不可能かは以下のコマンドで調べることが出来ます。`Adjustable`が`false`になっているのが上限緩和不可のクォータです。

```
PS C:\Users\naras> aws service-quotas list-aws-default-service-quotas --service-code elasticfilesystem
{
    "Quotas": [
        {
            "ServiceCode": "elasticfilesystem",
            "ServiceName": "Amazon Elastic File System (EFS)",
            "QuotaArn": "arn:aws:servicequotas:ap-northeast-1::elasticfilesystem/L-FA0AAA42",
            "QuotaCode": "L-FA0AAA42",
            "QuotaName": "Active users per NFS client",
            "Value": 128.0,
            "Unit": "None",
            "Adjustable": false,
            "GlobalQuota": false
        },
        {
            "ServiceCode": "elasticfilesystem",
            "ServiceName": "Amazon Elastic File System (EFS)",
            "QuotaArn": "arn:aws:servicequotas:ap-northeast-1::elasticfilesystem/L-3D348029",
            "QuotaCode": "L-3D348029",
            "QuotaName": "Security groups per mount target",
            "Value": 5.0,
            "Unit": "None",
            "Adjustable": false,
            "GlobalQuota": false
        },
        以下略
```


# まとめ
本記事ではROSAでEFSを利用するに考慮すべき点をご説明し、特に判断が必要な部分として以下の2つをご紹介しました。
①EFSとEBSのどちらを利用すべきか
②EFSを利用する際はクラスタ全体で単一のEFSを利用すべきか、アプリ毎にEFSを用意すべきか

私個人の意見としては、
①可用性の観点から可能な限りEFSを利用する
②基本方針として全アプリ共通で利用する単一のEFSを利用し、アプリの要件を満たせない場合のみ専用EFSを用意する
がバランスが良いのではないかと考えています。

本記事がROSAに限らずEKSも含め、AWS上のKubernetesでEFSを利用する際の参考になれば幸いです。